diff --git a/index.html b/index.html index 6546475..fbb1beb 100644 --- a/index.html +++ b/index.html @@ -13,6 +13,13 @@

fadeIn

+
+
+

fadeOut

+ +
+
+

move

@@ -27,6 +34,57 @@

scale

+
+
+

moveAndHide

+ + +
+
+
+
+
+

showAndHide

+ +
+
+
+
+
+

heartBeating

+ + +
+
+
+
+
+

customAnimation

+ +
+
+
+
+
+

worryAnimation

+
+
+
+
+
+

rotateAnimation

+ + +
+
+
+
+
+

testAnimation

+ +
+
+
diff --git a/index.js b/index.js index 61e55f6..43d2fa9 100644 --- a/index.js +++ b/index.js @@ -1,65 +1,316 @@ addListeners(); function addListeners() { - document.getElementById('fadeInPlay') - .addEventListener('click', function () { - const block = document.getElementById('fadeInBlock'); - fadeIn(block, 5000); + document.querySelector('#fadeInPlay').addEventListener('click', function () { + const animator = animaster(); + const block = document.getElementById('fadeInBlock'); + const animation = animator.addFadeIn(5000); + animation.play(block); + }); + + document.querySelector('#movePlay').addEventListener('click', function () { + const animator = animaster(); + const block = document.getElementById('moveBlock'); + const animation = animator.addMove(1000, {x: 20, y: 20}); + animation.play(block); + }); + + document.querySelector('#scalePlay').addEventListener('click', function () { + const animator = animaster(); + const block = document.getElementById('scaleBlock'); + const animation = animator.addScale(1000, 1.25); + animation.play(block); + }); + + document.querySelector('#fadeOutPlay').addEventListener('click', function () { + const animator = animaster(); + const block = document.getElementById('fadeOutBlock'); + const animation = animator.addFadeOut(5000); + animation.play(block); + }); + + document.querySelector('#moveAndHidePlay').addEventListener('click', function () { + const animator = animaster(); + const block = document.getElementById('moveAndHideBlock'); + const duration = 5000; + const animation = animator + .addMove(duration * 0.4, { x: 100, y: 20 }) + .addFadeOut(duration * 0.6); + const playing = animation.play(block); + document.getElementById('moveAndHideReset').addEventListener('click', function () { + playing.reset(); }); + }); - document.getElementById('movePlay') - .addEventListener('click', function () { - const block = document.getElementById('moveBlock'); - move(block, 1000, {x: 100, y: 10}); + document.querySelector('#showAndHidePlay').addEventListener('click', function () { + const animator = animaster(); + const block = document.getElementById('showAndHideBlock'); + const duration = 5000 / 3; + const animation = animator + .addFadeIn(duration) + .addDelay(duration) + .addFadeOut(duration); + animation.play(block); + }); + + document.querySelector('#heartBeatingPlay').addEventListener('click', function () { + const animator = animaster(); + const block = document.getElementById('heartBeatingBlock'); + const animation = animator + .addScale(500, 1.4) + .addScale(500, 1); + const playing = animation.play(block, true); + document.querySelector('#heartBeatingStop').addEventListener('click', function () { + playing.stop(); }); + }); + + document.querySelector('#customAnimationPlay').addEventListener('click', function () { + const animator = animaster(); + const block = document.getElementById('customAnimationBlock'); + const animation = animaster() + .addMove(200, {x: 40, y: 40}) + .addScale(800, 1.3) + .addMove(200, {x: 80, y: 0}) + .addScale(800, 1) + .addMove(200, {x: 40, y: -40}) + .addScale(800, 0.7) + .addMove(200, {x: 0, y: 0}) + .addScale(800, 2); + animation.play(block); + }); - document.getElementById('scalePlay') - .addEventListener('click', function () { - const block = document.getElementById('scaleBlock'); - scale(block, 1000, 1.25); + document.querySelector('#rotateAnimationPlay').addEventListener('click', function () { + const animator = animaster(); + const block = document.getElementById('rotateAnimationBlock'); + const animation = animator.addRotate(1000, 360 + 45); + const playing = animation.play(block); + document.querySelector('#rotateAnimationReset').addEventListener('click', function () { + playing.reset(); }); -} + }); -/** - * Блок плавно появляется из прозрачного. - * @param element — HTMLElement, который надо анимировать - * @param duration — Продолжительность анимации в миллисекундах - */ -function fadeIn(element, duration) { - element.style.transitionDuration = `${duration}ms`; - element.classList.remove('hide'); - element.classList.add('show'); -} + const worryAnimationHandler = animaster() + .addMove(200, {x: 80, y: 0}) + .addMove(200, {x: 0, y: 0}) + .addMove(200, {x: 80, y: 0}) + .addMove(200, {x: 0, y: 0}) + .buildHandler(); -/** - * Функция, передвигающая элемент - * @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('worryAnimationBlock').addEventListener('click', worryAnimationHandler); -/** - * Функция, увеличивающая/уменьшающая элемент - * @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.querySelector('#testAnimationPlay').addEventListener('click', function () { + const block = document.getElementById('testAnimationBlock'); + const a = animaster().addMove(111, {x: 10, y: -10}) + const b = a.addFadeOut(400); + a.play(block); + }); } -function getTransform(translation, ratio) { - const result = []; - if (translation) { - result.push(`translate(${translation.x}px,${translation.y}px)`); + +function animaster(steps) { + let _steps = steps || []; + + + function addDelay(duration) { + const newAnimaster = animaster([..._steps, { type: 'delay', duration: duration }]); + return newAnimaster; + } + + function addMove(duration, translation) { + const newAnimaster = animaster([..._steps, { type: 'move', duration: duration, translation: translation }]); + return newAnimaster; + } + + function addFadeIn(duration) { + const newAnimaster = animaster([..._steps, { type: 'fadeIn', duration: duration }]); + return newAnimaster; + } + + function addScale(duration, ratio) { + const newAnimaster = animaster([..._steps, { type: 'scale', duration: duration, ratio: ratio }]); + return newAnimaster; + } + + function addFadeOut(duration) { + const newAnimaster = animaster([..._steps, { type: 'fadeOut', duration: duration }]); + return newAnimaster; + } + + function addRotate(duration, angle) { + const newAnimaster = animaster([..._steps, { type: 'rotate', duration: duration, angle: angle }]); + return newAnimaster; + } + + function resetRotate(element) { + element.style.transitionDuration = null; + element.style.transform = null; + } + + function resetFadeIn(element) { + element.style.transitionDuration = null; + element.classList.remove('show'); + element.classList.add('hide'); } - if (ratio) { - result.push(`scale(${ratio})`); + + function resetFadeOut(element) { + element.style.transitionDuration = null; + element.classList.remove('hide'); + element.classList.add('show'); + } + + function resetMove(element) { + element.style.transitionDuration = null; + element.style.transform = null; + } + + function resetScale(element){ + element.style.transitionDuration = null; + element.style.transform = null; + } + + function fadeIn(element, duration) { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('hide'); + element.classList.add('show'); + } + + function fadeOut(element, duration) { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('show'); + element.classList.add('hide'); + } + + function move(element, duration, translation) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(translation, null); + } + + function scale(element, duration, ratio) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(null, ratio); } - return result.join(' '); + + function rotate(element, duration, angle) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = `rotate(${angle}deg)`; + } + + function getTransform(translation, ratio) { + const result = []; + if (translation) { + result.push(`translate(${translation.x}px,${translation.y}px)`); + } + if (ratio) { + result.push(`scale(${ratio})`); + } + return result.join(' '); + } + + function buildHandler() { + const animator = this; + return function() { + return animator.play(this); + }; + } + + function playCycled(element) { + const totalDuration = _steps.reduce((acc, step) => acc + step.duration, 0); + let stopper = null; + const interval = setInterval(() => { + stopper = play(element).stop; + }, totalDuration); + return { + stop: function () { + stopper(); + clearInterval(interval); + } + } + } + + function play(element, cycled = false) { + if (cycled) { + return playCycled(element); + } + let offset = 0; + _steps.forEach(step => { + switch (step.type) { + case 'delay': + offset += step.duration; + break; + case 'move': + setTimeout(() => { + move(element, step.duration, step.translation); + }, offset); + offset += step.duration; + break; + case 'fadeIn': + setTimeout(() => { + fadeIn(element, step.duration); + }, offset); + offset += step.duration; + break; + case 'fadeOut': + setTimeout(() => { + fadeOut(element, step.duration); + }, offset); + offset += step.duration; + break; + case 'scale': + setTimeout(() => { + scale(element, step.duration, step.ratio); + }, offset); + offset += step.duration; + break; + case 'rotate': + setTimeout(() => { + rotate(element, step.duration, step.angle); + }, offset); + offset += step.duration; + break; + default: + break; + } + }); + + return { + stop: function () { + _steps = []; + }, + reset: function () { + _steps.forEach(step => { + switch (step.type) { + case 'move': + resetMove(element); + break; + case 'fadeIn': + resetFadeIn(element); + break; + case 'fadeOut': + resetFadeOut(element); + break; + case 'scale': + resetScale(element); + break; + case 'rotate': + resetRotate(element); + break; + default: + break; + } + }); + } + } + } + + return { + play, + addMove, + addFadeIn, + addScale, + addFadeOut, + addDelay, + addRotate, + buildHandler + }; }