马黑黑 发表于 2024-6-6 13:01

初识JS原生animate动画函数

本帖最后由 马黑黑 于 2024-6-6 13:03 编辑 <br /><br /><style>
.mum { position: relative; margin: 0; padding: 10px; font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; color: black; background: rgba(240, 240, 240,.95); border: thin solid silver; border-radius: 6px; }
.mum ::selection { background-color: rgba(0,100,100,.35); }
.mum div { margin: 0; padding: 0; }
.mum cl-cd { display: block; position: relative; margin: 0 0 0 50px; padding: 0 0 0 10px; white-space: pre-wrap; overflow-wrap: break-word; border-left: 1px solid silver; }
.mum cl-cd::before { position: absolute; content: attr(data-idx); width: 50px; color: gray; text-align: right; transform: translate(-70px); }
.tRed { color: red; }
.tBlue { color: blue; }
.tGreen { color: green; }
.tDarkRed { color: darkred; }
.tMagenta { color: magenta; }

#artDiv p { margin: 12px 0; font: normal 1.2em/1.5em sans-serif; }
#artDiv mark { padding: 0 6px; background: lightblue; }
</style>

<div id="artDiv">
        <p>很多人不认识 JS 有原生的动画函数,百度的AI也认为没有。其实不然,JS早就拥有 Web Animation API,提供两个接口,其中 animate 函数就是用来操控动画的。本文将通过制作一个可控的元素旋转对象初识 Web Animation API,具体做法是,使用 JS 原生 animate 函数驱动一个 img 元素,令其旋转并可控。</p>
        <p>我们需要准备一下图片:</p>
        <p><img alt="" src="https://638183.freep.cn/638183/web/svg/sunfl-2.svg" /></p>
        <p>这张图片在后面的示例中需要一个 id ,id="<span class="tRed">h7</span>",它是图片的标识,是我们后续操作这张图片的依据。animate 函数可以这样调用:<mark><span class="tRed">h7</span>.animate(<span class="tGreen">/* 参数 */</span>);</mark>。现在要做的事情是了解 animate 函数的参数——其实就是 animate 函数的语法:</p>
        <div class='mum'>
<cl-cd data-idx="1"><span class="tRed">element</span>.animate(<span class="tBlue">keyframes</span>, <span class="tBlue">options</span>);</cl-cd>
        </div>
        <p><span class="tRed">element</span> 是要执行 animate 动画的元素,一般使用 id 标识,比如本文的图片标签 id <span class="tRed">h7</span>,或通过 document.querySelector 等方法抓取到的元素标识。下面讨论重点问题,即两个参数:</p>
        <p><span class="tBlue">keyframes</span> 参数,顾名思义指关键帧动画,它是关键帧动画描述的对象集合,比如从 0 到 360deg 的旋转描述,用 JS 对象来表示:</p>
        <div class='mum'>
<cl-cd data-idx="1">{</cl-cd>
<cl-cd data-idx="2">    <span class="tBlue">transform:</span> <span class="tMagenta">'rotate(0)'</span>,      <span class="tGreen">/* 第一帧 */</span></cl-cd>
<cl-cd data-idx="3">    <span class="tBlue">transform:</span> <span class="tMagenta">'rotate(360deg)'</span>,   <span class="tGreen">/* 第二帧 */</span></cl-cd>
<cl-cd data-idx="4">}</cl-cd>
        </div>
        <p>CSS关键帧集合描述放在花括号 {} 内,这是JS对象的表示方法。这个内容块描述了动画的两个帧,起始帧旋转 0 度,结尾帧旋转 360 度,向 animate(参数1, 参数2) 函数传递参数1,告诉它给我运行一个动画,从 0 到 360deg 旋转元素。这个内容快就是 animate 函数所需的第一个参数,我们直接将其放置在 keyframes 参数的位置即可,当然,为了方便,我们还可以将动画描述集合储存为一个变量,后面的示例代码会呈现这一点。</p>
        <p><span class="tBlue">options</span> 参数是动画属性集合,包含但不限于动画运行周期、动画运行次数,也是使用 JS 对象存储:</p>
        <div class='mum'>
