From 945490d51be23f0746f54c9da574ed65d99e70c5 Mon Sep 17 00:00:00 2001 From: Pavuk Date: Fri, 22 Oct 2021 13:58:39 +0500 Subject: [PATCH] 1-14 --- index.html | 26 +++++++ index.js | 217 ++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 192 insertions(+), 51 deletions(-) diff --git a/index.html b/index.html index 6546475..e5a09a9 100644 --- a/index.html +++ b/index.html @@ -10,6 +10,7 @@

fadeIn

+
@@ -17,6 +18,7 @@

fadeIn

move

+
@@ -24,9 +26,33 @@

move

scale

+
+
+
+

moveAndHide

+ + +
+
+
+
+
+

showAndHide

+ +
+
+
+
+
+

heartBeating

+ + +
+
+
diff --git a/index.js b/index.js index 61e55f6..752f7e7 100644 --- a/index.js +++ b/index.js @@ -1,65 +1,180 @@ -addListeners(); - -function addListeners() { - document.getElementById('fadeInPlay') - .addEventListener('click', function () { - const block = document.getElementById('fadeInBlock'); - fadeIn(block, 5000); - }); - - document.getElementById('movePlay') - .addEventListener('click', function () { - const block = document.getElementById('moveBlock'); - move(block, 1000, {x: 100, y: 10}); - }); - - document.getElementById('scalePlay') - .addEventListener('click', function () { - const block = document.getElementById('scaleBlock'); - scale(block, 1000, 1.25); - }); -} +addListeners(false, + ['fadeIn', 5000], + ['scale', 1000, 1.25], + ['moveAndHide', 1000, {x: 100, y: 20}], + ['move', 1000, {x: 100, y: 10}], + ['showAndHide', 1000]); + +addListeners(true, ['heartBeating']); + +function addListeners(cycle, ...listeners) { + for (let listener of listeners) { + let block = document.getElementById(listener[0] + 'Block'); + let action = document.getElementById(listener[0] + (cycle ? 'Stop' : 'Reset')); -/** - * Блок плавно появляется из прозрачного. - * @param element — HTMLElement, который надо анимировать - * @param duration — Продолжительность анимации в миллисекундах - */ -function fadeIn(element, duration) { - element.style.transitionDuration = `${duration}ms`; - element.classList.remove('hide'); - element.classList.add('show'); + document.getElementById(listener[0] + 'Play').addEventListener('click', function () { + let element = animaster()[listener[0]](block, ...listener.slice(1)); + action.addEventListener('click', cycle ? element.stop : element.reset) + }); + } } -/** - * Функция, передвигающая элемент - * @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); +function animaster() { + return { + _steps: [], + + buildHandler() { + let animaster = this; + return function () { + return animaster.play(this); + } + }, + + fadeOut(element, duration) { + return this.addFadeOut(duration).play(element); + }, + + fadeIn(element, duration) { + return this.addFadeIn(duration).play(element); + }, + + scale(element, duration, scale) { + return this.addScale(duration, scale).play(element); + }, + + move(element, duration, translation) { + return this.addMove(duration, translation).play(element); + }, + + showAndHide(element, duration) { + return this.addFadeIn(duration / 3) + .addDelay(duration / 3) + .addFadeOut(duration / 3) + .play(element); + }, + + moveAndHide(element, duration) { + return this.addMove(duration * 2 / 5, {x: 100, y: 20}) + .addFadeOut(duration * 3 / 5) + .play(element); + }, + + heartBeating(element) { + return this.addScale(500, 1.4) + .addScale(500, 1) + .play(element, true); + }, + + resetFadeOut(element) { + element.style.transitionDuration = null; + element.classList.remove('hide'); + element.classList.add('show'); + }, + + resetFadeIn(element) { + element.style.transitionDuration = null; + element.classList.remove('show'); + element.classList.add('hide'); + }, + + resetMoveAndScale(element) { + element.style.transitionDuration = null; + element.style.transform = getTransform(0, 1); + }, + + addFadeIn(duration) { + let newAnimaster = this.copy() + newAnimaster._steps.push({ + duration, + action: element => { + element.classList.remove('hide'); + element.classList.add('show');}, + reset: element => this.resetFadeIn(element) + }) + return newAnimaster; + }, + + addScale(duration, scale) { + let newAnimaster = this.copy() + newAnimaster._steps.push({ + duration, + action: element => element.style.transform = getTransform(null, scale), + reset: element => this.resetMoveAndScale(element) + }) + return newAnimaster; + }, + + addMove(duration, translation) { + let newAnimaster = this.copy() + newAnimaster._steps.push({ + duration, + action: element => element.style.transform = getTransform(translation, null), + reset: element => this.resetMoveAndScale(element) + }) + return newAnimaster; + }, + + addFadeOut(duration) { + let newAnimaster = this.copy() + newAnimaster._steps.push({ + duration, + action: element => { + element.classList.remove('show'); + element.classList.add('hide');}, + reset: element => this.resetFadeOut(element) + }) + return newAnimaster; + }, + + addDelay(duration) { + let newAnimaster = this.copy() + newAnimaster._steps.push({ + duration, + action: () => null, + reset: () => null + }); + return newAnimaster; + }, + + copy() { + let newAnimaster = animaster(); + newAnimaster._steps = this._steps.slice(); + return newAnimaster; + }, + + play(element, cycle = false) { + let tick; + let timer = setTimeout(tick = index => { + element.style.transitionDuration = `${this._steps[index].duration}ms`; + this._steps[index].action(element); + if (cycle || index < this._steps.length - 1) + timer = setTimeout(tick, Math.round(this._steps[index].duration), + (index + 1) % this._steps.length); + }, 0, 0); + + return { + stop: () => {clearTimeout(timer);}, + reset: () => { + element.style.transitionDuration = null; + this._steps.slice().reverse().forEach(s => s.reset(element)); + } + } + } + } } -/** - * Функция, увеличивающая/уменьшающая элемент - * @param element — HTMLElement, который надо анимировать - * @param duration — Продолжительность анимации в миллисекундах - * @param ratio — во сколько раз увеличить/уменьшить. Чтобы уменьшить, нужно передать значение меньше 1 - */ -function scale(element, duration, ratio) { - element.style.transitionDuration = `${duration}ms`; - element.style.transform = getTransform(null, ratio); +function setMode(element, show) { + element.classList.remove(show ? 'hide' : 'show'); + element.classList.add(show ? 'show' : 'hide'); } -function getTransform(translation, ratio) { +function getTransform(translation, scale) { const result = []; if (translation) { result.push(`translate(${translation.x}px,${translation.y}px)`); } - if (ratio) { - result.push(`scale(${ratio})`); + if (scale) { + result.push(`scale(${scale})`); } return result.join(' '); }