[泛红的蓝海]chrome弃用了SVG?
[泛红的蓝海]chrome弃用了SVG?
In 网页重构 on 2016-10-18 20:22:47 by 沙因
这个系列其实是很早之前写的,然后去年忽然发现chrome的warning……
首先看下这个
SVG's SMIL animations (<animate>, <set>, etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead.
翻译过来就是,chrome弃用了SMIL了。
https://developer.mozilla.org/zh-CN/docs/Web/SVG/SVG_animation_with_SMIL
当然,一般人第一眼看到这个的反应就是
啊啊啊,谷歌爸爸把SMIL删啦!!!SVG已经被淘汰啦啦啦!!!
然后就是,SMIL是什么鬼?
SMIL简单来说就是SVG中的部分动画表现形式,但SVG动画不仅仅只有SMIL。
鉴于很多同学还是不清楚SMIL是什么,所以这篇就来讲讲
CSS与JS的交互动画
……
好,在这之前先要明白SVG动画与SMIL的关系。
SMIL一般是指SVG内部元素的动画。
元素动画
比如这样:
这样:
这样:
还有这样:
想了解更多SMIL相关的信息可以看下这篇文章SVG动画史诗级指南(SMIL)
上面这些都属于SMIL,动画原理是通过SVG内的
然而我们常用的SVG动画还有不同的表现形式。
比如最经常用到的,线条动画。
这些动画原理是通过改变SVG内部元素的属性来实现动画效果。
属性动画
比如这样:
这样:
还有这样:
EXCUSE ME?
这特么不是普通的web动画吗?
盲生,你发现了华点!
上面都是改变SVG内部元素属性生成的动画。
比如用svg元素画个图,然后用js控制matrix
这到底算不算svg动画呢?
非要归类的话,这属于SVG的属性动画,而SVG的属性可以受JS与CSS控制。
实际上在SVG里,元素动画和属性动画可以实现一样的效果。
元素动画代码
<svg width="500" height="100"> <circle id="orange-circle" r="30" cx="50" cy="50" fill="orange" /> <animate xlink:href="#orange-circle" attributeName="cx" from="50" to="450" dur="1s" begin="click" fill="freeze" />svg>
属性动画代码
#orange-circle { animation:move 1s 1 forward;}@keyframes move{ from{transform:translateX(50px);} to{transform:translateX(450px);}}
动画效果表现上是相同的
如果想了解具体区别可以再看一遍这篇SVG动画史诗级指南(SMIL)
了解属性动画与元素动画后就容易解释了。
为什么SVG属性动画也被叫做SVG动画呢?
因为SVG有正常元素所没有的属性。
首先,SVG是个独立的文档流。
可缩放矢量图形(Scalable Vector Graphics,SVG),是一种用来描述二维矢量图形的XML 标记语言。 简单地说,SVG面向图形,XHTML面向文本。 SVG与Flash类似,都是用于二维矢量图形,二者的区别在于,SVG是一个W3C标准,基于XML,是开放的,而Flash是封闭的基于二进制格式的。因为都是W3C标准,SVG与其他的W3C标准,比如CSS, DOM和SMIL等能够协同工作。
https://developer.mozilla.org/zh-CN/docs/Web/SVG
而SVG本身有大量的元素,每种元素又有各自独特的属性。
正是这些独特的元素属性,在js与css的配合下,才能产生只有SVG才能表现的动画。
两个属性来实现
而变形动画则通过改变
不过变形动画如果使用js控制的话,那意味着里面的数值需要人工计算,这不太现实,关于变形动画的制作,我们后面会讲,现在还是要先弄清楚svg动画里的元素与属性。
既然所有动画都能属于属性动画,那么元素动画到底是什么?
元素动画是一种内置的动画数值处理方式。类似于CSS里的animation和keyframes
元素动画代码
<path fill="#910c0c" d="M179.461,19.838c7.902,35.956-3.314,34.171-8.669,55.591c-9.354,37.421,6.864,27.636-7.157,61.552c6.528-36.891-8.632-42.683-0.061-67.53C170.623,49.018,182.52,52.48,179.461,19.838L179.461,19.838z"> <animate attributeName="d" begin="0s" dur="2s" repeatCount="indefinite" values=" M179.461,19.838c7.902,35.956-3.314,34.171-8.669,55.591c-9.354,37.421,6.864,27.636-7.157,61.552c6.528-36.891-8.632-42.683-0.061-67.53C170.623,49.018,182.52,52.48,179.461,19.838L179.461,19.838z; M173.46,20.215c7.904,35.956-3.314,34.171-8.669,55.591c-5.353,21.42,5.864,19.635-8.158,53.553c1.529-19.893-9.63-26.683-3.059-52.533C158.9,55.879,176.519,52.857,173.46,20.215L173.46,20.215z; M179.461,19.838c7.902,35.956-3.314,34.171-8.669,55.591c-9.354,37.421,6.864,27.636-7.157,61.552c6.528-36.891-8.632-42.683-0.061-67.53C170.623,49.018,182.52,52.48,179.461,19.838L179.461,19.838z ">animate> path>
这段代码等价于,用js将
现在回过头看看文章一开始的
相信大家已经明白,chrome弃用的什么了。并不是弃用所有的SVG动画,而是弃用了SVG内的部分元素动画,或者说弃用的是部分动画元素。
因此SVG依然是可用的(虽然chrome从45版本就弃用SMIL,但是就算到了50依然只是console里warning一下,功能什么的都正常,口嫌体正直~)。
前面介绍了SVG与chrome的爱恨情仇,然后有同学表示一脸懵逼,“禁用就禁用了,反正我们也不懂的如何使用SMIL”。
很好,那么我们现在就来学习如何用SMIL制作SVG最特殊也是最有代表性的动画形式:变形动画。
“都弃用了还学个P”
想要制作SVG变形动画,首先要先了解SVG如何绘制这些图形。
我们得到的SVG里的
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#EE3224;" d=" M293.524,444.527 c24,75.274-9.083,143.344-76.473,200.571 c63-83-43.261-36.084-12.527-145.571 c1.241,51,54.062,25.51,59.616-1.082 c7.537-36.082,3-115-117-162 C233.14,365.445,277.524,404.959,293.524,444.527z ">
path内绘制命令
M = moveto 移动到L = lineto 绘制直线H = horizontal lineto 水平线条V = vertical lineto 垂直线条C = curveto 绘制曲线S = smooth curveto 平滑曲线Q = quadratic Belzier curve 二次方贝塞尔曲线T = smooth quadratic Belzier curveto 平滑二次方贝塞尔曲线A = elliptical Arc 椭圆弧线Z = closepath 闭合路径
M与Z可以分别理解为起点与终点,
L H V则是描绘直线,水平线以及垂直线
重点在于C 曲线命令
C 命令后面需要6个参数:
c x1,y1 x2,y2 x,y
其中x1,y1,x2,y2分别是手柄起点与终点位置,x,y是锚点位置
d="M214.14,175.445c0,0-6,371,152,297"
S 平滑曲线:
s x1,y1 x,y
平滑曲线的手柄是对称的,所以只需要一个手柄参数
d="M257.14,171.445c-51,18-103,124-59,209s189,71,217,40.5"
剩下Q T 分别为更为特殊的曲线,A为弧线。本文依然以实际应用场景为主,所以为了避免多余的信息造成理解困难就省去了,想进一步了解的同学可以查看SVG路径。
了解path的路径命令后,接下来的部分就简单了。
我们先把SVG保存出来
然后我们稍微调整一下锚点位置
保存得到的path
让我们比较一下两者前后d属性的区别
不同的图形,可是不一样的只是一些数字,所以SVG是如何进行变形动画,答案已经呼之欲出了。
AI导出SVG时,不是每个参数数字都会用逗号“,”分隔开,这里只是为了方便比较,特别处理的,实际应用中是否有逗号不影响
只要把这组数据进行过渡计算就能完成变形的动画了,这里以SVG的
attributeName 是需要进行变换的属性名,可以是d,fill,stroke等path本身自带的属性,配合value使用,value内则填写对应的属性值,多个值以分号“;”隔开,最后不要加分号。
begin 则是动画开始时间,单位s,ms,如果begin不为0,那么当前图形会显示path中的值而不是animate里value的第一个值,但是当begin为0时,则直接跳过path的值,从animate内的第一个值进行动画。
dur 为持续时间
repeatCount 为播放次数
至于其他的属性及详细用法,感兴趣的同学可以查看文章SVG动画史诗级指南(SMIL)。
tips:
制作变形动画,注意变形前后的锚点必须保持数量一致,而对应的命令也必须相同,比如前一帧是C后一帧变成了S,这样是无法产生动画效果。
最后的最后
好了,现在开始本文的重点了,SMIL被ban了,那我们还怎么制作SVG变形动画?
首先,属性动画能用。
所以像描边效果之类的动画效果都可以正常实现。
而变形动画,其实也可以通过css属性进行设置。
在css中直接定义d:path('path绘制命令')等价于在path中定义d属性。
@keyframes path{0%{d:path('M 200 100 L 300 100 L 200 300 Z');}100%{d:path('M 100 100 L 300 100 L 200 300 Z');}}.path { animation: path 1s infinite;
}
对比前面提到的path命令,我们可以知道,上面的动画分别是:
0%时绘制了一个从(200,100)到(300,100)最后到(200,300)闭合的图形。
100%时绘制了从(100,100)到(300,100)最后到(200,300)闭合的图形。
最后动画的呈现效果就是由一个直角三角形,变为等边三角形。
曲线变形也是同理
曲线变形
@keyframes curve{
0%{
d:path('M293.524 ,444.527
c24 ,75.273 ,-22.024 ,91.973 ,-12.024 ,200.57
c-18 ,-94.598 ,-107.71 ,-36.084 ,-76.976 ,-145.57
c1.241 ,51 ,54.062 ,25.51 ,59.616 ,-1.082
c7.536 ,-36.082 ,3 ,-115 ,-117 ,-162
C233.14 ,365.445 ,277.524 ,404.959 ,293.524 ,444.527
z');
}
100%{
d:path('M293.524 ,444.527
c24 ,75.274 ,-9.083 ,143.344 ,-76.473 ,200.571
c63 ,-83 ,-43.261 ,-36.084 ,-12.527 ,-145.571
c1.241 ,51 ,54.062 ,25.51 ,59.616 ,-1.082
c7.537 ,-36.082 ,3 ,-115 ,-117 ,-162
C233.14 ,365.445 ,277.524 ,404.959 ,293.524 ,444.527
z');
最后放个很酷的SVG奔跑的狐狸,大家可以按照上面的姿势来解析一下这个SVG~
因为年代久远,后续转载的部分大多没标明原作者,知道的同学可以说下出处。