<cl-cd data-idx="1">{</cl-cd>
<cl-cd data-idx="2">    <span class="tBlue">duration:</span> 8000, <span class="tGreen">/* 动画持续时长,毫秒单位 */</span></cl-cd>
<cl-cd data-idx="3">    <span class="tBlue">iteration:</span> 2,   <span class="tGreen">/* 动画运行次数,正整数,Infinity 为无限 */</span></cl-cd>
<cl-cd data-idx="4">}</cl-cd>
        </div>
        <p>同样地,将以上代码块放置到 animate(参数1,参数2) 参数2的位置,告诉 animate 函数,动画的运行属性值是这两个:8 秒钟一个运行周期、运行两次。</p>
        <p>把这些代码整合一下,动画就可以运行了:</p>
        <div class='mum'>
<cl-cd data-idx="1">&lt;<span class="tDarkRed">img</span> <span class="tRed">id</span>=<span class="tMagenta">"h7"</span> alt=<span class="tMagenta">""</span> width=<span class="tMagenta">"200"</span> src=<span class="tMagenta">"https://638183.freep.cn/638183/web/svg/sunfl-2.svg"</span> /&gt;</cl-cd>
<cl-cd data-idx="2">&nbsp;</cl-cd>
<cl-cd data-idx="3">&lt;<span class="tDarkRed">script</span>&gt;</cl-cd>
<cl-cd data-idx="4">h7.animate(</cl-cd>
<cl-cd data-idx="5">    {</cl-cd>
<cl-cd data-idx="6">      <span class="tBlue">transform:</span> <span class="tMagenta">'rotate(0)'</span>,      <span class="tGreen">/* 第一帧 */</span></cl-cd>
<cl-cd data-idx="7">      <span class="tBlue">transform:</span> <span class="tMagenta">'rotate(360deg)'</span>,   <span class="tGreen">/* 第二帧 */</span></cl-cd>
<cl-cd data-idx="8">    },</cl-cd>
<cl-cd data-idx="9">    {</cl-cd>
<cl-cd data-idx="10">      <span class="tBlue">duration:</span> 8000, <span class="tGreen">/* 动画持续时长,毫秒单位 */</span></cl-cd>
<cl-cd data-idx="11">      <span class="tBlue">iteration:</span> 2,   <span class="tGreen">/* 动画运行次数,正整数,Infinity 为无限 */</span></cl-cd>
<cl-cd data-idx="12">    }</cl-cd>
<cl-cd data-idx="13">);</cl-cd>
<cl-cd data-idx="14">&lt;<span class="tDarkRed">/script</span>&gt;</cl-cd>
        </div>
        <p>图片旋转两圈后自动停下来,不过这个停止动作不是我们控制的,是 iteration: 2 属性的限定。要控制 animate 函数的动画,我们需要拿到动画操作标识,然后通过这个标识控制动画。animate 函数和CSS关键帧动画一样,拥有动画的播放与暂停方法,详情请参阅本文演示示例的代码:</p>
        <div class='mum'>
