aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/web/css/css_animations/using_css_animations/index.html
blob: 82acb8ac6ee659fd6106489343f4dd72de8393d1 (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
---
title: CSS 動畫
slug: Web/CSS/CSS_Animations/Using_CSS_animations
tags:
  - Advanced
  - CSS animation
  - CSS 動畫
  - Example
  - Experimental
  - Guide
translation_of: Web/CSS/CSS_Animations/Using_CSS_animations
---
<p><span class="diff_add">{{SeeCompatTable}}{{CSSRef}}</span></p>

<div>
<p> CSS animations 使 CSS style configuration 的轉變變得可行。在這種動畫的運作上,你只需要定義兩個部份:1. 動畫的最初及結尾 2. 動畫轉變的方式。</p>

<p>  相較於傳統 script-driven 的動畫技術,CSS animations 有三種好處:</p>

<ol>
 <li>對於不複雜的動畫來說,CSS animation 是好選擇。你甚至不必懂得  JavaScript。</li>
 <li>在資源消耗上,CSS animation 有優勢,即使在系統負載超過 50% 仍可有效運作。在 JavaScript 上要達到一樣的目的有賴於你寫出品質非常好的  code。事實上,CSS animation 在運作上可以適時的減少 frame 量或以其它技術減少資源消耗。</li>
 <li>CSS animation 讓瀏覽器來負責動畫的產生過程,如此可以擁有較好的優化。</li>
</ol>

<h2 id="CSS_animation_設定">CSS animation 設定</h2>

<p>  你可以使用 {{ cssxref("animation") }} property 或其 sub-properties 來創建 CSS 動畫的細節(諸如轉化時間等)。但這並不能決定動畫的外觀,外觀的部份我們將在下面的 {{ anch("使用關鍵影格定義動畫流程") }} 介紹。</p>

<p>  這裡是 {{ cssxref("animation") }} property 的 sub-properties:</p>

<dl>
 <dt>{{ cssxref("animation-delay") }}</dt>
 <dd>定義元素讀取完畢到動畫開始的間隔時間。</dd>
 <dt>{{ cssxref("animation-direction") }}</dt>
 <dd>定義是否動畫播放完畢後將會反向播放。</dd>
 <dt>{{ cssxref("animation-duration") }}</dt>
 <dd>定義動畫完成一次週期的時間。</dd>
 <dt>{{ cssxref("animation-iteration-count") }}</dt>
 <dd>定義動畫重複的次數。你可以用 <code>infinite</code> 來讓動畫永遠重複播放。</dd>
 <dt>{{ cssxref("animation-name") }}</dt>
 <dd>定義關鍵影格 {{ cssxref("@keyframes") }} 的名字。</dd>
 <dt>{{ cssxref("animation-play-state") }}</dt>
 <dd>控制動畫的播放狀態。有 pause 和 running 兩種值,後者為預設值。</dd>
 <dt>{{ cssxref("animation-timing-function") }}</dt>
 <dd>定義動畫轉變時時間的加速曲線 (例如 linear)。</dd>
 <dt>{{ cssxref("animation-fill-mode") }}</dt>
 <dd>定義元素在動畫播放外(動畫開始前及結束後)的狀態。</dd>
</dl>

<h2 id="使用關鍵影格定義動畫流程">使用關鍵影格定義動畫流程</h2>

<p>  在你設定了動畫的時間資訊之後,你必須要設定動畫漸變的過程。這可以藉由建造兩個或更多的關鍵影格來達到目的 (使用 {{ cssxref("@keyframes") }} )。關鍵影格描述了該元素在漸變過程中的外觀。</p>

<p>  因為動畫漸變時間已經在 CSS style 中被定義(見上節),所以關鍵影格使用 {{ cssxref("percentage") }} 來指出他們會在整個漸變流程中的哪個時間點出現。 0% 代表他是整個動畫的起點,而 100% 指出他是整個動畫的結束點。這兩個特殊時間點一定要被定義,如此一來瀏覽器材知道該如何產生你的動畫。也因為他們是如此重要,所以這兩個時間點有特殊的別名: <code>from</code> 和 <code>to。</code></p>

<p>  當然你也可以在動畫轉變過程中增加更多的關鍵影格。</p>

<h2 id="範例">範例</h2>

<div class="note"><strong>注意:</strong> 為了簡潔起見,以下的範例中我們只列出前綴為 <code>-moz-</code> 的部份。當你查看 Live Sample 的原始碼時,可以看到前綴為 <code>-webkit-</code> 的部份。</div>

<h3 id="使文字滑過畫面">使文字滑過畫面</h3>

<p>  這是一個簡單的範例,他展示了 {{ HTMLElement("p") }} element 從畫面右方滑向左方。</p>

<pre class="brush: css">&lt;style type="text/css"&gt;
  p {
    -moz-animation-duration: 3s;
    -moz-animation-name: slidein;
  }

  @-moz-keyframes slidein {
    from {
      margin-left: 100%;
      width: 300%
    }

    to {
      margin-left: 0%;
      width: 100%;
    }
  }
&lt;/style&gt;
</pre>

<p>  這裡用 {{ cssxref("animation-duration") }} property 定義 {{ HTMLElement("p") }} element 的變動自開始到結束共花 3 秒。而關鍵影格的名稱由 {{ cssxref("@keyframes") }} 指定 - 叫做 slidein。</p>

<p>  傳統的 {{ HTMLElement("p") }} element 尚有其他性質可供設定,但假設這些性質並不支援 CSS animation,則我們不能期待他們會被瀏覽器顯示。</p>

<p>  這裡的關鍵影格我們定義了兩個 (以 {{ cssxref("@keyframes") }} 定義),開始 (0%)和結束 (100%)。開始的影格在 from 中,而結束在 to 中。由程式中我們可以看到,整個動畫由最一開始處於最右方且 width 為 300% 轉變為處於最左方且 width 為 100%。如此一來你就可以看到 {{ HTMLElement("p") }} element 由右而左的滑過畫面。</p>

<p>  結束影格描述 width 為 100% 可以確保 {{ HTMLElement("p") }} element 在可視範圍內。</p>

<pre class="brush: html">&lt;p&gt;The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.&lt;/p&gt;
</pre>

<p>{{EmbedLiveSample("使文字滑過畫面","100%","250")}}</p>

<h3 id="在開頭和結束間加入關鍵影格">在開頭和結束間加入關鍵影格</h3>

<p>  現在我們試著多加入新的關鍵影格。在這個範例中,我們希望做到在文字在移動時字體先變大而後恢復正常。程式碼如下:</p>

<pre class="brush: css">75% {
  font-size: 300%;
  margin-left: 25%;
  width: 150%;
}
</pre>

<pre class="brush: css hidden">p {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
</pre>

<pre class="brush: html hidden">&lt;p&gt;The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.&lt;/p&gt;
</pre>

<p>  這段程式碼告訴瀏覽器在開始後過了 75% 的時間後字體增大到三倍,且位置在離左側 25 % 處,此時總寬度為 150%。</p>

<p>{{EmbedLiveSample("在開頭和結束間加入關鍵影格","100%","250")}}</p>

<h3 id="重複播放">重複播放</h3>

<p>  為了達到重複播放的目的,我們使用 {{ cssxref("animation-iteration-count") }} property。讓我們把它設定成 <code>infinite</code> :</p>

<pre class="brush: css">p {
  -moz-animation-duration: 3s;
  -moz-animation-name: slidein;
  -moz-animation-iteration-count: infinite;
} </pre>

<pre class="brush: css hidden">@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
</pre>

<pre class="brush: html hidden">&lt;p&gt;The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.&lt;/p&gt;
</pre>

<p>{{EmbedLiveSample("重複播放","100%","250")}}</p>

<h3 id="播放完畢後反向播放">播放完畢後反向播放</h3>

<p>  由上個例子我們知道該如何永久性播放動畫。但這個顯示結果有些突兀,是以我們試著讓他播放完畢後倒帶執行。這需要用到 {{ cssxref("animation-direction") }},賦予 <code>alternate 的值:</code></p>

<pre class="brush: css">p {
  -moz-animation-duration: 3s;
  -moz-animation-name: slidein;
  -moz-animation-iteration-count: infinite;
  -moz-animation-direction: alternate;
} </pre>

<pre class="brush: css hidden">@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
</pre>

<pre class="brush: html hidden">&lt;p&gt;The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.&lt;/p&gt;
</pre>

<p>{{EmbedLiveSample("播放完畢後反向播放","100%","250")}}</p>

<h3 id="使用動畫的事件">使用動畫的事件</h3>

<p>  你可以藉由 animation event 來對 CSS animation 做更進階的控制,這需要用到 {{ domxref("event/AnimationEvent", "AnimationEvent") }} 物件。他可以用來偵測動畫所處的時間點等資訊。每個 event 包含發生的時間以及觸發 event 的動畫名字。</p>

<p>  我們將修改剛剛的範例來展示 animation event 的能力。</p>

<pre class="brush: css">.slidein {
  -moz-animation-duration: 3s;
  -webkit-animation-duration: 3s;
  animation-duration: 3s;
  -moz-animation-name: slidein;
  -webkit-animation-name: slidein;
  animation-name: slidein;
  -moz-animation-iteration-count: 3;
  -webkit-animation-iteration-count: 3;
  animation-iteration-count: 3;
  -moz-animation-direction: alternate;
  -webkit-animation-direction: alternate;
  animation-direction: alternate;
}

@-moz-keyframes slidein {
  from {
    margin-left:100%;
    width:300%
  }

  to {
    margin-left:0%;
    width:100%;
  }
}

@-webkit-keyframes slidein {
  from {
    margin-left:100%;
    width:300%
  }

  to {
   margin-left:0%;
   width:100%;
 }
}

@keyframes slidein {
  from {
    margin-left:100%;
    width:300%
  }

  to {
   margin-left:0%;
   width:100%;
 }
}</pre>

<h4 id="設定_animation_event_listeners">設定 animation event listeners</h4>

<p>  我們使用 JavaScript 來監控所有可能的 animation events。下面的 <code>setup()</code> 函式設定我們的 event listeners,並且在文件第一次被載入時執行他:</p>

<pre class="brush: js">function setup() {
  var e = document.getElementById("watchme");
  e.addEventListener("animationstart", listener, false);
  e.addEventListener("animationend", listener, false);
  e.addEventListener("animationiteration", listener, false);

  var e = document.getElementById("watchme");
  e.className = "slidein";
}
</pre>

<p>  這是非常簡單的程式,你可以從其它相關文件中取得 {{ domxref("element.addEventListener()") }} 的更多細節。setup() 函式所做的最後一件事是設定這個 element 的 class name 為 slidein,此時,我們啟動了這個動畫。</p>

<p>  這麼做的原因是 <code>animationstart</code> event 會在被動畫執行時立刻被觸發,所以我們只好在最後才設定 class name。</p>

<h4 id="接收_events">接收 events</h4>

<p>  這些 events 會被發送到 <code>listener()</code> 函式,如下所示:</p>

<pre class="brush: js">function listener(e) {
  var l = document.createElement("li");
  switch(e.type) {
    case "animationstart":
      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
      break;
    case "animationend":
      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
      break;
    case "animationiteration":
      l.innerHTML = "New loop started at time " + e.elapsedTime;
      break;
  }
  document.getElementById("output").appendChild(l);
}
</pre>

<p>  這段程式檢查藉由檢查 {{ domxref("event.type") }} 得知現在收到了哪種 animation event,並且以一個 {{ HTMLElement("ul") }} (unordered list) 形式的記錄下他。</p>

<p>  程式執行結果看起來會是這樣子的:</p>

<ul id="output">
 <li>Started: elapsed time is 0</li>
 <li>New loop started at time 3.01200008392334</li>
 <li>New loop started at time 6.00600004196167</li>
 <li>Ended: elapsed time is 9.234000205993652</li>
</ul>

<p>  注意這裡的時間是一個範例,你自己執行可能會取得不一樣的結果(但應該會近似)。此外,在動畫的最後,event 會是 <code>animationend</code> 而非  <code>animationiteration</code> 。</p>

<h4 id="完整的_HTML_程式碼">完整的 HTML 程式碼</h4>

<p>  這裡是完整的 HTML 程式碼:</p>

<pre class="brush: html">&lt;body onload="setup()"&gt;
  &lt;h1 id="watchme"&gt;Watch me move&lt;/h1&gt;
  &lt;p&gt;This example shows how to use CSS animations to make &lt;code&gt;h1&lt;/code&gt; elements
  move across the page.&lt;/p&gt;
  &lt;p&gt;In addition, we output some text each time an animation event fires, so you can see them in action.&lt;/p&gt;
  &lt;ul id="output"&gt;
  &lt;/ul&gt;
&lt;/body&gt; </pre>

<p>{{EmbedLiveSample('使用動畫的事件', '600', '300')}}</p>

<h2 id="更多資訊">更多資訊</h2>

<ul>
 <li>{{ domxref("Event/AnimationEvent", "AnimationEvent") }}</li>
 <li><a href="/en/CSS/CSS_animations/Detecting_CSS_animation_support" title="en/CSS/CSS animations/Detecting CSS animation support">Detecting CSS animation support</a></li>
</ul>
</div>

<p> </p>