diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/api/web_animations_api | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/zh-cn/web/api/web_animations_api')
3 files changed, 712 insertions, 0 deletions
diff --git a/files/zh-cn/web/api/web_animations_api/index.html b/files/zh-cn/web/api/web_animations_api/index.html new file mode 100644 index 0000000000..76f53da385 --- /dev/null +++ b/files/zh-cn/web/api/web_animations_api/index.html @@ -0,0 +1,167 @@ +--- +title: Web Animations API +slug: Web/API/Web_Animations_API +tags: + - web animations api +translation_of: Web/API/Web_Animations_API +--- +<p>{{DefaultAPISidebar("Web Animations")}}{{ SeeCompatTable() }}</p> + +<div class="summary"> +<p><strong>Web Animations API </strong>允许同步和定时更改网页的呈现, 即DOM元素的动画。它通过组合两个模型来实现:时序模型 和 动画模型。</p> +</div> + +<h2 id="概念和用法">概念和用法</h2> + +<dl> + <dd>Web Animations API 为浏览器和开发人员提供了一种用于描述DOM元素的动画的通用语言。要获得有关API背后的概念以及如何使用它的更多信息,请阅读<a href="/zh-CN/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API">使用Web Amimations API</a>。</dd> +</dl> + +<h2 id="网页动画接口">网页动画接口</h2> + +<dl> +</dl> + +<dl> + <dt>{{domxref("Animation")}}</dt> + <dd>提供播放控制、动画节点或源的时间轴。 可以接受使用{{domxref("KeyframeEffect.KeyframeEffect")}}构造函数创建的对象作为参数。</dd> + <dt>{{domxref("KeyframeEffect")}}</dt> + <dd>描述动画属性的集合,调用<strong>keyframes</strong>及{{domxref("Animation Effect Timing Properties")}}。 然后可以使用 {{domxref("Animation")}} 构造函数进行播放。</dd> + <dt>{{domxref("AnimationTimeline")}}</dt> + <dd>表示动画的时间轴。 此接口用以定义时间轴功能(继承自{{domxref("DocumentTimeline")}}和{{domxref("future timeline")}}),并且本身不被开发人员访问。</dd> + <dt>{{domxref("DocumentTimeline")}}</dt> + <dd>表示动画时间轴,包括默认的{{domxref("DocumentTimeline")}}(通过{{domxref("Document.timeline")}}访问)。</dd> + <dt>{{domxref("AnimationEffectTiming")}}</dt> + <dd>包含{{domxref("KeyframeEffect")}}的{{domxref("KeyframeEffect.timing", "timing")}}返回的定时属性对象。 它从{{domxref("AnimationEffectTimingReadOnly")}}继承其属性,但是以非只读形式。</dd> + <dt>{{domxref("SharedKeyframeList")}}</dt> + <dd>表示可在{{domxref("KeyframeEffect")}}对象之间共享的关键帧序列。 通过使用该对象,多个{{domxref("KeyframeEffect")}}对象可以重用相同的关键帧,而无需支付多次解析它们的成本。</dd> + <dt>{{domxref("AnimationEffectTimingProperties")}}</dt> + <dd>{{domxref("Element.animate()")}}, {{domxref("KeyframeEffectReadOnly.KeyframeEffectReadOnly()")}}和 {{domxref("KeyframeEffect.KeyframeEffect()")}}的定时属性对象。</dd> +</dl> + +<h2 id="扩展的其他接口">扩展的其他接口</h2> + +<p>The Web Animations API 向<strong style="font-size: 14px; font-weight: 700; line-height: 1.5;">{{domxref("document")}}</strong>和<strong style="font-size: 14px; font-weight: 700; line-height: 1.5;">{{domxref("element")}} </strong>添加了一些新的功能。</p> + +<h3 id="扩展到_Document_的接口">扩展到 <code>Document</code> 的接口</h3> + +<dl> + <dt>{{domxref("document.timeline")}}</dt> + <dd><code>DocumentTimeline</code> 表示默认文档时间轴</dd> + <dt>{{domxref("document.getAnimations()")}}</dt> + <dd>返回当前对文档中的元素有效的{{domxref("Animation")}}对象的数组。</dd> + <dt> + <h3 id="扩展到_Element_的接口">扩展到 <code>Element</code> 的接口</h3> + </dt> + <dt>{{domxref("Element.animate()")}}</dt> + <dd>用于在元素上创建和播放动画的快捷方式。 它返回创建的{{domxref("Animation")}}对象实例。</dd> +</dl> + +<dl> +</dl> + +<h2 id="Web动画只读接口">Web动画只读接口</h2> + +<p>规格中包括以下接口,用于定义在多个其他位置使用的功能。 你不会在Web开发工作中直接使用这些接口,但他们能帮助库或框架作者了解这些接口如何工作,使他们的库的实现可以更有效,或者浏览器工程师寻找一个比规范提供的内容更容易的参考。</p> + +<dl> + <dt>{{domxref("AnimationEffectTimingReadOnly")}}</dt> + <dd>A dictionary object of timing properties, which are inherited by the mutable {{domxref("AnimationEffectTiming")}} interface associated with {{domxref("KeyframeEffect")}}.</dd> + <dt>{{domxref("AnimationEffectReadOnly")}}</dt> + <dd>Defines current and future "Animation Effects" like {{domxref("KeyframeEffect")}}, which can be passed to {{domxref("Animation.Animation")}} objects for playing, and {{domxref("KeyframeEffectReadOnly")}} which is used by {{domxref("KeyframeEffect")}} (inherited by <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations">CSS Animations</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions">Transitions</a>).</dd> + <dt>{{domxref("KeyframeEffectReadOnly")}}</dt> + <dd>Describes sets of animatable properties and values that can be played using the {{domxref("Animation.Animation()")}} constructor, and which are inherited by {{domxref("KeyframeEffect")}}. </dd> +</dl> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('Web Animations')}}</td> + <td>{{Spec2('Web Animations')}}</td> + <td>Initial definition</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器支持">浏览器支持</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support (Element.animate())</td> + <td>{{ CompatChrome(36.0) }}<br> + </td> + <td>{{ CompatGeckoDesktop(48)}}</td> + <td>{{ CompatNo }}</td> + <td> + <p>29<br> + 28 behind pref</p> + </td> + <td>{{ CompatNo }}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Android Webview</th> + <th>Firefox Mobile (Gecko)</th> + <th>Firefox OS (Gecko)</th> + <th>IE Phone</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + <th>Chrome for Android</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatNo }}</td> + <td>{{CompatChrome(42.0)}}</td> + <td>{{ CompatGeckoMobile(48) }}</td> + <td>{{ CompatNo }}</td> + <td>{{ CompatNo }}</td> + <td>{{ CompatNo }}</td> + <td>{{ CompatNo }}</td> + <td>{{ CompatChrome(42.0) }}</td> + </tr> + </tbody> +</table> +[1] 仅在Firefox 52 Nightly和Dev版本中启用。在测试版/发布版中关闭。</div> + +<p> </p> + +<h2 id="相关内容">相关内容</h2> + +<p> </p> + +<ul> + <li><a href="/en-US/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API">Using the Web Animations API</a></li> + <li><a href="https://mozdevs.github.io/Animation-examples/">Web Animations demos</a></li> + <li><a href="https://github.com/web-animations/web-animations-js">Polyfill</a></li> + <li>Firefox's current implementation: <a href="https://birtles.github.io/areweanimatedyet/">AreWeAnimatedYet</a></li> + <li> + <p><a href="http://codepen.io/danwilson/pen/xGBKVq">Browser support test</a></p> + </li> +</ul> diff --git a/files/zh-cn/web/api/web_animations_api/keyframe_formats/index.html b/files/zh-cn/web/api/web_animations_api/keyframe_formats/index.html new file mode 100644 index 0000000000..d534d4a5c4 --- /dev/null +++ b/files/zh-cn/web/api/web_animations_api/keyframe_formats/index.html @@ -0,0 +1,196 @@ +--- +title: 关键帧(Keyframe)格式 +slug: Web/API/Web_Animations_API/Keyframe_Formats +tags: + - Animation + - annimate + - 关键帧 + - 关键帧格式 +translation_of: Web/API/Web_Animations_API/Keyframe_Formats +--- +<p>{{ SeeCompatTable() }}{{ APIRef("Web Animations API") }}</p> + +<p>{{domxref("Element.animate()")}}, {{domxref("KeyframeEffect.KeyframeEffect()")}}, 和 {{domxref("KeyframeEffect.setKeyframes()")}} 都接受格式为一组关键帧的对象, 这种格式有以下几种选项。</p> + +<h2 id="语法">语法</h2> + +<div id="keyframe-syntax"> +<p>关键帧格式有两种不同的方式:</p> + +<ol> + <li> + <p>一个由多个关键帧的属性和值组成的对象所构成的<code>数组</code>。这是{{domxref("KeyframeEffect.getKeyframes()", "getKeyframes()")}}方法返回的规范格式。</p> + + <pre class="brush: js"><em>element</em>.animate(<strong>[ + { // from + opacity: 0, + color: "#fff" + }, + { // to + opacity: 1, + color: "#000" + } +]</strong>, 2000);</pre> + + <p>对每个关键帧的偏移可以通过提供一个<code>offset</code>来指定。</p> + + <pre class="brush: js"><em>element</em>.animate(<strong>[ { opacity: 1 }, + { opacity: 0.1, offset: 0.7 }, + { opacity: 0 } ]</strong>, + 2000); +</pre> + + <div class="note"> + <p><strong>提示</strong>: <code>offset</code> 的值必须是在<strong>[0.0, 1.0]</strong>这个区间内,且须升序排列。</p> + </div> + + <p>并非所有的关键帧都需要设置<code>offset</code>。 没有指定<code>offset</code>的关键帧将与相邻的关键帧均匀间隔。</p> + + <p>可以通过提供<code>easing</code>过渡来给指定关键帧之间应用过渡效果,如下所示: </p> + + <pre class="brush: js"><em>element</em>.animate(<strong>[ { opacity: 1, easing: 'ease-out' }, + { opacity: 0.1, easing: 'ease-in' }, + { opacity: 0 } ]</strong>, + 2000); +</pre> + + <p>在这个例子中,指定的easing仅适用于指定它的关键帧到下一帧之间。 但是在<code>options</code>中指定的 <code>easing</code> 值都将应用在一个动画的整个持续时间里。</p> + </li> + <li>一个包含key-value键值的<code>对象</code>需要包含动画的属性和要循环变化的值<code>数组</code>。 + <pre class="brush: js"><em>element.</em>animate(<strong>{ + opacity: [ 0, 1 ], // [ from, to ] + color: [ "#fff", "#000" ] // [ from, to ] +}</strong>, 2000); +</pre> + + <p>使用这种格式,每个数组的元素数量不必相等。所提供的值将独立分开。</p> + + <pre class="brush: js"><em>element.</em>animate(<strong>{ + opacity: [ 0, 1 ], // offset: 0, 1 + backgroundColor: [ "red", "yellow", "green" ], // offset: 0, 0.5, 1 +}</strong>, 2000); +</pre> + + <p>特殊键<code>offset</code>,<code>easing</code>和<code>composite</code>(如下)可以与属性值一起指定。</p> + + <pre class="brush: js"><em>element.</em>animate(<strong>{ + opacity: [ 0, 0.9, 1 ], + offset: [ 0, 0.8 ], // [ 0, 0.8, 1 ] 的简写 + easing: [ 'ease-in', 'ease-out' ], +}</strong>, 2000); +</pre> + + <p>从属性值列表生成一组合适的关键帧后,每个提供的偏移量将应用于相应的关键帧。如果值不足或者列表包含空值<code>null</code>,则以没有指定处理(即和上面第1种数组格式的一样均匀间隔).</p> + + <p>如果<code>easing</code> 或<code>composite</code> 值太少,将根据需要,重复相应的列表。</p> + </li> +</ol> + +<h2 id="属性">属性</h2> + +<p>关键帧可以为任何的css动画属性指定 property-value 。 使用 camel-case 的属性名将变为 camelCase 格式,例如 {{cssxref("background-color")}} 变成 <code>backgroundColor</code> ,再如 {{cssxref("background-position-x")}} 变成 <code>backgroundPositionX</code>.。速记词,例如 {{cssxref("margin")}} 也是可以用的。.</p> + +<p>两个特色的css属性:</p> + +<ul> + <li>{{cssxref("float")}}, 必须写成 <code>cssFloat</code> ,因为"float" 是 JavaScript的保留关键字</li> + <li>{{cssxref("offset")}}, 必须写成 <code>cssOffset</code> ,因为"offset" 表示如下的关键帧 offset</li> +</ul> + +<p>还可以指定以下特色属性:</p> + +<dl> + <dt>offset</dt> + <dd> + <p>关键帧的 offset 偏移量指定为介于<code>0.0</code>和<code>1.0</code>之间的数字或为<code>null</code>。 这相当于使用<code>@keyframes</code>在CSS样式表中以百分比指定开始和结束状态。 如果此值为<code>null</code>或缺失,则关键帧将在相邻关键帧之间均匀分布。</p> + </dd> + <dt>easing</dt> + <dd> + <p>从这个关键帧直到这一级中的下一个关键帧所使用的 <a href="/en-US/docs/Web/CSS/timing-function">timing function</a></p> + </dd> + <dt>composite</dt> + <dd> + <p>{{domxref("KeyframeEffect.composite")}} 操作用于将此关键帧中指定的值与基础值组合在一起。 如果正在使用在效果上指定的复合操作,则不会出现这种情况。</p> + </dd> +</dl> +</div> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">备注</th> + </tr> + <tr> + <td>{{SpecName("Web Animations", "#processing-a-keyframes-argument", "Keyframe object formats")}}</td> + <td>{{Spec2('Web Animations')}}</td> + <td>Initial definition</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Android Webview</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{ CompatUnknown}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="相关推荐">相关推荐</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API">Web Animations API</a></li> + <li>{{domxref("Element.animate()")}}</li> + <li>{{domxref("KeyframeEffect.KeyframeEffect()")}}</li> + <li>{{domxref("KeyframeEffect.setKeyframes()")}}</li> +</ul> diff --git a/files/zh-cn/web/api/web_animations_api/using_the_web_animations_api/index.html b/files/zh-cn/web/api/web_animations_api/using_the_web_animations_api/index.html new file mode 100644 index 0000000000..8be4f10ccb --- /dev/null +++ b/files/zh-cn/web/api/web_animations_api/using_the_web_animations_api/index.html @@ -0,0 +1,349 @@ +--- +title: Using the Web Animations API +slug: Web/API/Web_Animations_API/Using_the_Web_Animations_API +translation_of: Web/API/Web_Animations_API/Using_the_Web_Animations_API +--- +<p>{{DefaultAPISidebar("Web Animations")}}</p> + +<p class="summary">web动画API可以让我们用JavaScript写动画并且控制动画。本文将通过有趣的demo和教学,以有趣的方式开启您对这片爱丽丝仙境的探索。</p> + +<h2 id="认识Web动画API">认识Web动画API</h2> + +<p><a href="/en-US/docs/Web/API/Web_Animations_API">Web动画API</a>将浏览器动画引擎向开发者打开,并由JavaScript进行操作。这些API被设计成 <a href="/en-US/docs/Web/CSS/CSS_Animations">CSS Animations</a> and <a href="/en-US/docs/Web/CSS/CSS_Transitions">CSS Transitions</a>的接口,未来会对这些API做补充以丰富更多的功能。它是对网络上动画化的支持最有效的方式之一,让浏览器进行自己的内部,不需要hacks,或者强迫,或者{{domxref("Window.requestAnimationFrame()")}}。</p> + +<p>通过Web动画API,我们可以将交互式动画从样式表移动到JavaScript,将表现与行为分开。 我们不再需要依赖DOM重的技术,如将CSS属性和范围类写入元素来控制播放方向。 与纯粹的声明式CSS不同,JavaScript还允许我们动态地将属性值设置为持续时间。 对于构建自定义动画库和创建交互式动画,Web动画API可能是完成工作的完美工具。 让我们看看它能做什么!</p> + +<h2 id="浏览器兼容情况">浏览器兼容情况</h2> + +<p>默认情况下,Firefox 48+和Chrome 36+中提供了本文中讨论的基本Web动画API功能。 Webkit和Edge已经将API移动到各自的待办事项列表中,但是直到我们看到所有浏览器都有完整的支持,所以有一个便于维护的polyfill( <a href="https://github.com/web-animations/web-animations-js">handy maintained polyfill</a>)可以测试功能支持,并在必要时添加它。</p> + +<h2 id="用web动画API写css动画">用web动画API写css动画</h2> + +<p>学习Web动画API的更为熟悉的方法之一是从大多数网络开发人员开始使用以前的CSS动画。 CSS动画有一个熟悉的语法,很好地分解为演示目的。</p> + +<h3 id="The_CSS_version">The CSS version</h3> + +<p>这是一个用CSS写的滚动动画,显示爱丽丝落下通向仙境的兔子洞(see the full <a href="http://codepen.io/rachelnabors/pen/QyOqqW">code on Codepen</a>):</p> + +<p><a href="http://codepen.io/rachelnabors/pen/rxpmJL"><img alt="Alice Tumbling down the rabbit's hole." src="https://mdn.mozillademos.org/files/13843/tumbling-alice_optimized.gif" style="display: block; height: 374px; margin-left: auto; margin-right: auto; width: 700px;"></a></p> + +<p>请注意背景的移动,爱丽丝的旋转,以及她的颜色偏移变化。 本教程我们将仅仅关注爱丽丝。 这是控制爱丽丝动画的简化的CSS:</p> + +<pre class="brush: css">#alice { + animation: aliceTumbling infinite 3s linear; +} + +@keyframes aliceTumbling { + 0% { + color: #000; + transform: rotate(0) translate3D(-50%, -50%, 0); + } + 30% { + color: #431236; + } + 100% { + color: #000; + transform: rotate(360deg) translate3D(-50%, -50%, 0); + } +}</pre> + +<p>这样可以以恒定的(线性linear)速率在3秒内改变爱丽丝的颜色和变换的旋转,并无限循环。 在 <a href="/en-US/docs/Web/CSS/@keyframes">@keyframes</a> 块中,我们可以看到每个循环(约0.9秒)的30%,Alice的颜色从黑色变为深红色,然后在循环结束时再次返回。</p> + +<h3 id="Moving_it_to_JavaScript">Moving it to JavaScript</h3> + +<p>现在让我们尝试使用Web动画API创建相同的动画。</p> + +<h4 id="Representing_keyframes">Representing keyframes</h4> + +<p>我们首先要做的是创建一个对应于我们的CSS @keyframes块的关键帧对象:</p> + +<pre class="brush: js">var aliceTumbling = [ + { transform: 'rotate(0) translate3D(-50%, -50%, 0)', color: '#000' }, + { color: '#431236', offset: 0.3}, + { transform: 'rotate(360deg) translate3D(-50%, -50%, 0)', color: '#000' } +];</pre> + +<p>这里我们使用一个包含多个对象的数组。 每个对象代表原始CSS中的一个键。 然而,与CSS不同,Web动画API不需要明确地告知每个键出现的动画的百分比。 它将根据您给出的按键数量自动将动画划分为相等的部分。 这意味着具有三个键的关键帧对象将通过动画的每个循环的方式播放中间键,除非另有说明。</p> + +<p>当我们想要明确地设置一个键与其他键的偏移量时,我们可以直接在对象中指定一个偏移量,并与逗号分隔。 在上面的例子中,为了确保爱丽丝的颜色变化为30%而不是50%,我们给它的偏移量为0.3。</p> + +<p>必须至少指定两个关键帧(表示动画序列的开始和结束状态).如果您的关键帧列表只有一个条目, {{domxref("Element.animate()")}} 将抛出不支持的异常报错.</p> + +<p>所以要回顾一下,除非你指定一个键上的偏移量,否则键的默认值是等间隔的。 方便吗?</p> + +<h4 id="表示时间属性">表示时间属性</h4> + +<p>我们还需要创建一个定时属性的对象 (an {{domxref("AnimationEffectTimingProperties")}} object) 对应于爱丽丝动画中的值:</p> + +<pre class="brush: js">var aliceTiming = { + duration: 3000, + iterations: Infinity +}</pre> + +<p>你会注意到这里有一些差异,如何在CSS中表示等价的值:</p> + +<ul> + <li>一个,持续时间是毫秒,而不是秒 - 3000不是3秒.。像{{domxref("WindowTimers.setTimeout()")}} 和{{domxref("Window.requestAnimationFrame()")}}, Web动画API只支持毫秒。</li> + <li>The other thing you’ll notice is that it’s <code>iterations</code>, not <code>iteration-count</code>.</li> +</ul> + +<div class="note"> +<p>CSS 动画中使用的属性值与Web动画中使用的属性值存在一些小的差异。比如,Web动画中不能使用字符串“infinite”,而是使用Javascript的关键字 Infinity。 以及我们用 <code>easing</code> 来代替<code>timing-function</code>。我们不必在这列出<code>easing</code>的值,因为不像在CSS动画里,默认的"<a href="/en-US/docs/Web/CSS/animation-timing-function">animation-timing-function</a>"是<code>ease</code>。页面动画API的默认easing是<code>linear</code>— 而这就是我们想要的。</p> +</div> + +<h4 id="整合这些特性">整合这些特性</h4> + +<p>是时候把这些特性结合到一起运用了 {{domxref("Element.animate()")}} :</p> + +<pre class="brush: js">document.getElementById("alice").animate( + aliceTumbling, + aliceTiming +)</pre> + +<p>And boom: the animation starts playing (see the finished <a href="http://codepen.io/rachelnabors/pen/rxpmJL">version on Codepen</a>).</p> + +<p>可以在可以使用CSS动画化的任何DOM元素上调用animate()方法。 它可以用几种方式写成。 我们可以直接像这样传递他们的值,而不是为关键帧和时间属性制作对象:</p> + +<pre class="brush: js">document.getElementById("alice").animate( + [ + { transform: 'rotate(0) translate3D(-50%, -50%, 0)', color: '#000' }, + { color: '#431236', offset: 0.3}, + { transform: 'rotate(360deg) translate3D(-50%, -50%, 0)', color: '#000' } + ], { + duration: 3000, + iterations: Infinity + } +);</pre> + +<p>更重要的是,如果我们只想指定动画的持续时间,而不是其迭代(默认动画迭代一次),我们可以单独传递毫秒:</p> + +<pre class="brush: js">document.getElementById("alice").animate( + [ + { transform: 'rotate(0) translate3D(-50%, -50%, 0)', color: '#000' }, + { color: '#431236', offset: 0.3}, + { transform: 'rotate(360deg) translate3D(-50%, -50%, 0)', color: '#000' } + ], 3000);</pre> + +<h2 id="使用play(),pause(),reverse()和playbackRate控制播放">使用play(),pause(),reverse()和playbackRate控制播放</h2> + +<p>虽然我们可以使用Web动画API编写CSS动画,其中API真正派上用场的是操纵动画的播放。 Web动画API提供了一些控制播放的有用方法。 让我们来看看在Growing / Shrinking Alice游戏中暂停和播放动画(请查看Codepen的完整代码 <a href="http://codepen.io/rachelnabors/pen/PNYGZQ">full code on Codepen</a>):</p> + +<p><a href="http://codepen.io/rachelnabors/pen/PNYGZQ?editors=0010"><img alt="Playing the growing and shrinking game with Alice." src="https://mdn.mozillademos.org/files/13845/growing-shrinking_article_optimized.gif" style="display: block; height: 374px; margin-left: auto; margin-right: auto; width: 700px;"></a></p> + +<p>在这个游戏中,爱丽丝有一个动画,使她从小到大,我们通过一个瓶子和一个蛋糕控制。 这两个都有自己的动画。</p> + +<h3 id="暂停和启动动画">暂停和启动动画</h3> + +<p>稍后我们会再讨论爱丽丝的动画,但现在我们来看看蛋糕的动画:</p> + +<pre class="brush: js">var nommingCake = document.getElementById('eat-me_sprite').animate( +[ + { transform: 'translateY(0)' }, + { transform: 'translateY(-80%)' } +], { + fill: 'forwards', + easing: 'steps(4, end)', + duration: aliceChange.effect.timing.duration / 2 +});</pre> + +<p>{{domxref("Element.animate()")}} 方法会在调用后立即执行。 为了防止蛋糕在用户有机会点击之前进食自己, 我们调用 {{domxref("Animation.pause()")}} ,如下:</p> + +<pre class="brush: js">nommingCake.pause();</pre> + +<p>我们可以运行 {{domxref("Animation.play()")}} 方法:</p> + +<pre class="brush: js">nommingCake.play();</pre> + +<p>特别地,我们想将其链接到爱丽丝的动画,所以当蛋糕被吃掉时,她变得更大。 我们可以通过以下功能来实现:</p> + +<pre class="brush: js">var growAlice = function() { + + // Play Alice's animation. + aliceChange.play(); + + // Play the cake's animation. + nommingCake.play(); + +}</pre> + +<p>当用户握住鼠标或者在触摸屏上按住他们的手指在蛋糕上时,我们现在可以调用growAlice来使所有动画发挥作用:</p> + +<pre class="brush: js">cake.addEventListener("mousedown", growAlice, false); +cake.addEventListener("touchstart", growAlice, false);</pre> + +<h3 id="其他有用的方法">其他有用的方法</h3> + +<p>除了暂停和播放,我们可以使用以下动画方法:</p> + +<ul> + <li>{{domxref("Animation.finish()")}} 动画结束.</li> + <li>{{domxref("Animation.cancel()")}} 终止动画.</li> + <li>{{domxref("Animation.reverse()")}} 设置动画播放速度</li> + <li> ({{domxref("Animation.playbackRate")}}到负值,所以它向后运行.</li> +</ul> + +<p>让我们先来看一下playbackRate - 一个否定的播放速度将导致一个动画反向运行。 当爱丽丝从瓶中喝酒时,她越来越小。 这是因为瓶子将动画的播放速度从1更改为-1:</p> + +<pre class="brush: js">var shrinkAlice = function() { + aliceChange.playbackRate = -1; + aliceChange.play(); +} + +bottle.addEventListener("mousedown", shrinkAlice, false); +bottle.addEventListener("touchstart", shrinkAlice, false);</pre> + +<p>在<a href="https://en.wikipedia.org/wiki/Through_the_Looking-Glass">Through the Looking-Glass</a>,爱丽丝旅行到一个世界,她必须跑步留在原地 - 运行两倍快速前进! 在红女王比赛的例子中,爱丽丝和红女王正在跑步,留下来(查看Codepen上的全部代码<a href="http://codepen.io/rachelnabors/pen/PNGGaV">full code on Codepen</a>):</p> + +<p><a href="http://codepen.io/rachelnabors/pen/PNGGaV"><img alt="Alice and the Red Queen race to get to the next square in this game." src="https://mdn.mozillademos.org/files/13847/red-queen-race_optimized.gif" style="display: block; height: 342px; margin-left: auto; margin-right: auto; width: 640px;"></a></p> + +<p>因为小孩子很容易疲惫不堪,不像自动机棋子,爱丽丝不断减速。 我们已经通过在动画播放时设置了一个衰减代码:</p> + +<pre class="brush: js">setInterval( function() { + + // Make sure the playback rate never falls below .4 + if (redQueen_alice.playbackRate > .4) { + redQueen_alice.playbackRate *= .9; + } + +}, 3000);</pre> + +<p>但是通过点击或点击来敦促他们使他们通过乘以播放速度来加快速度:</p> + +<pre class="brush: js">var goFaster = function() { + + redQueen_alice.playbackRate *= 1.1; + +} + +document.addEventListener("click", goFaster); +document.addEventListener("touchstart", goFaster);</pre> + +<p>背景元素还具有播放时间,当您点击或点击时,它们会受到影响。 当Alice和Red Queen跑两倍的时候会发生什么? 当你让他们放慢时会发生什么?</p> + +<h2 id="获取动画信息">获取动画信息</h2> + +<p>想象其他方式我们可以使用playbackRate,例如通过让他们减慢整个网站的动画来改善具有前庭障碍的用户的可访问性。 这不可能在CSS中重新计算每个CSS规则的持续时间,但是通过Web动画API,我们可以使用即将到来的(在浏览器中不支持!){{domxref("document.getAnimations()")}}方法 循环遍历页面上的每个动画,并将它们的播放速度减半:</p> + +<pre class="brush: js">document.getAnimations().forEach( + function (animation) { + animation.playbackRate *= .5; + } +);</pre> + +<p>使用Web动画API,您需要更改的只是一个小的属性!</p> + +<p>另一件与CSS动画有关的难点就是创建依赖于其他动画提供的值。 例如,在“成长和收缩爱丽丝”游戏的例子中,您可能会注意到蛋糕的持续时间有些奇怪:</p> + +<pre class="brush: js">duration: aliceChange.effect.timing.duration / 2</pre> + +<p>要了解这里发生了什么,让我们来看看Alice的动画:</p> + +<pre class="brush: js">var aliceChange = document.getElementById('alice').animate( + [ + { transform: 'translate(-50%, -50%) scale(.5)' }, + { transform: 'translate(-50%, -50%) scale(2)' } + ], { + duration: 8000, + easing: 'ease-in-out', + fill: 'both' + });</pre> + +<p>爱丽丝的动画让她的尺寸从一半到8秒的两倍。 然后我们暂停她:</p> + +<pre class="brush: js">aliceChange.pause();</pre> + +<p>如果我们在动画开始时已经把她暂停了,那么她的全部尺寸将从一半开始,就像她已经把整个瓶子都喝完了一样! 我们想把动画的“播放头”放在中间,所以她已经中途了。 我们可以通过将她的 {{domxref("Animation.currentTime")}}设置为4秒,如下所示:</p> + +<pre class="brush: js">aliceChange.currentTime = 4000;</pre> + +<p>但是在制作这个动画的时候,我们可能会改变爱丽丝的持续时间。 如果我们将动态时间设置为timeTime,那么它不会更好吗?所以我们一次不必再做两个更新? 我们实际上可以通过引用aliceChange的{{domxref("Animation.effect")}}属性来实现,该属性返回一个包含Alice上所有效果细节的对象:</p> + +<pre class="brush: js">aliceChange.currentTime = aliceChange.effect.timing.duration / 2;</pre> + +<p>效果让我们访问动画的关键帧和时间对象 - aliceChange.effect.timing指向Alice的时间对象(其类型为{{domxref("AnimationEffectTimingReadOnly")}}) - 这包含她的{{domxref("AnimationEffectTimingReadOnly.duration")}}。 我们可以将她的持续时间分成两半,以获得她动画时间轴的中点,使她成为正常的高度。 现在,我们可以在任何一个方向扭转和播放动画,使她变小或变大!</p> + +<p>当设置蛋糕和瓶子的持续时间时,我们可以做同样的事情:</p> + +<pre class="brush: js">var drinking = document.getElementById('liquid').animate( +[ + { height: '100%' }, + { height: '0' } +], { + fill: 'forwards', + duration: aliceChange.effect.timing.duration / 2 +}); +drinking.pause();</pre> + +<p>现在,所有三个动画只有一个持续时间,我们可以从一个地方容易地改变。</p> + +<p>我们还可以使用Web动画API来确定动画当前的时间。 当你用尽蛋糕吃或者清空瓶子时,游戏就结束了。 哪个角色扮演者取决于爱丽丝在她的动画中有多远,无论她是否变得太大,不能进入小门太小,无法达到打开门的钥匙。 我们可以弄清楚她是否在动画的大端或小端,让她的动画当前时间(<code><a href="/en-US/docs/Web/API/Animation/currentTime">currentTime</a></code>)被她的activeDuration分成:</p> + +<pre class="brush: js">var endGame = function() { + + // get Alice's timeline's playhead location + var alicePlayhead = aliceChange.currentTime; + var aliceTimeline = aliceChange.effect.activeDuration; + + // stops Alice's and other animations + stopPlayingAlice(); + + // depending on which third it falls into + var aliceHeight = alicePlayhead/aliceTimeline; + + if (aliceHeight <= .333){ + // Alice got smaller! + ... + + } else if (aliceHeight >= .666) { + // Alice got bigger! + ... + + } else { + // Alice didn't change significantly + ... + + } +} +</pre> + +<div class="note"> +<p><strong>Note:</strong> <code>getAnimations()</code> and <code>effect</code> are not fully supported as of this writing, but the polyfill does support them today.</p> +</div> + +<h2 id="Callbacks_and_promises">Callbacks and promises</h2> + +<p>CSS动画和转换有自己的事件侦听器,这些也可以通过Web动画API:</p> + +<ul> + <li><code><a href="/en-US/docs/Web/API/Animation/onfinish">onfinish</a></code> is the event handler for the <code>finish</code> event and can be triggered manually with <code><a href="/en-US/docs/Web/API/Animation/finish">finish()</a></code>.</li> + <li><code><a href="/en-US/docs/Web/API/Animation/oncancel">oncancel</a></code> is the event handler for the <code>cancel</code> event and can be triggers with <code><a href="/en-US/docs/Web/API/Animation/cancel">cancel()</a></code>.</li> +</ul> + +<p>在这里,我们为蛋糕,瓶子和爱丽丝设置回调来触发endGame功能:</p> + +<pre class="brush: js">// When the cake or runs out... +nommingCake.onfinish = endGame; +drinking.onfinish = endGame; + +// ...or Alice reaches the end of her animation +aliceChange.onfinish = endGame; + +</pre> + +<p>Prefer promises? The Web Animations API also specifies two promises: <code><a href="/en-US/docs/Web/API/Animation/onfinish">onfinish</a></code> and <code><a href="/en-US/docs/Web/API/Animation/oncancel">oncancel</a></code>.</p> + +<div class="note"> +<p>These promises are not fully supported as of this writing.</p> +</div> + +<h2 id="结论">结论</h2> + +<p>这些是Web动画API的基本功能,其中大部分功能已在最新版本的Firefox和Chrome中得到支持。 到目前为止,您应该准备好在浏览器中“跳下兔子洞”,动画制作动画实验! 如果您正在使用API并要共享,请尝试使用#WAAPI主题标签。 我们将会观看并且将编写更多的教程来涵盖更多的功能,支持传播!</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li class="post__title">The <a href="http://codepen.io/collection/bpEza/">full suite of Alice in Wonderland demos</a> on CodePen for you to play with, fork, and share</li> + <li class="post__title"><a href="https://hacks.mozilla.org/2016/08/animating-like-you-just-dont-care-with-element-animate/">Animating like you just don’t care with Element.animate</a> — a great article to read that explains more on the background of the Web Animations API, and why it is more performant than other web animation methods</li> + <li class="post__title"><a href="https://github.com/web-animations/web-animations-js">web-animations-js</a> — the Web Animations API polyfill</li> +</ul> |