svg动画之:animateMotion
本帖最后由 马黑黑 于 2022-9-10 11:09 编辑 <br /><br /><p>我们在 <a href="https://www.huachaowang.com/forum.php?mod=viewthread&tid=62964&extra=page%3D1">时间</a> 一帖里提到过,svg 可以直接驱动文本沿着既定路径移动。试看如下效果,蓝色边框的区域是 svg 画布,文字沿着直线路径来回移动。代码和效果如下:</p><p><br></p><p><font color="#8b0000"><svg width="600" height="200" style="border: 1px solid blue; margin: auto; display: block; position: relative;"></font></p><p><font color="#8b0000"> <text x="0" y="5" style="font: bold 2em sans-serif; stroke: red; fill: none;">月是故乡明</font></p><p><font color="#8b0000"> <animateMotion </font><font color="#0000ff">path="M 10 100 H 440 z"</font><font color="#8b0000"> </font><font color="#ff0000">dur</font><font color="#8b0000">="8s" </font><font color="#ff0000">repeatCount</font><font color="#8b0000">="indefinite"></animateMotion></font></p><p><font color="#8b0000"> </text></font></p><p><font color="#8b0000"></svg></font></p><svg width="600" height="200" style="border: 1px solid blue; margin: auto; display: block; position: relative;">
<text x="0" y="5" style="font: bold 2em sans-serif; stroke: red; fill: none;">月是故乡明
<animateMotion path="M 10 100 H 440 z" dur="8s" repeatCount="indefinite"></animateMotion>
</text>
</svg>
<p><br>animateMotion 可以直接写路径,代码中的蓝色部分就是,上例用 path 写出了一个从 10 开始 到 440结束的水平路径,路径中的 z 表示闭合路径,这是文本来回移动的依据(运动总是照着路径的,路径闭合意味着头尾相连,直线路径不会头尾相连,就往复循环)。</p><p><br></p><p>animateMotion 还有几个重要参数,这里仅就上例做解释:dur 必须,运动周期时长;repeatCount,重复次数,可用正整数,也可以用例中的数值(无限数值),不设置此参数时运动一次就停下来。</p><p><br></p><p><font color="#ff0000">animateMotion 必须被包裹在调用运动的标签内</font>。上面的例子中,它放在 <text> 和 </text> 之内。可能有朋友会问:那么,像圆、矩形、线条之类的svg元素,它们就不能使用 animateMotion 运动了?因为它们是自闭合标签!答案会令大家满意:能用,自闭合标签在使用 animateMotion 运动时,写成有起始符、收尾符的标签即可!请看例子,一个矩形代替上面的文本运动:</p><p><br></p><p><font color="#8b0000"><svg width="600" height="200" style="border: 1px solid blue; margin: auto; display: block; position: relative;"></font></p><p><font color="#8b0000"> </font><font color="#ff00ff"><rect</font> <font color="#8b0000">x="0" y="0" width="50" height="30" fill="olive"></font></p><p><font color="#8b0000"> <animateMotion </font><font color="#0000ff">path="M 10 100 H 540 z"</font><font color="#8b0000"> </font><font color="#ff0000">dur</font><font color="#8b0000">="8s" </font><font color="#ff0000">repeatCount</font><font color="#8b0000">="indefinite"></animateMotion></font></p><p><font color="#8b0000"> </font><font color="#ff00ff"></rect></font></p><p><font color="#8b0000"></svg></font></p><p><font color="#8b0000"><br></font></p><p>通常,rect 标签都是写成 <font color="#8b0000"><rect x="10" y="10" .... </font> <font color="#ff0000">/></font> 这样的自闭合方式,为了调用 animateMotion 就必须包裹它,所以也能有终止标签符号 </rect>!</p><p><br></p> 本帖最后由 马黑黑 于 2022-9-10 13:10 编辑 <br /><br /><p>将 animateMotion 所使用的路径写在自己代码内不是官方建议的方法,但在路径极简且无需反复调用路径时,可以考虑。官方建议 animateMotion 使用路径的方法是先设计路径,再使用 mpath 标签指定所使用的路径。以l类似一楼的直线路径为例,我们来看看如何实现:</p><p><br></p><p><svg width="600" height="200" viewBox="0 0 600 200" style="border: 1px solid"></p><p><span style="white-space:pre"> </span><path id="<font color="#ff0000">path1</font>" d="M 50 100 H 530 z" stroke="red" /></p><p><span style="white-space:pre"> </span><rect x="10" <font color="#008000">y="-20"</font> width="50" height="40" fill="olive"></p><p><span style="white-space:pre"> </span><animateMotion dur="8s" r<font color="#0000ff">epeatCount="5"</font>></p><p><span style="white-space:pre"> </span><mpath xlink:href="<font color="#ff0000">#path1</font>" /></p><p><span style="white-space:pre"> </span></animateMotion></p><p><span style="white-space:pre"> </span></rect></p><p></svg></p><p><br></p><p><br></p>
<svg width="600" height="200" viewBox="0 0 600 200" style="border: 1px solid">
<path id="path1" d="M 50 100 H 530 z" stroke="red"></path>
<rect x="10" y="-20" width="50" height="40" fill="olive">
<animateMotion dur="8s" repeatCount="5">
<mpath xlink:href="#path1"></mpath>
</animateMotion>
</rect>
</svg>
<p><br>mpath 以 animateMotion 的子标签出现,只负责为 animateMotion 指定前面设计的 path 路径。</p><p><br></p><p>在上面的例子里,矩形的 y 值为什么设定为 -20 即矩形的高度的一半?根据 rect 的(xy)坐标,当它处于静止状态时,它的位置又在哪里?又,当矩形根据 animateMotion 的设定投入运动中,它为什么在路径x线Y轴的正中央?为了展示这一点,这里将 animateMotion 的 repeatCount 设置为 5,运行 5 次后动画会停下来,然后可以理解:矩形的 xy坐标 的设置,当基于路径运动时应参照路径的某些情形(如初始path坐标或xy坐标中全部或某一个轴)进行设定,当矩形是静止展现时,则应以 svg 的左上角(0,0)做基点设定矩形的位置。</p><p><br></p><p>迄今为止,我们还没有令运动对象以曲线作为运动路径。这里,设计一条三次贝塞尔曲线,先看效果:</p><p><br></p>
<svg width="600" height="200" viewBox="0 0 600 200" style="border: 1px solid">
<path id="path2" d="M 0 0 C 260 300, 400 20, 600 200" fill="none" stroke="red"></path>
<rect x="0" y="-20" width="50" height="40" fill="olive">
<animateMotion dur="3s" rotate="auto" repeatCount="indefinite">
<mpath xlink:href="#path2"></mpath>
</animateMotion>
</rect>
</svg>
<p><br>代码:</p><p><br></p><p><svg width="600" height="200" viewBox="0 0 600 200" style="border: 1px solid"></p><p><span style="white-space:pre"> </span><path id="<font color="#ff0000">path2</font>" <font color="#0000ff">d="M 0 0 C 260 300, 400 20, 600 200"</font> fill="none" stroke="red" /></p><p><span style="white-space:pre"> </span><rect x="0" y="-20" width="50" height="40" fill="olive"></p><p><span style="white-space:pre"> </span><animateMotion dur="3s" <font color="#ff00ff">rotate="auto"</font> repeatCount="indefinite"></p><p><span style="white-space:pre"> </span><mpath xlink:href="<font color="#ff0000">#path2</font>" /></p><p><span style="white-space:pre"> </span></animateMotion></p><p><span style="white-space:pre"> </span></rect></p><p></svg></p><p><br></p><p>蓝色代码,<span style="color: rgb(0, 0, 255);">d="M 0 0 C 260 300, 400 20, 600 200"</span>,M 0 0 ,画笔起笔处也是曲线开始点的坐标,C 是三次贝塞尔曲线指令(CurveTo的缩写),所带的三组参数,最后一组是曲线的终点坐标,第一、第二组是两个控制点坐标。这个路径没有用小写字母 z 闭合,因为这条曲线闭合了构不成合理的运行轨道。</p><p><br></p><p>animateMotion 代码中还有一个重要的设置,<span style="color: rgb(255, 0, 255);">rotate="auto"</span>,这是叫矩形能够根据路径自动调整“车身”的意思,没有这句,矩形行进的效果没那么好。</p> 这个怎么好像要等上一会才会开始运动? 红影 发表于 2022-9-10 11:24
这个怎么好像要等上一会才会开始运动?
立即动的。不知你的浏览器是什么 今天这个播放器教程的歌词就这样做的吧,黑黑精彩不断{:4_178:} 小辣椒 发表于 2022-9-10 12:59
今天这个播放器教程的歌词就这样做的吧,黑黑精彩不断
那个播放器没有用上这里的 动画,它是基于纯粹的CSS动画的,那个帖子里说的清楚 欣赏老师的精彩动画代码,多谢分享。祝您双节幸福快乐!{:4_204:} 梦缘 发表于 2022-9-10 15:23
欣赏老师的精彩动画代码,多谢分享。祝您双节幸福快乐!
喝水{:4_191:} 马黑黑 发表于 2022-9-10 11:07
本帖最后由 马黑黑 于 2022-9-10 13:10 编辑 将 animateMotion 所使用的路径写在自己代码内不是官方建议的 ...
这个曲线运动的好美,像是滑滑梯{:4_187:} 红影 发表于 2022-9-10 18:27
这个曲线运动的好美,像是滑滑梯
曲线运动实际上是现实中最常见的运动。曲线同时也是很美的。 马黑黑 发表于 2022-9-10 19:04
曲线运动实际上是现实中最常见的运动。曲线同时也是很美的。
这个以后倒是可以派派用途呢,真的很好看。 中秋大家快乐! 上海朝阳 发表于 2022-9-10 21:16
中秋大家快乐!
同乐同乐 红影 发表于 2022-9-10 20:57
这个以后倒是可以派派用途呢,真的很好看。
嗯,你设计一个二次、三次贝塞尔曲线不是个问题。记得你设计的蜜蜂运动节点,看得出你在路径设计方面是好手。 马黑黑 发表于 2022-9-10 21:19
嗯,你设计一个二次、三次贝塞尔曲线不是个问题。记得你设计的蜜蜂运动节点,看得出你在路径设计方面是好 ...
那个没什么啊,只不过是取点位值而已,而且不用太精确,差不多就行了{:4_173:} 红影 发表于 2022-9-10 23:20
那个没什么啊,只不过是取点位值而已,而且不用太精确,差不多就行了
路径就是设置各个点的位置,当然,需要精准 马黑黑 发表于 2022-9-11 07:38
路径就是设置各个点的位置,当然,需要精准
嗯,很多地方取点必须准确,看上去才不怪异。但蜜蜂那个不用太准确{:4_173:} 红影 发表于 2022-9-11 10:21
嗯,很多地方取点必须准确,看上去才不怪异。但蜜蜂那个不用太准确
嗯,这个知道 马黑黑 发表于 2022-9-11 10:21
嗯,这个知道
当图图中有其他参照,则,则取点必须准确。因为参照之下的差异会很明显。 红影 发表于 2022-9-11 10:53
当图图中有其他参照,则,则取点必须准确。因为参照之下的差异会很明显。
如果可以,尽可能精准取点。
页:
[1]
2