Skip to content

Commit

Permalink
Review fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
nglazov committed May 22, 2019
1 parent c0c86b3 commit b3cbae9
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 22 deletions.
8 changes: 3 additions & 5 deletions 7-animation/3-js-animation/1-animate-ball/solution.md
@@ -1,10 +1,8 @@
Чтобы заставить мячик прыгать можно использовать CSS-свойство `top` и задать мячику `position:absolute` внутри поля с `position:relative`.
Чтобы заставить мячик прыгать, можно использовать CSS-свойство `top` и задать мячику `position:absolute` внутри поля с `position:relative`.

Нижняя координата поля -- `field.clientHeight`. Но свойство `top` соответствует координате мяча от верхней границы мяча, конечная позиция мяча может быть вычислена так: `field.clientHeight - ball.clientHeight`.
Нижняя координата поля -- `field.clientHeight`. CSS-свойство `top` относится к верхней границе мяча, которая должна идти от 0 до `field.clientHeight - ball.clientHeight`.

Итак мы анимируем свойство `top` от `0` до `field.clientHeight - ball.clientHeight`.

Теперь, чтобы получить эффект "скачущего" мяча, мы можем использовать временную функцию `bounce` в режиме `easeOut`.
А чтобы получить эффект "скачущего" мяча, мы можем использовать функцию расчета времени `bounce` в режиме `easeOut`.

Вот конечный код для анимации:

Expand Down
2 changes: 1 addition & 1 deletion 7-animation/3-js-animation/2-animate-ball-hops/task.md
Expand Up @@ -2,7 +2,7 @@ importance: 5

---

# Создайте анимацию мячика прыгающего вправо
# Анимируйте мячик, прыгающий вправо

Сделайте отскок мяча вправо. Как в примере:

Expand Down
32 changes: 16 additions & 16 deletions 7-animation/3-js-animation/article.md
Expand Up @@ -6,7 +6,7 @@

## Использование setInterval

Анимация может быть представлена в виде последовательности кадров (каждый кадр немного меняет HTML/CSS-свойства).
Анимация реализуется через последовательность кадров, каждый из которых немного меняет HTML/CSS-свойства.

Например, изменение `style.left` от `0px` до `100px` -- двигает элемент. И если мы будем делать это с помощью `setInterval`, изменяя на `2px` с небольшими интервалами времени, например 50 раз в секунду, тогда изменения будут выглядеть плавными. Принцип такой же, как в кино: 24 кадров в секунду достаточно, чтобы создать эффект плавности.

Expand Down Expand Up @@ -38,7 +38,7 @@ let timer = setInterval(function() {

}, 20);

