From c61e3fafabb7e997a2f6f868e3a72f3a0e4c830e Mon Sep 17 00:00:00 2001 From: RenatZubakin Date: Fri, 22 Oct 2021 05:27:33 +0500 Subject: [PATCH] gg --- README.md | 14 ++--- index.html | 34 +++++++++- index.js | 177 +++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 190 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index c044e46..cfd0bd7 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ При клике на кнопку play возле названия анимации запустят ее. -1. Создай функцию с названием `animaster` +-1. Создай функцию с названием `animaster` -2. Сейчас функции-анимации (`move`, `fadeIn`, `scale`) лежат в глобальной области видимости и имеют очень простые названия — их легко случайно переопределить. Поэтому спрячь их определения внутрь функции `animaster`. Функция `animaster` должна возвращать объект с методами для запуска разных анимаций. Сделай так, чтобы кнопки на страничке все еще показывали анимацию. +-2. Сейчас функции-анимации (`move`, `fadeIn`, `scale`) лежат в глобальной области видимости и имеют очень простые названия — их легко случайно переопределить. Поэтому спрячь их определения внутрь функции `animaster`. Функция `animaster` должна возвращать объект с методами для запуска разных анимаций. Сделай так, чтобы кнопки на страничке все еще показывали анимацию. Использовать анимации теперь можно будет вот так: @@ -14,22 +14,22 @@ animaster().scale(element, 500, .8) ``` -3. По аналогии с функцией `fadeIn` создай функцию `fadeOut`, скрывающую элемент. +-3. По аналогии с функцией `fadeIn` создай функцию `fadeOut`, скрывающую элемент. -4. Мы хотим, немного облегчить жизнь пользователям анимастера, поэтому напишем для них несколько сложных анимаций. Сложные анимации состоят из нескольких простых, запущенных в правильном порядке и в нужное время. Добавь в интерфейс анимастера три новые анимации. Не забудь сделать так, чтобы с html-странички можно было их запустить. Вот такие анимации должен реализовывать анимастер: +-4. Мы хотим, немного облегчить жизнь пользователям анимастера, поэтому напишем для них несколько сложных анимаций. Сложные анимации состоят из нескольких простых, запущенных в правильном порядке и в нужное время. Добавь в интерфейс анимастера три новые анимации. Не забудь сделать так, чтобы с html-странички можно было их запустить. Вот такие анимации должен реализовывать анимастер: - `moveAndHide` — блок должен одновременно сдвигаться на 100 пикселей вправо и на 20 вниз, а потом исчезать. Метод на вход должен принимать продолжительность анимации. При этом 2/5 времени блок двигается, 3/5 — исчезает. - `showAndHide` — блок должен появиться, подождать и исчезнуть. Каждый шаг анимации длится 1/3 от времени, переданного аргументом в функцию. - `heartBeating` — имитация сердцебиения. Сначала элемент должен увеличиться в 1,4 раза, потом обратно к 1. Каждый шаг анимации занимает 0,5 секунды. Анимация должна повторяться бесконечно. -5. Сделай возможность отключать анимацию сердцебиения: +-5. Сделай возможность отключать анимацию сердцебиения: - сделай, чтобы метод `heartBeating` возвращал объект с методом `stop` - при вызове метода `stop` анимация должна прекращаться (скорее всего, нужно останавливать таймер, которым ты анимацию запускаешь) - добавь в разметку кнопку stop по аналогии с кнопкой play - в коде добавь обработчик клика по аналогии с тем, как это сделано для кнопки play. Обработчик должен вызывать метод `stop` анимации -6. Сделай функции отмены для каждой элементарной операции. Создай служебные (не доступные снаружи анимастера) функции `resetFadeIn`, `resetFadeOut` и `resetMoveAndScale`. Все эти функции принимают на вход элемент, на котором надо сбросить состояние. +-6. Сделай функции отмены для каждой элементарной операции. Создай служебные (не доступные снаружи анимастера) функции `resetFadeIn`, `resetFadeOut` и `resetMoveAndScale`. Все эти функции принимают на вход элемент, на котором надо сбросить состояние. `resetFadeIn` и `resetFadeOut` должны менять обратно css-классы в classList — каждая из них должны убирать все дописанные стили, устанавливая их в `null`: @@ -37,7 +37,7 @@ animaster().scale(element, 500, .8) element.style.заданныйАнимациейСтиль = null; ``` -7. Сделай кнопку reset для анимации `moveAndHide` по аналогии с кнопкой stop из одного из предыдущих пунктов. При нажатии на кнопку reset последующие шаги анимации должны отменяться аналогично stop из `heartBeating`, а элемент должен мгновенно вернуться в исходное состояние с помощью функций из предыдущего пункта. +-7. Сделай кнопку reset для анимации `moveAndHide` по аналогии с кнопкой stop из одного из предыдущих пунктов. При нажатии на кнопку reset последующие шаги анимации должны отменяться аналогично stop из `heartBeating`, а элемент должен мгновенно вернуться в исходное состояние с помощью функций из предыдущего пункта. 8. Сделай так, чтобы анимацию `move` можно было вызвать не только так: diff --git a/index.html b/index.html index 6546475..21aefc1 100644 --- a/index.html +++ b/index.html @@ -18,7 +18,7 @@