<cl-cd data-idx="1">&lt;<span class="tDarkRed">img</span> <span class="tRed">id</span>=<span class="tMagenta">"h7"</span> alt=<span class="tMagenta">""</span> width=<span class="tMagenta">"200"</span> src=<span class="tMagenta">"https://638183.freep.cn/638183/web/svg/sunfl-2.svg"</span> /&gt;</cl-cd>
<cl-cd data-idx="2">&nbsp;</cl-cd>
<cl-cd data-idx="3">&lt;<span class="tDarkRed">script</span>&gt;</cl-cd>
<cl-cd data-idx="4"><span class="tGreen">//rot对象 :旋转动画描述(省略首帧)</span></cl-cd>
<cl-cd data-idx="5"><span class="tBlue">const</span> rot = {</cl-cd>
<cl-cd data-idx="6">&nbsp; &nbsp; <span class="tBlue">transform:</span> <span class="tMagenta">'rotate(360deg)'</span>,</cl-cd>
<cl-cd data-idx="7">};</cl-cd>
<cl-cd data-idx="8">&nbsp;</cl-cd>
<cl-cd data-idx="9"><span class="tGreen">// rotAttr对象 :动画属性值列表</span></cl-cd>
<cl-cd data-idx="10"><span class="tBlue">const</span> rotAttr = {</cl-cd>
<cl-cd data-idx="11">&nbsp; &nbsp; <span class="tBlue">duration:</span> 8000,</cl-cd>
<cl-cd data-idx="12">&nbsp; &nbsp; <span class="tBlue">iterations:</span> Infinity,</cl-cd>
<cl-cd data-idx="13">};</cl-cd>
<cl-cd data-idx="14">&nbsp;</cl-cd>
<cl-cd data-idx="15"><span class="tGreen">// 运行并获得动画操作入口 rotate</span></cl-cd>
<cl-cd data-idx="16"><span class="tBlue">const</span> rotate = h7.animate(rot, rotAttr);</cl-cd>
<cl-cd data-idx="17">&nbsp;</cl-cd>
<cl-cd data-idx="18"><span class="tGreen">//图片单击事件</span></cl-cd>
<cl-cd data-idx="19">h7.onclick = () =&gt; {</cl-cd>
<cl-cd data-idx="20">&nbsp; &nbsp; rotate.playState === <span class="tMagenta">'running'</span> ? rotate.pause() : rotate.play();</cl-cd>
<cl-cd data-idx="21">};</cl-cd>
<cl-cd data-idx="22">&lt;<span class="tDarkRed">/script</span>&gt;</cl-cd>
        </div>
        <p>playState 是动画的运行状态,主要是 running 和 paused 两种;同时,animate 动画拥有 play() 和 pause() 两种方法。以上代码,我们就是根据 playerState 状态调用不同的方法来实现对 animate 动画的控制。效果如下:</p>
        <img id="h7" alt="" width="200" src="https://638183.freep.cn/638183/web/svg/sunfl-2.svg" />
        <p>(点击图片可以控制动画)</p>
        <p>小结:animate 是 JS 原生的动画函数,它源自 Web Animation API 接口,它需要两个参数,参数1是动画各帧的描述集合,用以描述动画的全程,参数2是动画属性值的描述集合,用以描述动画的运行周期(时长)、运行次数等,两个参数都是用 JS 对象表示,分别放置在在花括号内;animate 函数的动画与动画属性值的描述语法大致和CSS关键帧动画一样,但有自己的语法规范。animate 函数应由元素调用,<mark>元素标识.animate(参数1, 参数2);</mark>。而要控制动画,需要获得动画标识,<mark>动画标识 = 元素标识.animate();</mark>,然后可以使用 <mark>动画标识.play();</mark> 播放动画、使用 <mark>动画标识.pause();</mark> 暂停动画。动画的运行状态则通过 <mark>动画标识.playState</mark> 获得,状态一般是 running 或 paused(还有中间状态,这里不提)。</p>
</div>

<script>
const rot = {
        transform: 'rotate(0)',
        transform: 'rotate(360deg)',
};
const rotAttr = {
        duration: 8000,
        iterations: Infinity,
};
const rotate = h7.animate(rot, rotAttr);
h7.onclick = () => rotate.playState === 'running' ? rotate.pause() : rotate.play();
</script>

亚伦影音工作室 发表于 2024-6-6 15:33

这样的分析真清楚,对复杂的动画不知道是否可用!

南无月 发表于 2024-6-6 17:19

非常详细的教程哎。。
中午看了一次。。
小白看了全部代码再回去看分析,更清晰一些。。{:4_170:}

南无月 发表于 2024-6-6 17:20

{:4_199:}小白能看得懂一些的就是超级好的教程。

马黑黑 发表于 2024-6-6 17:40

南无月 发表于 2024-6-6 17:20
小白能看得懂一些的就是超级好的教程。

animate之前有过介绍或使用

马黑黑 发表于 2024-6-6 17:41

南无月 发表于 2024-6-6 17:19
非常详细的教程哎。。
中午看了一次。。
小白看了全部代码再回去看分析,更清晰一些。。

这个实现的功能相对简单,况且,和我们经常使用的CSS关键帧动画是紧密相连的,理解起来应该不会太难

马黑黑 发表于 2024-6-6 17:42

亚伦影音工作室 发表于 2024-6-6 15:33
这样的分析真清楚,对复杂的动画不知道是否可用!

