diff --git a/index.html b/index.html index 6546475..4a261df 100644 --- a/index.html +++ b/index.html @@ -10,13 +10,23 @@

fadeIn

+
+
+
+

fadeOut

+ + +
+
+

move

+
@@ -24,10 +34,56 @@

move

scale

+
- +
+
+

background

+ + +
+
+
+
+
+

showAndHide

+ + +
+
+
+
+
+

moveAndHide

+ + +
+
+
+
+
+

heartBeat

+ + +
+
+
+
+
+

animationMet

+ + +
+
+
+
+
+

worryAnimation

+
+
+
- \ No newline at end of file + diff --git a/index.js b/index.js index 61e55f6..a25675d 100644 --- a/index.js +++ b/index.js @@ -1,56 +1,208 @@ 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); - }); -} +function animaster() { + this.step = []; + this.coping = function () { + let copy = Object.assign({}, this); + copy.step = copy.step.slice(); + return copy + } -/** - * Блок плавно появляется из прозрачного. - * @param element — HTMLElement, который надо анимировать - * @param duration — Продолжительность анимации в миллисекундах - */ -function fadeIn(element, duration) { - element.style.transitionDuration = `${duration}ms`; - element.classList.remove('hide'); - element.classList.add('show'); -} + let currentCommand = { + fadeIn(element, duration) { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('hide'); + element.classList.add('show'); + }, + + resetFadeIn(element) { + element.style = null; + element.classList.add('hide'); + element.classList.remove('show'); + }, + + fadeOut(element, duration) { + element.style.transitionDuration = `${duration}ms`; + element.classList.remove('show'); + element.classList.add('hide'); + }, + + resetFadeOut(element) { + element.style = null; + element.classList.add('show'); + element.classList.remove('hide'); + }, + + move(element, duration, translation) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(translation, null); + }, + + scale(element, duration, ratio) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(null, ratio); + }, + + resetMoveAndScale(element) { + element.style = null; + }, + + changeColor(element, duration, color) { + element.style.transitionDuration = `${duration}ms`; + element.style.backgroundColor = color; + } + } + + this.addMoveAndHide = function (duration, translation) { + let add = this.addMove(duration * 0.4, translation); + add = add.addFadeOut(duration * 0.6); + return add; + }; + + this.addShowAndHide = function (duration) { + let add = this.addFadeIn(duration * 1 / 3); + add = add.addDelay(duration * 1 / 3); + add = add.addFadeOut(duration * 1 / 3); + return add; + }; + + this.addMove = function (duration, translation) { + let add = this.coping(); + add.step.push({command: "move", duration, translation}); + return add; + }; + + this.addScale = function (duration, ratio) { + let add = this.coping(); + add.step.push({command: "scale", duration, ratio}); + return add; + }; + + this.addDelay = function (duration) { + let add = this.coping(); + add.step.push({duration}); + return add; + }; -/** - * Функция, передвигающая элемент - * @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); + this.addChangeColor = function (duration, color) { + let add = this.coping(); + add.step.push({command: "changeColor", duration, color}); + return add; + } + + this.addHeartBeat = function () { + let add = this.addScale(300, 1.4); + add = add.addScale(300, 1); + return add; + }; + + this.addFadeIn = function (duration) { + let add = this.coping(); + add.step.push({command: "fadeIn", duration}); + return add; + }; + + this.addFadeOut = function (duration) { + let add = this.coping(); + add.step.push({command: "fadeOut", duration}); + return add; + } + + this.buildHandler = function () { + return (elem) => this.play(elem.target); + } + + this.play = function (element, unending) { + let commandArray = []; + let commands = () => { + let duration = 0; + for (const step of this.step) { + commandArray.push(setTimeout(() => + currentCommand[step["command"]] === undefined + || currentCommand[step["command"]](element, step["duration"], step["translation"] + || step["ratio"] + || step["color"]), duration)); + duration += step["duration"]; + } + }; + + let interval; + if (!unending) commands(); + else interval = setInterval(() => commands(), this.step.reduce((a, b) => a["duration"] + b["duration"])); + + return { + reset: (element) => { + commandArray.forEach(x => clearTimeout(x)); + if (element.classList.contains("show") || !element.classList.contains("hide")) + currentCommand.resetFadeOut(element); + else + currentCommand.resetFadeIn(element); + currentCommand.resetMoveAndScale(element); + }, + stop: () => { + clearInterval(interval); + } + } + }; + return this; } -/** - * Функция, увеличивающая/уменьшающая элемент - * @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 addListeners() { + + function addHandlerOnButton(elementId, animation, unending) { + let reset; + document.getElementById(`${elementId}Play`) + .addEventListener('click', function () { + const block = document.getElementById(`${elementId}Block`); + reset = animation.play(block, unending); + }); + document.getElementById(unending ? `${elementId}Stop` : `${elementId}Reset`) + .addEventListener('click', function () { + const block = document.getElementById(`${elementId}Block`); + console.log(reset); + reset = unending ? reset["stop"] : reset["reset"]; + reset(block); + }); + } + + const animationMet = animaster() + .addMove(200, {x: 40, y: 40}) + .addScale(800, 1.3) + .addChangeColor(100, "DarkOrchid") + .addMove(200, {x: 40, y: -40}) + .addScale(800, 1) + .addChangeColor(100, "MediumPurple") + .addMove(200, {x: -40, y: -40}) + .addScale(800, 0.7) + .addChangeColor(100, "BlueViolet") + .addMove(200, {x: -40, y: 40}) + .addScale(800, 1) + .addChangeColor(100, "DarkViolet") + .addMove(200, {x: 40, y: 40}) + .addScale(800, 1.3) + .addChangeColor(100, "Purple") + .addMove(200, {x: 40, y: -40}) + .addScale(800, 1) + .addChangeColor(100, "Indigo") + .addMove(200, {x: 0, y: 0}) + + 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(); + + addHandlerOnButton('fadeIn', animaster().addFadeIn(5000), false); + addHandlerOnButton('fadeOut', animaster().addFadeOut(5000), false); + addHandlerOnButton('move', animaster().addMove(1000, {x: 100, y: 10}), false); + addHandlerOnButton('scale', animaster().addScale(1000, 1.25), false); + addHandlerOnButton('moveAndHide', animaster().addMoveAndHide(2000, {x: 100, y: 20}), false); + addHandlerOnButton('showAndHide', animaster().addShowAndHide(2000), false); + addHandlerOnButton("heartBeat", animaster().addHeartBeat(), true); + addHandlerOnButton('background', animaster().addChangeColor(1000, "white"), false); + addHandlerOnButton('animationMet', animationMet, false); + document.getElementById('worryAnimationBlock').addEventListener('click', worryAnimationHandler); } function getTransform(translation, ratio) {