// как timePassed меняет значение от 0 до 2000
// в то время как timePassed идет от 0 до 2000
// left изменяет значение от 0px до 400px
function draw(timePassed) {
train.style.left = timePassed / 5 + 'px';
Expand Down Expand Up @@ -75,20 +75,20 @@ setInterval(animate2, 20); // в разных местах кода
setInterval(animate3, 20);
```

Независимые перерисовки, сгруппированные вместе, облегчают процесс перерисовки для браузера (и выглядят более плавными для пользователя).
Эти независимые перерисовки лучше сгруппировать вместе, тогда они будут легче для браузера, а значит - не грузить процессор и более плавно выглядеть.

Существует еще одна вещь, про которую надо помнить: когда CPU перегружен или еще по какой-то причине (например, когда вкладка браузера скрыта), нам не следует запускать перерисовку каждые `20ms`.
Существует еще одна вещь, про которую надо помнить: когда CPU перегружен или есть другие причины делать перерисовку реже (например, когда вкладка браузера скрыта), нам не следует делать её каждые `20ms`.

Но как нам узнать об этом в JavaScript? Спецификация о [Animation timing](http://www.w3.org/TR/animation-timing/) описывает функцию `requestAnimationFrame`, которая решает все описанные проблемы и делает даже больше.
Но как нам узнать об этом в JavaScript? Спецификация [Animation timing](http://www.w3.org/TR/animation-timing/) описывает функцию `requestAnimationFrame`, которая решает все описанные проблемы и делает даже больше.

Синтаксис:
```js
let requestId = requestAnimationFrame(callback)
```

Такой вызов планирует запуск функции `callback` в ближайшее время, когда браузер сочтёт возможным осуществить анимацию.
Такой вызов планирует запуск функции `callback` на ближайшее время, когда браузер сочтёт возможным осуществить анимацию.

Если в `callback` происходит изменение элемента, тогда оно будет выполнено с другими `requestAnimationFrame` и CSS-анимациями. Таким образом браузер выполнит один геометрический пересчёт и отрисовку, вместо нескольких.
Если в `callback` происходит изменение элемента, тогда оно будет сгруппировано с другими `requestAnimationFrame` и CSS-анимациями. Таким образом браузер выполнит один геометрический пересчёт и отрисовку, вместо нескольких.

Значение `requestId` может быть использовано для отмены анимации:
```js
Expand All @@ -98,9 +98,9 @@ cancelAnimationFrame(requestId);

Функция `callback` имеет один аргумент -- время прошедшее с момента начала загрузки страницы в миллисекундах. Это значение может быть получено с помощью вызова [performance.now()](mdn:api/Performance/now).

Существуют причины, когда запуск анимации откладывается (обычно выполняется практически сразу после `requestAnimationFrame`), например CPU перегружен или аккумулятор ноутбука почти разряжен.
Как правило, `callback` запускается очень скоро, если только не перегружен CPU или не разряжена батарея ноутбука, или у браузера нет какой-то ещё причины замедлиться.

Код ниже показывает время проходящее между первыми 10 запусками `requestAnimationFrame`. Обычно оно 10-20 мс:
Код ниже показывает время между первыми 10 запусками `requestAnimationFrame`. Обычно оно 10-20 мс:

```html run height=40 refresh
<script>
Expand Down Expand Up @@ -176,7 +176,7 @@ function animate({timing, draw, duration}) {
}
```

...Или что-нибудь ещё. Так или иначе, мы можем анимировать всё что угодно.
...Или делать что-нибудь ещё. Мы можем анимировать что угодно, как захотим.


Теперь давайте используем нашу функцию, чтобы анимировать свойство `width` от `0` до `100%`.
Expand Down Expand Up @@ -350,9 +350,9 @@ let bounceEaseOut = makeEaseOut(bounce);

![](bounce-inout.png)

Если есть такой анимационный эффект, как отскоки -- то после трансформации он будет показан в конце.
Если раньше анимационный эффект, такой как отскоки, был в начале, то после трансформации он будет показан в конце.

На графике выше красным цветом обозначена <span style="color:#EE6B47">обычная функция</span> и синим -- <span style="color:#62C0DC">инвертированная</span>.
На графике выше красным цветом обозначена <span style="color:#EE6B47">обычная функция</span> и синим -- <span style="color:#62C0DC">после easeOut</span>.

- Обычный скачок -- объект сначала медленно скачет внизу, а затем резко подпрыгивает вверх.
- Обратный `easeOut` -- объект вначале прыгает вверх, и затем скачет там.
Expand All @@ -361,7 +361,7 @@ let bounceEaseOut = makeEaseOut(bounce);

Мы можем применить эффект дважды -- в начале и конце анимации. Такая трансформация называется "easeInOut".

Для этой функции расчёта времени, анимация будет вычисляться следующим образом:
Для функции расчёта времени, анимация будет вычисляться следующим образом:

```js
if (timeFraction <= 0.5) { // первая половина анимации
Expand Down Expand Up @@ -402,7 +402,7 @@ bounceEaseInOut = makeEaseInOut(bounce);

Как видно, график первой половины анимации представляет собой уменьшенный `easeIn`, а второй – уменьшенный `easeOut`. В результате, анимация начинается и заканчивается одинаковым эффектом.

## Ещё интересней функция "draw"
## Более интересная функция "draw"

Вместо передвижения элемента мы можем делать что-нибудь ещё. Всё, что нам нужно -- это правильно написать функцию `draw`.

Expand All @@ -414,7 +414,7 @@ bounceEaseInOut = makeEaseInOut(bounce);

JavaScript может помочь в тех случаях, когда CSS не справляется или нужен жесткий контроль над анимацией. JavaScript-анимации должны быть сделаны с помощью `requestAnimationFrame`. Это встроенный метод браузера, который вызывает переданную в него функцию в тот момент, когда браузер готовится совершить перерисовку (обычно это происходит быстро, но конкретные задержки зависят от браузера).

Когда вкладка скрыта, на ней совсем не происходит перерисовок и функция не будет вызвана: анимация будет приостановлена и не потратит ресурсы. Это хорошо.
Когда вкладка скрыта, на ней совсем не происходит перерисовок, и функция не будет вызвана: анимация будет приостановлена и не потратит ресурсы. Это хорошо.

Вспомогательная функция `animate` для создания анимации:

Expand Down Expand Up @@ -447,7 +447,7 @@ function animate({timing, draw, duration}) {
- `timing` -- функция вычисления прогресса анимации. Получается момент времени от 0 до 1, возвращает прогресс анимации, обычно тоже от 0 до 1.
- `draw` -- функция отрисовки анимации.

Конечно, мы могли бы улучшить вспомогательную функцию и добавить в неё больше наворотов. Но JavaScript-анимации не каждый день используются, а только когда хотят сделать что-то интересное и необычное. Не стоит усложнять функцию, до тех пор пока это вам не понадобились.
Конечно, мы могли бы улучшить вспомогательную функцию и добавить в неё больше наворотов. Но JavaScript-анимации не каждый день используются, а только когда хотят сделать что-то интересное и необычное. Не стоит усложнять функцию до тех пор пока это вам не понадобились.

JavaScript-анимации могут использовать любые функции расчёта времени. Мы рассмотрели множество примеров и их вариаций, чтобы сделать их еще более универсальными. В отличие от CSS, мы здесь не ограничены только кривой Безье.

Expand Down

0 comments on commit b3cbae9

Please sign in to comment.