From 83c5d48aa450296859878bc0953b26daeb668f01 Mon Sep 17 00:00:00 2001 From: coca-in-a-cola Date: Thu, 21 Oct 2021 22:32:27 +0500 Subject: [PATCH] Tasks 1-15 --- index.html | 36 ++++++ index.js | 333 ++++++++++++++++++++++++++++++++++++++++++++++------- styles.css | 12 ++ 3 files changed, 340 insertions(+), 41 deletions(-) diff --git a/index.html b/index.html index 6546475..a68c0b5 100644 --- a/index.html +++ b/index.html @@ -27,6 +27,42 @@

scale

+
+
+

move and hide

+ + +
+
+
+
+
+

show and hide

+ +
+
+
+
+
+

heartbeat

+ + +
+
+
+
+
+

worry

+
+
+
+
+
+

shadow

+ +
+
Анимация текста
+
diff --git a/index.js b/index.js index 61e55f6..ab7d2c7 100644 --- a/index.js +++ b/index.js @@ -4,62 +4,313 @@ function addListeners() { document.getElementById('fadeInPlay') .addEventListener('click', function () { const block = document.getElementById('fadeInBlock'); - fadeIn(block, 5000); + block.classList.contains('hide') ? + animaster().addFadeIn(1000).play(block): + animaster().addFadeOut(1000).play(block); }); document.getElementById('movePlay') .addEventListener('click', function () { const block = document.getElementById('moveBlock'); - move(block, 1000, {x: 100, y: 10}); + animaster() + .addMove(500, { x: 100, y: 10 }) + .addMove(500, { x: 0, y: 0}) + .play(block); }); document.getElementById('scalePlay') .addEventListener('click', function () { const block = document.getElementById('scaleBlock'); - scale(block, 1000, 1.25); + animaster() + .addScale(500, 1.25) + .addScale(500, 1) + .play(block); }); -} -/** - * Блок плавно появляется из прозрачного. - * @param element — HTMLElement, который надо анимировать - * @param duration — Продолжительность анимации в миллисекундах - */ -function fadeIn(element, duration) { - element.style.transitionDuration = `${duration}ms`; - element.classList.remove('hide'); - element.classList.add('show'); -} + //через BuildHandler + 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(); + + document + .getElementById('worryAnimationBlock') + .addEventListener('click', worryAnimationHandler); + + const moveHideBlock = document.getElementById('moveHideBlock'); + const moveHideAnimation = animaster().moveAndHide(moveHideBlock, 1000); + document.getElementById('moveHidePlay') + .addEventListener('click', function () { + moveHideAnimation.play(); + }); + document.getElementById('moveHideStop') + .addEventListener('click', function () { + moveHideAnimation.stop(); + }); -/** - * Функция, передвигающая элемент - * @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); -} -/** - * Функция, увеличивающая/уменьшающая элемент - * @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('showHidePlay') + .addEventListener('click', function () { + const block = document.getElementById('showHideBlock'); + animaster() + .addFadeIn(300) + .addDelay(300) + .addFadeOut(300) + .play(block); + }); + + const heartBeatBlock = document.getElementById('heartbeatBlock'); + let heartBeatAnimation; + document.getElementById('heartbeatPlay') + .addEventListener('click', function () { + heartBeatAnimation = animaster() + .addScale(300, 1.25) + .addDelay(300) + .addScale(300, 1) + .play(heartBeatBlock, true); + }); + document.getElementById('heartbeatStop') + .addEventListener('click', function () { + if (heartBeatAnimation) + heartBeatAnimation.stop(); + }); + + document.getElementById('shadowPlay') + .addEventListener('click', function () { + const block = document.getElementById('shadowText'); + animaster() + .addShadow(1500) + .removeShadow(1500) + .play(block); + }); } -function getTransform(translation, ratio) { - const result = []; - if (translation) { - result.push(`translate(${translation.x}px,${translation.y}px)`); +function animaster() { + return { + + /** + * Блок плавно появляется из прозрачного. + * @param element — HTMLElement, который надо анимировать + * @param duration — Продолжительность анимации в миллисекундах + */ + fadeIn(element, duration) { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('hide'); + element.classList.add('show'); + }, + + fadeOut(element, duration) { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('show'); + element.classList.add('hide'); + }, + + /** + * Функция, передвигающая элемент + * @param element — HTMLElement, который надо анимировать + * @param duration — Продолжительность анимации в миллисекундах + * @param translation — объект с полями x и y, обозначающими смещение блока + */ + move(element, duration, translation) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(translation, null); + }, + + _steps: [], + + /** + * Функция, добавляющая анимациию (новая реализация) + */ + addStep(name, duration, translation, scale, execFn) { + const step = { + exec: execFn, + duration: duration, + translation: translation, + scale: scale, + name: name, + } + + this._steps.push(step); + return this; + }, + + addMove(duration, translation) { + return this.addStep('move', duration, translation, null, + (element) => { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(translation, null); + }); + }, + + addScale(duration, scale) { + return this.addStep('scale', duration, null, scale, + (element) => { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(null, scale); + }); + }, + + addFadeIn(duration) { + return this.addStep('fadeIn', duration, null, null, + (element) => { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('hide'); + element.classList.add('show'); + }); + }, + + addFadeOut(duration) { + return this.addStep('fadeOut', duration, null, null, + (element) => { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('show'); + element.classList.add('hide'); + }); + }, + + addDelay(duration) { + return this.addStep('wait', duration, null, null, + (element) => { + //... + }); + }, + + addShadow(duration) { + return this.addStep('shadow', duration, null, null, + (element) => { + element.style.transitionDuration = `${duration}ms`; + element.classList.add('shadow'); + }); + }, + removeShadow(duration) { + return this.addStep('shadow', duration, null, null, + (element) => { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('shadow'); + }); + }, + + play(element, cycled = false, stepIndex = 0) { + if (stepIndex < this._steps.length) { + this._steps[stepIndex].exec(element); + this._playTimeout = setTimeout( () => + { + this.play(element, cycled, stepIndex+1) + }, this._steps[stepIndex].duration) + } + + else if (cycled) { + this.play(element, cycled, 0) + } + + return { + stop: () => { + if (this._playTimeout) + clearInterval(this._playTimeout); + }, + + reset: () => { + stop(); + _resetMoveScale(element); + _resetfadeIn(element); + } + } + }, + + /** + * Функция, увеличивающая/уменьшающая элемент + * @param element — HTMLElement, который надо анимировать + * @param duration — Продолжительность анимации в миллисекундах + * @param ratio — во сколько раз увеличить/уменьшить. Чтобы уменьшить, нужно передать значение меньше 1 + */ + scale(element, duration, ratio) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(null, ratio); + }, + + moveAndHide(element, duration) { + const timing = duration / 5; + let timer; + return { + play: () => { + animaster().move(element, timing*2, { x: 100, y: 20 }); + timer = setTimeout(()=>animaster().fadeOut(element,timing*3),timing * 2); + }, + + stop: () => { + clearTimeout(timer); + _resetMoveScale(element); + _resetfadeIn(element); + } + } + }, + + showAndHide(element, duration) { + const timing = duration / 3; + setTimeout(()=>animaster().fadeIn(element,timing),0); + setTimeout(()=>animaster().fadeOut(element,timing),timing*2); + }, + + heartBeating(element, timing = 500, ratio = 1.4) { + let timer; + const animation = () => { + timer = setTimeout( + () => { + animaster().scale(element, timing, ratio) + timer = setTimeout ( + ()=> { + animaster().scale(element, timing, 1) + timer = setTimeout(animation, timing*3) + }, timing + ) + }, 0 + ); + }; + + const stop = () => { + clearTimeout(timer); + } + + return { + play: animation, + stop: stop, + } + }, + + buildHandler() { + const animator = this; + return function (element) { + return animator.play(element.target); + }; + }, + } + + 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(' '); } - if (ratio) { - result.push(`scale(${ratio})`); + + function _resetMoveScale(element) { + element.style.transitionDuration = `${0}ms`; + element.style.transform = getTransform(null, null); } - return result.join(' '); -} + + function _resetfadeIn(element) { + _resetfadeOut(element); + } + + function _resetfadeOut(element) { + element.style.transitionDuration = `${0}ms`; + element.classList.remove('hide'); + element.classList.remove('show'); + } + +} \ No newline at end of file diff --git a/styles.css b/styles.css index 68ad652..c17941c 100644 --- a/styles.css +++ b/styles.css @@ -45,4 +45,16 @@ } .show { opacity: 1; +} + +.shadow { + text-shadow:0px 0px 0 rgb(137,156,213),1px 1px 0 rgb(129,148,205),2px 2px 0 rgb(120,139,196),3px 3px 0 rgb(111,130,187),4px 4px 0 rgb(103,122,179),5px 5px 0 rgb(94,113,170),6px 6px 0 rgb(85,104,161),7px 7px 0 rgb(76,95,152),8px 8px 0 rgb(68,87,144),9px 9px 0 rgb(59,78,135),10px 10px 0 rgb(50,69,126),11px 11px 0 rgb(42,61,118),12px 12px 0 rgb(33,52,109),13px 13px 0 rgb(24,43,100),14px 14px 0 rgb(15,34,91),15px 15px 0 rgb(7,26,83),16px 16px 0 rgb(-2,17,74),17px 17px 0 rgb(-11,8,65),18px 18px 0 rgb(-19,0,57),19px 19px 0 rgb(-28,-9,48), 20px 20px 0 rgb(-37,-18,39),21px 21px 20px rgba(0,0,0,1),21px 21px 1px rgba(0,0,0,0.5),0px 0px 20px rgba(0,0,0,.2); +} + +#shadowText { + text-align: center; + font: bold 80px Sans-Serif; + padding: 40px 0; + color: #92a5de; + background: red; } \ No newline at end of file