From cd4d4e7816754c92811555627c3d9e73e64e0f16 Mon Sep 17 00:00:00 2001 From: valdmity Date: Mon, 13 Mar 2023 19:19:50 +0500 Subject: [PATCH] task --- .idea/.gitignore | 5 + .idea/animaster.iml | 12 +++ .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 ++ index.html | 76 ++++++++++----- index.js | 222 +++++++++++++++++++++++++++++++++++++------- 6 files changed, 273 insertions(+), 56 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/animaster.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/animaster.iml b/.idea/animaster.iml new file mode 100644 index 0000000..0c8867d --- /dev/null +++ b/.idea/animaster.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2448e27 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/index.html b/index.html index 6546475..3cc1c0e 100644 --- a/index.html +++ b/index.html @@ -6,28 +6,58 @@ -
-
-

fadeIn

- -
-
-
-
-
-

move

- -
-
-
-
-
-

scale

- -
-
-
+
+
+

fadeIn

+ +
+
+
+
+
+

fadeOut

+ +
+
+
+
+
+

move

+ +
+
+
+
+
+

scale

+ +
+
+
+
+
+

move and hide

+ + +
+
+
+
+
+

show and hide

+ +
+
+
+
+
+

heart beating

+ + +
+
+
- + - \ No newline at end of file + diff --git a/index.js b/index.js index 61e55f6..ce0922a 100644 --- a/index.js +++ b/index.js @@ -4,53 +4,55 @@ function addListeners() { document.getElementById('fadeInPlay') .addEventListener('click', function () { const block = document.getElementById('fadeInBlock'); - fadeIn(block, 5000); + animaster().addFadeIn(5000).play(block, false); + }); + + document.getElementById('fadeOutPlay') + .addEventListener('click', function () { + const block = document.getElementById('fadeOutBlock'); + animaster().addFadeOut(5000).play(block, false); }); document.getElementById('movePlay') .addEventListener('click', function () { const block = document.getElementById('moveBlock'); - move(block, 1000, {x: 100, y: 10}); + animaster().addMove(1000, {x: 100, y:10}).play(block, false); }); document.getElementById('scalePlay') .addEventListener('click', function () { const block = document.getElementById('scaleBlock'); - scale(block, 1000, 1.25); + animaster().addScale(1000, 1.25).play(block, false); }); -} -/** - * Блок плавно появляется из прозрачного. - * @param element — HTMLElement, который надо анимировать - * @param duration — Продолжительность анимации в миллисекундах - */ -function fadeIn(element, duration) { - element.style.transitionDuration = `${duration}ms`; - element.classList.remove('hide'); - element.classList.add('show'); -} + document.getElementById('moveAndHide') + .addEventListener('click', function () { + const block = document.getElementById('moveAndHideBlock'); + animaster().moveAndHide(block, {x: 100, y: 20}, 1000); + }); -/** - * Функция, передвигающая элемент - * @param element — HTMLElement, который надо анимировать - * @param duration — Продолжительность анимации в миллисекундах - * @param translation — объект с полями x и y, обозначающими смещение блока - */ -function move(element, duration, translation) { - element.style.transitionDuration = `${duration}ms`; - element.style.transform = getTransform(translation, null); -} + document.getElementById('stopMoveAndHide') + .addEventListener('click', function () { + const block = document.getElementById('moveAndHideBlock'); + animaster().resetMoveAndHide(block); + }); + + document.getElementById('showAndHide') + .addEventListener('click', function () { + const block = document.getElementById('showAndHideBlock'); + animaster().showAndHide(block, 3000); + }); + + document.getElementById('heartBeating') + .addEventListener('click', function () { + const block = document.getElementById('heartBeatingBlock'); + const heartBeating = animaster().heartBeating(block, 1000); -/** - * Функция, увеличивающая/уменьшающая элемент - * @param element — HTMLElement, который надо анимировать - * @param duration — Продолжительность анимации в миллисекундах - * @param ratio — во сколько раз увеличить/уменьшить. Чтобы уменьшить, нужно передать значение меньше 1 - */ -function scale(element, duration, ratio) { - element.style.transitionDuration = `${duration}ms`; - element.style.transform = getTransform(null, ratio); + document.getElementById('stopHeartBeating') + .addEventListener('click', function () { + heartBeating.stop(); + }); + }); } function getTransform(translation, ratio) { @@ -63,3 +65,157 @@ function getTransform(translation, ratio) { } return result.join(' '); } + +function animaster() { + function resetFadeIn(element){ + element.style.transitionDuration = null; + element.classList.remove('show'); + element.classList.add('hide'); + } + + function resetFadeOut(element){ + element.style.transitionDuration = null; + element.classList.remove('hide'); + element.classList.add('show'); + } + + function resetMoveAndScale(element){ + element.style.transitionDuration = null; + element.style.transform = null; + } + + return { + _steps: [], + + addMove: function (duration, transition) { + this._steps.push({ + duration: duration, + resetFunc: e => resetMoveAndScale(e), + do: e => this.move(e, duration, transition) + }); + return this; + }, + addScale: function (duration, ratio) { + this._steps.push({ + duration: duration, + resetFunc: e => resetMoveAndScale(e), + do: e => this.scale(e, duration, ratio) + }); + return this; + }, + addFadeIn: function (duration) { + this._steps.push({ + duration: duration, + resetFunc: e => resetFadeIn(e), + do: e => this.fadeIn(e, duration) + }); + return this; + }, + addFadeOut: function (duration) { + this._steps.push({ + duration: duration, + resetFunc: e => resetFadeOut(e), + do: e => this.fadeOut(e, duration) + }); + return this; + }, + addDelay: function (duration){ + this._steps.push({ + duration: duration, + resetFunc: _ => {}, + do: _ => setTimeout(() => {}, duration) + }); + return this; + }, + + play: function (element, cycled, steps = this._steps) { + let duration = 0; + this._steps.forEach(step => duration += step.duration) + let isStopped = 0; + function doCycle(){ + if (isStopped){ + return; + } + steps.reduce((pr, step) => { + return pr.then(() => step.do(element)); + }, Promise.resolve()); + } + doCycle(); + if (cycled){ + setInterval(doCycle, duration); + } + return { + stop() { + isStopped = true; + clearInterval(doCycle); + }, + reset() { + stop(); + for(const step of steps){ + if (step.resetFunc){ + step.resetFunc(element); + } + } + } + } + }, + buildHandler(){ + const steps = this._steps; + const obj = this; + return function (){ + obj.play(obj, false, steps); + } + }, + fadeIn: function (element, duration) { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('hide'); + element.classList.add('show'); + }, + fadeOut: function (element, duration) { + element.style.transitionDuration = `${duration}ms`; + element.classList.add('hide'); + element.classList.remove('show'); + }, + move: function (element, duration, translation) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(translation, null); + }, + scale: function (element, duration, ratio) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(null, ratio); + }, + moveAndHide: function (element, translation, duration) { + const movingDuration = duration * 0.4; + const hideDuration = duration * 0.6; + animaster() + .addMove(movingDuration, translation) + .addFadeOut(hideDuration) + .play(element, false); + }, + resetMoveAndHide: function (element) { + resetFadeOut(element); + resetMoveAndScale(element); + }, + showAndHide: function (element, duration) { + const partDuration = duration / 3; + animaster() + .addFadeIn(partDuration) + .addFadeOut(partDuration) + .play(element, false); + }, + heartBeating: function (element, duration) { + const partDuration = duration / 2; + + const scaling = setInterval(() => { + animaster().addScale(partDuration, 1.4) + .addScale(partDuration, 1) + .play(element, false) + }, duration); + return { + stop: function () { + clearInterval(scaling); + } + } + } + } +}