fadeIn

move

-
+
@@ -27,6 +27,38 @@

scale

+
+
+

move and hide

+ + +
+
+
+
+
+

show and hide

+ +
+
+
+
+
+

heart beating

+ + +
+
+
+ +
+
+

Невидимая анимация

+ +
+
+
+ diff --git a/index.js b/index.js index 61e55f6..30ab8e1 100644 --- a/index.js +++ b/index.js @@ -1,35 +1,131 @@ addListeners(); +const animator = animaster(); function addListeners() { document.getElementById('fadeInPlay') .addEventListener('click', function () { const block = document.getElementById('fadeInBlock'); - fadeIn(block, 5000); + block.classList.contains('hide') ? + animator.addFadeIn(2000).play(block): + animator.addFadeOut(2000).play(block); }); document.getElementById('movePlay') .addEventListener('click', function () { const block = document.getElementById('moveBlock'); - move(block, 1000, {x: 100, y: 10}); + animator.addMove(500, {x: 20, y:20}).play(block); }); document.getElementById('scalePlay') .addEventListener('click', function () { const block = document.getElementById('scaleBlock'); - scale(block, 1000, 1.25); + animator.addScale(1000,1.25).play(block); + }); + document.getElementById('moveHidePlay') + .addEventListener('click', function () { + const block = document.getElementById('moveHideBlock'); + animator.moveAndHide(block, 1000); + document + .getElementById("moveHideStop") + .addEventListener("click", function() { + animator.resetMoveAndScale(block); + animator.resetFadeOut(block); + }); + }); + document.getElementById('showAndHidePlay') + .addEventListener('click', function () { + const block = document.getElementById('showAndHide'); + animator.showAndHide(block, 1000); + }); + document.getElementById('heartBeatingPlay') + .addEventListener('click', function () { + const block = document.getElementById('heartBeating'); + animator.fadeIn(block, 1000); + let heartBeatingStop = animator.heartBeating(block, 1000); + document + .getElementById("heartBeatingStop") + .addEventListener("click", heartBeatingStop.stop); + }); } +function animaster(){ + + this.steps = []; -/** + return{ + /** * Блок плавно появляется из прозрачного. * @param element — HTMLElement, который надо анимировать * @param duration — Продолжительность анимации в миллисекундах + * _ */ -function fadeIn(element, duration) { - element.style.transitionDuration = `${duration}ms`; - element.classList.remove('hide'); - element.classList.add('show'); -} + + 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'); + }, + + resetFadeIn(element) { + element.style.transitionDuration = null; + element.classList.remove('show'); + element.classList.add('hide'); + }, + + resetFadeOut(element) { + element.style.transitionDuration = null; + element.classList.remove('hide'); + element.classList.add('show'); + }, + + resetMoveAndScale(element) { + element.style.transitionDuration = null; + element.style.transform = null; + element.classList.remove('hide'); + element.classList.add('show'); + }, + + addMove(duration, translation) { + return this.addAnimation('move', duration, translation); + }, + + addScale(duration, ratio) { + return this.addAnimation('scale', duration, ratio); + }, + + addFadeIn(duration) { + return this.addAnimation('fadeIn', duration); + }, + + addFadeOut(duration) { + return this.addAnimation('fadeOut', duration); + }, + + play(element, cycled = false) { + let sum = 0; + for (let step of steps) { + setTimeout( + () => this[step.animation](element, step.duration, ...step.other), + sum + ); + sum += step.duration; + } + steps=[]; + }, + addAnimation(animation, duration, ...other) { + steps.push({ + animation, + duration, + other + }); + return this; + }, /** * Функция, передвигающая элемент @@ -37,29 +133,56 @@ function fadeIn(element, duration) { * @param duration — Продолжительность анимации в миллисекундах * @param translation — объект с полями x и y, обозначающими смещение блока */ -function move(element, duration, translation) { - element.style.transitionDuration = `${duration}ms`; - element.style.transform = getTransform(translation, null); -} + move(element, duration, translation) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(translation, null); + }, -/** + moveAndHide(element,duration){ + const timing = duration / 5; + animator.move(element, timing*2, { x: 100, y: 20 }); + setTimeout(()=>animator.fadeOut(element,timing*3),timing * 2); + }, + showAndHide(element,duration){ + const timing = duration/3; + animator.fadeIn(element,timing*3); + setTimeout(timing*3) + setTimeout(()=>animator.fadeOut(element,timing*3),timing*3) + }, + heartBeating(element,duration){ + let beat = () => { + this.scale(element, duration / 2, 1.4); + setTimeout(() => this.scale(element, duration / 2, 1), duration / 2); + }; + let beating = setInterval(beat, duration); + return { + stop() { + clearInterval(beating); + } + }; + + }, + + + /** * Функция, увеличивающая/уменьшающая элемент * @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 getTransform(translation, ratio) { - const result = []; - if (translation) { - result.push(`translate(${translation.x}px,${translation.y}px)`); + scale(element, duration, ratio) { + element.style.transitionDuration = `${duration}ms`; + element.style.transform = getTransform(null, ratio); + }, } - if (ratio) { - result.push(`scale(${ratio})`); + 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(' '); } - return result.join(' '); -} +} \ No newline at end of file