比起控制纯CSS关键帧动画,这个自由度要高得多

南无月 发表于 2024-6-6 20:01

马黑黑 发表于 2024-6-6 17:41
这个实现的功能相对简单,况且,和我们经常使用的CSS关键帧动画是紧密相连的,理解起来应该不会太难

{:4_181:}就看着眼熟~~友好的JS

南无月 发表于 2024-6-6 20:02

马黑黑 发表于 2024-6-6 17:40
animate之前有过介绍或使用
{:4_181:}几乎贴贴都在用啊

马黑黑 发表于 2024-6-6 20:10

南无月 发表于 2024-6-6 20:02
几乎贴贴都在用啊
不是。你要弄清楚CSS关键帧动画和JS animate动画的区别:

CSS关键帧动画是自驱动,一个元素,如果有 animation 属性,如下面所示,

.mypic {
    /* 其他代码 */
    animation: rot 4s linear infinite;
}

那么,class="mypic" 的元素就会运行 rot 动画,rot 动画可能是酱紫:

@keyframes rot { transform: rotate(360deg); }

这些,都是CSS的,JS的 animate 函数不需要元素去设定。而是通过函数来设定动画,你可以理解为JS使用 animate 函数封装CSS动画。

马黑黑 发表于 2024-6-6 20:11

南无月 发表于 2024-6-6 20:01
就看着眼熟~~友好的JS

友好陌生

南无月 发表于 2024-6-6 20:31

马黑黑 发表于 2024-6-6 20:11
友好陌生

{:4_173:}友好的大怪兽。。

南无月 发表于 2024-6-6 20:35

马黑黑 发表于 2024-6-6 20:10
不是。你要弄清楚CSS关键帧动画和JS animate动画的区别:

CSS关键帧动画是自驱动,一个元素,如果有 a ...


我以为我在单词差不多的份上理解了个大概
原来有着根本的差别。{:4_170:}
亏得老师有耐心又说一遍

南无月 发表于 2024-6-6 20:36

{:4_191:}又想请老师喝酒了咋办

马黑黑 发表于 2024-6-6 20:38

南无月 发表于 2024-6-6 20:36
又想请老师喝酒了咋办

马黑黑 发表于 2024-6-6 20:47

本帖最后由 马黑黑 于 2024-6-6 20:49 编辑

南无月 发表于 2024-6-6 20:35
我以为我在单词差不多的份上理解了个大概
原来有着根本的差别。
亏得老师有耐心又说一遍
做音画帖,离不开三样东东:

CSS(<style>...</style>)
HTML (<div>...</div>)
JS (<script>...</script>)

CSS制定样式表,就是各个元素的样纸;
HTML是帖子构架;
JS是控制帖子相关东东的编程语言,它可以动态管理CSS和HTML。

如果把HTML比作人,那么,这是人最基本的结构,素面朝天的样纸;而CSS则是化妆师、甚至是整容师,人的穿着和打扮主要由CSS负责;至于JS,那忒厉害了,它可以通过修改CSS设定的样式给人重新打扮、化妆、整容等,还可以把人干掉或给他装个假肢什么的,并赋予人以智慧。

CSS也可以做一些JS的工作,极少量,比如动画、hover交互,将来CSS能干更多。

马黑黑 发表于 2024-6-6 20:49

南无月 发表于 2024-6-6 20:31
友好的大怪兽。。

是滴

南无月 发表于 2024-6-6 20:54

马黑黑 发表于 2024-6-6 20:47
做音画帖,离不开三样东东:

CSS(...)


这个可真是生动形象。。
CSS大概打扮打扮也能出场,长宽高位置啥的摆一摆
JS就是中枢神经,控制啥的都在这里。。{:4_173:}{:4_199:}

南无月 发表于 2024-6-6 20:55

马黑黑 发表于 2024-6-6 20:38


干脆的酒喝着痛快{:4_170:}

南无月 发表于 2024-6-6 20:56

马黑黑 发表于 2024-6-6 20:47
做音画帖,离不开三样东东:

CSS(...)


其实CSS也挺厉害的是吧。。很多动画它都能设定
页: [1] 2 3 4 5 6 7 8
查看完整版本: 初识JS原生animate动画函数