aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/css/css_animations/tips/index.html
blob: 15929f62202d3190fba2eea56cd226bf487e62dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
---
title: CSS Animations tips and tricks
slug: Web/CSS/CSS_Animations/Tips
translation_of: Web/CSS/CSS_Animations/Tips
---
<div>{{cssref}}</div>

<p>CSS-анимация позволяет делать невероятные вещи с элементами, из которых состоят ваши документы и приложения. Однако есть вещи, которые не являются очевидными и, о способах реализации которых, вы не знаете, но вы бы хотели их реализовать. Эта статья представляет собой набор советов и трюков, которые мы нашли, чтобы облегчить вашу работу. В том числе, как снова запустить остановленную анимацию.</p>

<h2 id="Run_an_animation_again" name="Run_an_animation_again">Запустить анимацию снова</h2>

<p>Спецификация <a href="/en-US/docs/Web/CSS/CSS_Animations">CSS Animations</a> не предлагает способа запустить анимацию снова. Нет никакого волшебного метода resetAnimation () для элементов, и вы даже не можете просто установить элемент {{cssxref ("animation-play-state")}} в" running " снова. Вместо этого вы должны использовать хитрые трюки, чтобы запустить остановленную анимацию для воспроизведения.</p>

<p>Предлагаем вам один из способов, который мы считаем достаточно надёжным и стабильным.</p>

<h3 id="HTML_содержимое">HTML содержимое</h3>

<p>Во-первых, давайте определим HTML для {{HTMLElement("div")}} который мы хотим анимировать, и кнопку, которая будет запускать (или воспроизводить) анимацию.</p>

<pre class="brush: html">&lt;div class="box"&gt;
&lt;/div&gt;

&lt;div class="runButton"&gt;Click me to run the animation&lt;/div&gt;</pre>

<h3 id="CSS_содержимое">CSS содержимое</h3>

<p>Теперь мы определим саму анимацию с помощью CSS. Некоторые стили CSS, которые не важны (стиль самой кнопки "выполнить"), здесь не показаны, для краткости.</p>

<div class="hidden">
<pre class="brush: css">.runButton {
  cursor: pointer;
  width: 300px;
  border: 1px solid black;
  font-size: 16px;
  text-align: center;
  margin-top: 12px;
  padding-top: 2px;
  padding-bottom: 4px;
  color: white;
  background-color: darkgreen;
  font: 14px "Open Sans", "Arial", sans-serif;
}</pre>
</div>

<pre class="brush: css">@keyframes colorchange {
  0% { background: yellow }
  100% { background: blue }
}

.box {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}

.changing {
  animation: colorchange 2s;
}</pre>

<p>Здесь есть два класса. В классе <code>"box"</code> прописано основное описание внешнего вида элемента, без какой-либо анимационной информации. Детали анимации включены в класс <code>"changing"</code> , который сообщает, что {{cssxref("@keyframes")}} с именем <code>"colorchange"</code> должен использоваться в течение 2 секунд.</p>

<p>Обратите внимание, что каких-либо анимационных эффектов у элемента не наблюдается, т.е. анимации нет.</p>

<h3 id="JavaScript_содержимое">JavaScript содержимое</h3>

<p>Далее мы рассмотрим JavaScript, который дополняет эту работу. Основа этой техники находится в функции play (), которая вызывается, когда пользователь нажимает на кнопку "Выполнить".</p>

<pre class="brush: js">function play() {
  document.querySelector(".box").className = "box";
  window.requestAnimationFrame(function(time) {
    window.requestAnimationFrame(function(time) {
      document.querySelector(".box").className = "box changing";
    });
  });
}</pre>

<p>Это выглядит странно, не так ли? Это потому, что единственный способ воспроизвести анимацию снова-удалить анимационный эффект, позволить документу пересчитать стили так, чтобы он знал, что вы это сделали, а затем добавить анимационный эффект обратно в элемент. Чтобы это произошло, мы должны быть креативными.</p>

<p>Вот что происходит, когда вызывается функция <code>play()</code> :</p>

<ol>
 <li>Список классов CSS в элементе сбрасывается до простого "box". Это приводит к удалению всех других классов, которые в настоящее время применяются к элементу, включая класс <code>"changing"</code> , который обрабатывает анимацию. Другими словами, мы удаляем анимационный эффект из элемента. Однако изменения в списке классов не вступают в силу до тех пор, пока не будет завершен перерасчет стиля и не произойдет обновление, отражающее это изменение.</li>
 <li>Чтобы убедиться, что стили пересчитаны, мы используем  {{domxref("window.requestAnimationFrame()")}} с колбэком. Наш колбэк выполняется непосредственно перед следующей перерисовкой документа. Проблема заключается в том,что, поскольку это происходит до перерисовки, перерасчёт стиля ещё не произошёл! </li>
 <li>Наш колбэк ловко вызывает <code>requestAnimationFrame()</code> второй раз! На этот раз колбэк выполняется до следующей перерисовки, то есть после того, как произошла перерасчёт стиля. Этот колбэк добавляет класс <code>"changing"</code> обратно в элемент, так что перерисовка снова запустит анимацию.</li>
</ol>

<p>Конечно, нам также нужно добавить обработчик событий к нашей кнопке "выполнить", чтобы она действительно что-то делала:</p>

<pre class="brush: js">document.querySelector(".runButton").addEventListener("click", play, false);</pre>

<h3 id="Результат">Результат</h3>

<p>{{ EmbedLiveSample('Run_an_animation_again', 320, 160) }}</p>

<h2 id="Остановка_анимации">Остановка анимации</h2>

<p>Простое удаление {{cssxref("animation-name")}} применённого к элементу, заставит его исчезнуть или перейти в следующее состояние. Если вместо этого вы хотите, чтобы анимация закончилась, а затем остановилась, вам нужно попробовать другой подход. Главные хитрости заключаются в следующем:</p>

<ol>
 <li>Сделайте свою анимацию настолько самодостаточной, насколько это возможно. Это означает, что вы не должны полагаться на <code>animation-direction: alternate</code>. Вместо этого вы должны явно написать анимацию ключевого кадра, которая проходит через полную анимацию в одном прямом повторении.</li>
 <li>Используйте JavaScript и очистите анимацию, используемую при запуске события<code>animationiteration</code> .</li>
</ol>

<p>Следующая демонстрация показывает, как вы могли бы достичь вышеупомянутой техники JavaScript:</p>

<pre class="brush: css">.slidein {
  animation-duration: 5s;
  animation-name: slidein;
  animation-iteration-count: infinite;
}

.stopped {
  animation-name: none;
}

@keyframes slidein {
  0% {
    margin-left: 0%;
  }
  50% {
    margin-left: 50%;
  }
  100% {
    margin-left: 0%;
  }
}
</pre>

<pre class="brush: html">&lt;h1 id="watchme"&gt;Click me to stop&lt;/h1&gt;
</pre>

<pre class="brush: js">let watchme = document.getElementById('watchme')

watchme.className = 'slidein'
const listener = (e) =&gt; {
  watchme.className = 'slidein stopped'
}
watchme.addEventListener('click', () =&gt;
  watchme.addEventListener('animationiteration', listener, false)
)
</pre>

<p>Demo <a href="https://jsfiddle.net/morenoh149/5ty5a4oy/">https://jsfiddle.net/morenoh149/5ty5a4oy/</a></p>

<h2 id="Смотрите_также">Смотрите также</h2>

<ul>
 <li><a href="/en-US/docs/Web/Guide/CSS/Using_CSS_transitions">Using CSS transitions</a></li>
 <li>{{domxref("Window.requestAnimationFrame()")}}</li>
</ul>