马黑黑 发表于 2023-12-5 09:10

svg之 animateMotion 路径动画(一)

本帖最后由 马黑黑 于 2023-12-5 10:31 编辑 <br /><br /><style>
.papa > p { margin: 10px 0; }
.hCode { display: block; padding: 10px 10px 10px 50px; font: normal 15px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; background: #F7EFE6; overflow-x: auto; tab-size: 4; position: relative; }
.hCode::before { position: absolute; content: attr(data-line); left: 0; top: 0; padding: 10px; font: inherit; color: #999; text-align: right; border-right: 1px solid tan; }
.rred { color: red; }
.zs { color: green; }
</style>

<div class=".papa">

<h2>svg之 animateMotion 路径动画(一)</h2>
<p>以下效果,小矩形绕着横躺的8字闭合路径秀步,比牙签腿的模特走T台更为优雅且极具魅力。如果打开页面后错过了一睹其芳容的机会,没关系,鼠标指针移到小矩形,它依然会屁颠屁颠地去跳八字步舞——可以永远驱使它这么做,它不知疲倦。<br><br></p>

<svg width="400" height="200" viewBox="0 0 200 100" style="border: 1px solid gray;">
        <rect x="-5" y="-5" width="10" height="10" fill="navy">
                <animateMotion
                        id="aniMotion"
                        path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z"
                        dur="8s"
                        repeatCount="1"
                        rotate="auto"
                        begin="0s;mouseover"
                        restart="whenNotActive"
                        fill="freeze"></animateMotion>
        </rect>
</svg>

<p>
        <label for="chkBox" class="rred">自动转身</label>
        <input id="chkBox" type="checkbox" value="auto" checked />
        <output id="rotMsg">rotate="auto"</output>
</p>

<p>之前讲过的 animate 和 animateTransform 动画,animate 动画通过持续改变元素的属性、animateTransform 通过驱使元素形变来达成元素的运动效果,它们各有自己的规矩,元素的运动不能随心所欲控制运动路线。现在,重量级的 animateMotion 动画出场了,它给运动对象即要运动的svg元素以运动的路径,运动元素(例如上例的小矩形)就会沿着该路径运动。</p>
<p>我们先来看看上述例子的代码结构:</p>

<pre class="hCode">
&lt;svg ...&gt;
        &lt;rect x="-5" y="-5" width="10" height="10" fill="navy"&gt;
                &lt;animateMotion ...&gt;&lt;/animateMotion&gt;
        &lt;/rect&gt;
&lt;/svg&gt;
</pre>

<p>上面的代码并不能运行,展现它只是为了帮助我们(加深)理解svg动画的代码结构。看得出来:animateMotion动画的代码包裹在矩形(rect)元素代码之内,是rect元素的子元素,然后它从里面驱动矩形,相当于是矩形运动的发动机。这与前面介绍的animate和animateTransform动画一样。理解了这个,我们可以看看上例的完整代码:</p>

<pre class="hCode">
&lt;svg width="400" height="200" viewBox="0 0 200 100" style="border: 1px solid gray;"&gt;
        &lt;rect x="-5" y="-5" width="10" height="10" fill="navy"&gt;
                &lt;animateMotion
                        <span class="rred">path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z"</span>
                        dur="8s" <span class="zs">/* 周期运动时长 */</span>
                        repeatCount="1" <span class="zs">/* 重复次数 */</span>
                        <span class="rred">rotate="auto"</span> <span class="zs">/* 是否转身 :auto=自动转身*/</span>
                        begin="0s;mouseover" <span class="zs">/* 触发动画 0s=马上,mouseover=鼠标滑过 */</span>
                        restart="whenNotActive" <span class="zs">/* 重启动画方式 :动画不运行时*/</span>
                        fill="freeze" <span class="zs">/* 动画结束时状态 :freeze=结束时的状态 */</span>
                &gt;&lt;/animateMotion&gt;
        &lt;/rect&gt;
&lt;/svg&gt;
</pre>

<p>第四行,即第一个红色代码行,<span class="rred">path</span> 属性提供运动路径,这是animateMotion动画的核心所在:必须得有一个路径。路径可以是任意的,只要合法、有效。路径可以是闭合的(末尾带Z或z),也可以是非闭合的。<span class="rred">rotate</span> 属性用于控制元素运动时“身体”的<span class="rred">转动</span>状态,设为 auto 表示自动转动,如此,运动对象会智能地感知运动路线当下的朝向,自动调整“身体”以保持自己的朝向与路径的朝向一致,这个本事是专业模特的基本功之一(上面的示例中,可以勾选底部的复选按钮切换是否自动转身)。其他属性和之前介绍的一样,可以看上述代码的注释逐一理解。</p>

</div>

<script>

let btns = document.querySelectorAll('.btnok'),
        stages = document.querySelectorAll('.stage'),
        hCodes = document.querySelectorAll('.hCode'),
        hLineNums = document.querySelectorAll('.hLineNum');

hCodes.forEach((item,key) => {
        let lines = hCodes.innerText.trim().split('\n').length;
        let str = '';
        for(let i = 0; i < lines; i ++) {
                str += i + 1 + '\n';
        }
        item.dataset.line = str;
});

chkBox.onclick = () => {
        chkBox.checked
                ? (aniMotion.setAttribute('rotate','auto'), rotMsg.innerText = 'auto="auto"')
                : (aniMotion.setAttribute('rotate','none'), rotMsg.innerText = 'auto="none"');
};

</script>

红影 发表于 2023-12-5 13:32

跟着学习一下,animate 动画通过持续改变元素的属性、animateTransform 通过驱使元素形变来达成元素的运动效果、animateMotion 动画酒事沿着路径运动吧。居然划分得这么细致{:4_187:}

红影 发表于 2023-12-5 14:10

赶紧又回去看了看前面讲的。
svg有不是动画的Transform变形。然后后面就是3种动画。3种动画挺容易混的,其实主要是实现动画的方式不同吧。
animate通过改变某个或多个属性,貌似也能走出线路呢。这个要指定属性名,并告诉怎么改变。
animateTransform跟属性没关系,可以让元素位移、倾斜、旋转、缩放等,要指定运动属性,还要给出values等设置。
animateMotion最主要的是要给出 path ,这个和第二种的位移有点像呢,设置的方式不同而已{:4_173:}

红影 发表于 2023-12-5 14:13

这个例子里的animateMotion动画,如果它的代码不是包裹在矩形(rect)元素代码之内,酒要用id名字去对应了吧?好像前面的就是这样的{:4_173:}

马黑黑 发表于 2023-12-5 19:16

红影 发表于 2023-12-5 13:32
跟着学习一下,animate 动画通过持续改变元素的属性、animateTransform 通过驱使元素形变来达成元素的运动 ...

这是svg动画的三大金刚,还有一个小金刚 set 第一讲讲过了

马黑黑 发表于 2023-12-5 19:17

红影 发表于 2023-12-5 14:13
这个例子里的animateMotion动画,如果它的代码不是包裹在矩形(rect)元素代码之内,酒要用id名字去对应了 ...

这个是,可以参考前面的内容。另外,animateMotion还有自己独特的特性,第二讲会讲到。

马黑黑 发表于 2023-12-5 19:18

红影 发表于 2023-12-5 14:10
赶紧又回去看了看前面讲的。
svg有不是动画的Transform变形。然后后面就是3种动画。3种动画挺容易混的,其 ...

完全不是同一层面上的运动特性

红影 发表于 2023-12-5 19:26

马黑黑 发表于 2023-12-5 19:16
这是svg动画的三大金刚,还有一个小金刚 set 第一讲讲过了

三大金刚啊,没有金刚钻,不揽瓷器活的意思呗{:4_173:}

红影 发表于 2023-12-5 19:26

马黑黑 发表于 2023-12-5 19:17
这个是,可以参考前面的内容。另外,animateMotion还有自己独特的特性,第二讲会讲到。

嗯嗯,等着看它的特性{:4_187:}

红影 发表于 2023-12-5 19:27

马黑黑 发表于 2023-12-5 19:18
完全不是同一层面上的运动特性

嗯嗯,语句也不相同。但是有些简单的动作好像都能实现。

马黑黑 发表于 2023-12-5 20:33

红影 发表于 2023-12-5 19:27
嗯嗯,语句也不相同。但是有些简单的动作好像都能实现。

你理解的有问题呢。
动画形态,在svg里主要由三个动画标签实现,它们各自有各自的特性。动只是一个大范围的东东,怎么动,才是这三个动画标签所规范的。

马黑黑 发表于 2023-12-5 20:34

红影 发表于 2023-12-5 19:26
嗯嗯,等着看它的特性

它的特性就是路径

马黑黑 发表于 2023-12-5 20:34

红影 发表于 2023-12-5 19:26
三大金刚啊,没有金刚钻,不揽瓷器活的意思呗

{:4_203:}

红影 发表于 2023-12-5 21:27

马黑黑 发表于 2023-12-5 20:33
你理解的有问题呢。
动画形态,在svg里主要由三个动画标签实现,它们各自有各自的特性。动只是一个大范 ...

我是说从外观效果上,它们能弄出同样的效果,虽然三个标签的操作不同{:4_173:}

红影 发表于 2023-12-5 21:28

马黑黑 发表于 2023-12-5 20:34
它的特性就是路径

路径还有特性啊{:4_203:}

红影 发表于 2023-12-5 21:28

马黑黑 发表于 2023-12-5 20:34


不会这三大金刚,就没法让svg动起来啊{:4_173:}

马黑黑 发表于 2023-12-6 18:27

红影 发表于 2023-12-5 21:28
不会这三大金刚,就没法让svg动起来啊

可以的:把svg作为运动对象,用CSS或JS驱动。JS也可以在svg内部驱动svg元素运动。

马黑黑 发表于 2023-12-6 18:28

红影 发表于 2023-12-5 21:28
路径还有特性啊

animateMotion就是路径动画,其核心特征就是路径path属性

马黑黑 发表于 2023-12-6 18:28

红影 发表于 2023-12-5 21:27
我是说从外观效果上,它们能弄出同样的效果,虽然三个标签的操作不同

但这不是一回事,如果是一回事,就没必要设计它们,有一个就行了

红影 发表于 2023-12-6 21:11

马黑黑 发表于 2023-12-6 18:27
可以的:把svg作为运动对象,用CSS或JS驱动。JS也可以在svg内部驱动svg元素运动。

还是直接驱动它最直接呢{:4_173:}
页: [1] 2 3 4
查看完整版本: svg之 animateMotion 路径动画(一)