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">
<svg ...>
<rect x="-5" y="-5" width="10" height="10" fill="navy">
<animateMotion ...></animateMotion>
</rect>
</svg>
</pre>
<p>上面的代码并不能运行,展现它只是为了帮助我们(加深)理解svg动画的代码结构。看得出来:animateMotion动画的代码包裹在矩形(rect)元素代码之内,是rect元素的子元素,然后它从里面驱动矩形,相当于是矩形运动的发动机。这与前面介绍的animate和animateTransform动画一样。理解了这个,我们可以看看上例的完整代码:</p>
<pre class="hCode">
<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
<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>
></animateMotion>
</rect>
</svg>
</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> 跟着学习一下,animate 动画通过持续改变元素的属性、animateTransform 通过驱使元素形变来达成元素的运动效果、animateMotion 动画酒事沿着路径运动吧。居然划分得这么细致{:4_187:} 赶紧又回去看了看前面讲的。
svg有不是动画的Transform变形。然后后面就是3种动画。3种动画挺容易混的,其实主要是实现动画的方式不同吧。
animate通过改变某个或多个属性,貌似也能走出线路呢。这个要指定属性名,并告诉怎么改变。
animateTransform跟属性没关系,可以让元素位移、倾斜、旋转、缩放等,要指定运动属性,还要给出values等设置。
animateMotion最主要的是要给出 path ,这个和第二种的位移有点像呢,设置的方式不同而已{:4_173:} 这个例子里的animateMotion动画,如果它的代码不是包裹在矩形(rect)元素代码之内,酒要用id名字去对应了吧?好像前面的就是这样的{:4_173:} 红影 发表于 2023-12-5 13:32
跟着学习一下,animate 动画通过持续改变元素的属性、animateTransform 通过驱使元素形变来达成元素的运动 ...
这是svg动画的三大金刚,还有一个小金刚 set 第一讲讲过了 红影 发表于 2023-12-5 14:13
这个例子里的animateMotion动画,如果它的代码不是包裹在矩形(rect)元素代码之内,酒要用id名字去对应了 ...
这个是,可以参考前面的内容。另外,animateMotion还有自己独特的特性,第二讲会讲到。 红影 发表于 2023-12-5 14:10
赶紧又回去看了看前面讲的。
svg有不是动画的Transform变形。然后后面就是3种动画。3种动画挺容易混的,其 ...
完全不是同一层面上的运动特性 马黑黑 发表于 2023-12-5 19:16
这是svg动画的三大金刚,还有一个小金刚 set 第一讲讲过了
三大金刚啊,没有金刚钻,不揽瓷器活的意思呗{:4_173:} 马黑黑 发表于 2023-12-5 19:17
这个是,可以参考前面的内容。另外,animateMotion还有自己独特的特性,第二讲会讲到。
嗯嗯,等着看它的特性{:4_187:} 马黑黑 发表于 2023-12-5 19:18
完全不是同一层面上的运动特性
嗯嗯,语句也不相同。但是有些简单的动作好像都能实现。 红影 发表于 2023-12-5 19:27
嗯嗯,语句也不相同。但是有些简单的动作好像都能实现。
你理解的有问题呢。
动画形态,在svg里主要由三个动画标签实现,它们各自有各自的特性。动只是一个大范围的东东,怎么动,才是这三个动画标签所规范的。 红影 发表于 2023-12-5 19:26
嗯嗯,等着看它的特性
它的特性就是路径 红影 发表于 2023-12-5 19:26
三大金刚啊,没有金刚钻,不揽瓷器活的意思呗
{:4_203:} 马黑黑 发表于 2023-12-5 20:33
你理解的有问题呢。
动画形态,在svg里主要由三个动画标签实现,它们各自有各自的特性。动只是一个大范 ...
我是说从外观效果上,它们能弄出同样的效果,虽然三个标签的操作不同{:4_173:} 马黑黑 发表于 2023-12-5 20:34
它的特性就是路径
路径还有特性啊{:4_203:} 马黑黑 发表于 2023-12-5 20:34
不会这三大金刚,就没法让svg动起来啊{:4_173:} 红影 发表于 2023-12-5 21:28
不会这三大金刚,就没法让svg动起来啊
可以的:把svg作为运动对象,用CSS或JS驱动。JS也可以在svg内部驱动svg元素运动。 红影 发表于 2023-12-5 21:28
路径还有特性啊
animateMotion就是路径动画,其核心特征就是路径path属性 红影 发表于 2023-12-5 21:27
我是说从外观效果上,它们能弄出同样的效果,虽然三个标签的操作不同
但这不是一回事,如果是一回事,就没必要设计它们,有一个就行了 马黑黑 发表于 2023-12-6 18:27
可以的:把svg作为运动对象,用CSS或JS驱动。JS也可以在svg内部驱动svg元素运动。
还是直接驱动它最直接呢{:4_173:}