SVG 格局的动画用什么东西来做?

1天前 (02-16 08:37)阅读1回复0
kanwenda
kanwenda
  • 管理员
  • 注册排名1
  • 经验值139060
  • 级别管理员
  • 主题27812
  • 回复0
楼主

概述

SVG 图形能够利用「animation elements」(动画元素),停止动画处置。动画元素最后是在SMIL动画标准中定义的;那些element包罗:

<animate></animate>– 它允许你在一段时间内为标识表记标帜的属性和特征设置动画。<set></set>– 那是 animate 的一种便利的简写形式,可用于将动画值分配给非数字属性和属性,例如可见性属性。<animatemotion></animatemotion>– 沿运动途径挪动元素。<animatecolor></animatecolor>– 跟着时间的推移修改特定属性或特征的颜色值。请留意,该元素已被弃用,取而代之的是简单地利用 animate 元从来定位能够接纳颜色值的属性。虽然它仍然存在于 SVG 1.1 标准中,但明白指出它已被弃用;而且它已从 SVG 2 标准中完全删除。

除了 SMIL 标准中定义的动画元素之外,SVG 还包罗与 SMIL 动画标准兼容的扩展;那些扩展包罗扩展元素功用的属性和附加动画元素。SVG 扩展包罗:

<animatetransform></animatetransform>– 允许你跟着时间的推移为 SVG 的转换属性之一设置动画,例如transform属性。path (attribute) – 允许在animateMotion元素的途径属性中指定 SVG 途径数据语法的任何特征(SMIL 动画只允许途径属性中的 SVG 途径数据语法的子集)。animateMotion我们将鄙人一节中详细讨论。<mpath></mpath>– 与animateMotion元素连系利用以引用将用做运动途径的运动途径。mpath 元素包罗在animateMotion元素内部,位于完毕标识表记标帜之前。keypoints (attribute) – 用做属性animateMotion以供给对运动途径动画速度的切确控造。rotate (attribute) – 用做animateMotion控造对象能否主动扭转的属性,使其 x 轴指向与运动途径的标的目的切向量不异(或相反)的标的目的。此属性是使运动沿途径按预期工做的关键。有关更多信息,请拜见animateMotion部门。

SVG 动画在素质上能够类似于 CSS 动画和过渡。创建关键帧、挪动物体、改动颜色等。但是,它们能够做一些 CSS 动画做不到的工作,我们将对此停止介绍。

为什么要利用 SVG 动画?

SVG 能够利用 CSS(幻灯片)设置款式和动画。根本上,任何能够应用于 HTML 元素的转换或过渡动画也能够应用于 SVG 元素。但是有些 SVG 属性不克不及通过 CSS 停止动画处置,但能够通过 SVG 停止动画处置。例如,SVG 途径带有一组定义该途径外形的「数据」(属性)。d=""那些数据能够通过 SMIL 停止修改和动画化,但不克不及通过 CSS。那是因为 SVG 元素是由一组称为 SVG暗示属性的属性描述的。此中一些属性能够利用 CSS 设置、修改和设置动画,而其他属性则不克不及。

所以,良多动画和效果在那个时候底子无法用CSS来实现。能够利用 JavaScript 或从 SMIL 派生的声明性 SVG 动画来填补 CSS SVG 动画空白。

若是你更喜好利用 JavaScript,我保举利用Dmitry Baranovsky的 snap.svg,它被描述为“SVG 中的 jQuery”。那是一个例子的集合。

或者,若是你更喜好更具声明性的动画办法,则能够利用我们将在本指南中介绍的 SVG 动画元素!

imgSMIL 相关于 JS 动画的另一个优势是,当 SVG 做为 CSS 嵌入或用做CSS时,JS 动画不起感化background-image。SMIL 动画在那两种情况下都有效(或者应该,阅读器撑持待定)。在我看来,那是一个很大的优势。因而,你可能会发现本身选择 SMIL 而不是其他选项。本文是帮忙你立即起头利用 SMIL 的指南。

阅读器撑持和回退

阅读器对 SMIL 动画的撑持相当不错。它们适用于除 Internet Explorer 和 Opera Mini 之外的所有阅读器。有关阅读器撑持的全面概述,你能够参考我能够利用上的兼容性表。

若是你需要为 SMIL 动画供给回退,你能够利用Modernizr立即测试阅读器撑持。若是不撑持 SMIL,你能够供给某种回退(JavaScript 动画、替代体验等)。

指定动画的目的xlink:href

无论选择四种动画元素中的哪一种,都需要指定该元素定义的动画目的。

为了指定目的,你能够利用该xlink:href属性。该属性接纳对元素的 URI 引用,该元素是此动画的目的,因而会跟着时间的推移而修改。「目的元素必需是当前 SVG 文档片段的一部门。」

<rect id="cool_shape" ...=""> <animate xlink:href="#cool_shape" ...=""></animate> </rect>

若是你以前碰到过 SVG 动画元素,你可能已经看到它们嵌套在它们应该设置动画的元素内。那是可能的,也契合标准:

❝若是xlink:href未供给该属性,则目的元素将是当前动画元素的间接父元素。

❞<rect id="cool_shape" ...=""> <animate ...=""></animate> </rect>

所以若是你想将动画“封拆”到它所应用的元素中,你能够如许做。若是你想让动画在文档的其他处所分隔,你也能够如许做,并利用指定每个动画的目的xlink:href。那两种体例都很好。

attributeName利用和指定动画的目的属性attributeType

所有动画元素还共享另一个属性:attributeName. 该attributeName属性用于指定你正在设置动画的属性的名称。

例如,若是你想为 x 轴上 a 的中心位置设置动画,你能够通过指定as属性cx的值来实现。attributeName

attributeName只承受一个值,而不是值列表,因而,你一次只能为一个属性设置动画。若是要为多个属性设置动画,则需要为元素定义多个动画。那是我希望有所差别的工具,并且我认为 CSS 比 SMIL 有优势。但话又说回来,因为其他动画属性的值(我们将在接下来介绍),一次只定义一个属性名称才有意义,不然其他属性值可能会变得太复杂而无法利用。

在指定属性名称时,能够添加 XMLNS(XML 定名空间的缩写)前缀来指示属性的定名空间。定名空间也能够利用attributeType属性指定。例如,一些属性是 CSS 定名空间的一部门(那意味着该属性也能够做为 CSS 属性找到),而其他属性则仅限于 XML。能够在此处找到显示那些属性的表格。表格中的属性并非所有的 SVG 属性。它们只是能够利用 CSS 设置的。此中一些已经做为 CSS 属性供给。

若是 的值attributeType未明白设置或设置为auto,则阅读器必需起首在 CSS 属性列表中搜刮婚配的属性名称,若是未找到,则在默认 XML 定名空间中搜刮该元素。

例如,以下代码片段opacity为 SVG 矩形设置了动画。因为该opacity属性也可用做 CSS 属性,因而attributeType设置为 CSS 定名空间:

<rect> <animate attributetype="CSS" attributename="opacity" from="1" to="0" dur="5s" repeatcount="indefinite"> </animate> </rect>

我们将鄙人面的示例中介绍其他动画属性。除非另有申明,不然所有动画属性关于所有动画元素都是通用的。

在一段时间内将元素的属性从一个值动画化为另一个值,并指定完毕形态:from、by、to和dur``fill

让我们从将一个圆圈从一个位置挪动到另一个位置起头。我们将通过更改其cx属性值(指定此中心的 x 位置)来实现。

我们将利用元从来做到那一点。此元素用于一次为一个属性设置动画。接纳数值和颜色的属性凡是利用 . 有关能够设置动画的属性列表,请参阅此表。

为了在一段时间内将一个值更改为另一个值,from利用to、 和dur属性。除了那些之外,你还需要指定动画何时起头利用该begin属性。

<circle id="my-circle" r="30" cx="50" cy="50" fill="orange"> <animate xlink:href="#my-circle" attributename="cx" from="50" to="450" dur="1s" begin="click" fill="freeze"></animate> </circle>

在上面的例子中,我们定义了一个圆,然后在那个圆上挪用了一个动画。圆心从初始位置沿 x 轴挪动 50 个单元到 450 个单元。

该begin值设置为click。那意味着圆圈将在单击时挪动。你也能够将此值设置为时间值。例如,begin="0s"将在页面加载后立即启动动画。你能够通过设置正时间值来「延迟动画。」 例如,begin="2s"加载后两秒起头播放动画。

更有趣的begin是,你能够定义值,例如「在单击元素后一秒起头播放」click + 1s动画!此外,你能够利用其他值来同步动画,而无需计算其他动画的持续时间和延迟。稍后会详细介绍。****

该dur属性类似于animation-durationCSS 中的等价物。

fromandto属性类似于CSS中动画块中的fromand关键帧:to``@keyframe

@keyframes moveCircle { from { /* start value */ } to { /* end value */ } }

属性(不幸的是与定义元素填充颜色fill的属性同名fill)类似于animation-fill-mode属性,它指定元素能否应在动画完毕后返回到其初始形态。SVG 中的值与 CSS 中的值类似,只是利用差别的名称:

freeze:动画效果定义为将效果值冻结在活动持续时间的最初一个值。动画效果在文档持续时间的剩余时间内“冻结”(或曲到动画从头启动)。remove:当动画的活动持续时间完毕时,动画效果将被移除(不再应用)。动画活动完毕后,动画不再影响目的(除非从头启动动画)。

测验考试更改现场演示中的值以查看动画若何遭到影响:

https://codepen.io/SaraSoueidan/pen/QWYWyr/e883265849147a0a4b712c5960c448a8

该by属性用于指定动画的相对偏移量。望文生义,你能够利用它来指定你希望动画停止的数量。的效果by几乎只要在动画持续时间以离漫步骤前进时才可见,类似于它与 CSSsteps()函数一路利用的体例。相当于 CSSsteps()功用的 SVG 是calcMode="discrete". 我们将calcMode在本文后面介绍该属性。

另一种效果by更明显的情况是当你只指定to属性时。一个例子是,若是你将它与set我们也将在本文后面介绍的元素一路利用。

最初但并不是最不重要的by一点是,在处置叠加和累积动画时也很有用。我们将在本文后面讨论。

重启动画restart

避免动画在活动时从头启动可能很有用。为此,SVG 供给了restart属性。你能够将此属性设置为三个可能值之一:

always:动画能够随时从头起头。那是默认值。whenNotActive: 动画只要在不活动时才气从头起头(即活动完毕后)。在活动期间测验考试从头启动动画将被忽略。never:元素不克不及在父时间容器的当前简单持续时间的剩余时间内从头启动。(在 SVG 的情况下,因为父时间容器是 SVG 文档片段,因而在文档持续时间的剩余时间内无法从头启动动画。)定名动画并同步它们

假设我们要为圆圈的位置和颜色设置动画,以便在挪动动画完毕时发作颜色变革。我们能够通过将begin变色动画的值设置为等于dur挪动动画的值来做到那一点;那就是我们凡是在 CSS 中的做法。

然而,SMIL 有一个很好的事务处置特征。我们之前提到过,该begin属性承受像click + 5s. 该值称为“事务值”,在那种情况下由事务引用和后跟“时钟值”构成。那里有趣的部门是第二部门的定名:“时钟值”。为什么它不但是一个“时间价值”呢?谜底是你能够间接利用时钟值,如“10min”或“01:33”,相当于“1 分 33 秒”,以至“02:30:03”(两小时 30 分钟,和 3 秒)。在撰写本文时,时钟值尚未在任何阅读器中完全实现。

因而,若是我们回到之前的演示并利用click + 01:30,若是阅读器起头撑持它,则动画将在单击圆圈后 1 分 30 秒触发。

它能够承受的另一种值是另一个动画的 ID,后跟一个事务引用。若是你有两个(或更多)动画(无论它们能否应用于统一个元素!)而且你想要同步它们以便此中一个相关于另一个起头,你能够如许做而没必要晓得持续时间另一个动画。

例如,鄙人一个演示中,蓝色矩形在圆形动画起头后 1 秒起头挪动。那是通过为每个动画供给一个ID,然后将该 ID 与begin事务一路利用来完成的,如以下代码所示:

<circle id="orange-circle" r="30" cx="50" cy="50" fill="orange"> <rect id="blue-rectangle" width="50" height="50" x="25" y="200" fill="#0099cc"></rect> <animate xlink:href="#orange-circle" attributename="cx" from="50" to="450" dur="5s" begin="click" fill="freeze" id="circ-anim"> </animate> <animate xlink:href="#blue-rectangle" attributename="x" from="50" to="425" dur="5s" begin="circ-anim.begin + 1s" fill="freeze" id="rect-anim"> </animate> </circle>

那begin="circ-anim.begin + 1s"是告诉阅读器在圆形起头后 1 秒起头矩形动画的部门。你能够查看现场演示:

https://codepen.io/SaraSoueidan/pen/NWoWZo/55195eee8647f438525b852000504c7a

你还能够在圆形动画完毕后利用end事务启动矩形动画:

<animate xlink:href="#blue-rectangle" attributename="x" from="50" to="425" dur="5s" begin="circ-anim.end" fill="freeze" id="rect-anim"> </animate>

你以至能够在圆圈动画完毕之前启动它:

<animate xlink:href="#blue-rectangle" attributename="x" from="50" to="425" dur="5s" begin="circ-anim.end - 3s" fill="freeze" id="rect-anim"> </animate> 反复动画repeatCount

若是你想屡次运行一个动画,你能够利用repeatCount属性来做到那一点。你能够指定希望它反复的次数,或者利用indefinite关键字让它无限反复。因而,若是我们将圆圈的动画反复两次,代码将如下所示:

<animate xlink:href="#orange-circle" attributename="cx" from="50" to="450" dur="5s" begin="click" repeatcount="2" fill="freeze" id="circ-anim"> </animate>

你能够在此处查看现场演示。在演示中,我将反复计数设置为2在圆圈和indefinite正方形上。

请留意动画是若何从初始from值而不是它在动画完毕时到达的值从头起头的。不幸的是,SMIL 不包罗像 CSS 动画允许我们做的那样在起头值和完毕值之间来回切换的办法。在 CSS 中,该animation-direction属性指定动画能否应该在某些或所有轮回或迭代中反向播放。animation-direction: alternatevalue暗示奇数次的动画轮回迭代按一般标的目的播放,偶数次的动画轮回迭代按反标的目的播放。那意味着第一个轮回将从头播放到结尾,然后第二个轮回将从结尾回到开头播放,然后第三个轮回将从头播放到结尾,依此类推。

在 SMIL 中,要做到那一点,你必需利用 JavaScript 显式更改from和to属性的值。Big Bite Creative 的乔恩·麦克帕特兰 (Jon McPartland) 不久前写了一篇文章,解释了他是若何为本身造做的菜单图标动画做到那一点的。

另一种处理办法是将完毕值指定为中间值,然后让完毕值与初始值不异。例如,你能够将动画设置为以from一个值起头,并以与 不异的值完毕to,只是你将要设置为最末值的值指定为 和 之间的中间from值to。

在 CSS 中,我们会利用如许的工具来做到那一点: @keyframes example { from, to { left: 0; } 50% { left: 300px; } }

SMIL 中的等价物是利用values属性,我们将在稍后解释。

也就是说,上述处理办法可能对你有用,也可能不合适你,详细取决于你所逃求的动画类型,以及你能否正在链接动画、反复动画或添加动画。

那是 Miles Elam 利用一些延迟起头时间造做的标致、简单的无限动画:

https://codepen.io/mileselam/pen/QWVYXR

限造反复时间repeatDur

若是动画持续很长时间,将元素设置为无限反复可能会令人厌恶或对用户不友好。因而,将反复时间限造在某个时间段内,并在相关于文档开头的某个时间后停行反复可能是个好主意。那称为演示时间。

呈现时间指示「时间线中相关于给定文档片段的文档起头的位置」。它是利用repeatDur属性指定的。它的语法类似于时钟值的语法,但它不是相关于另一个动画事务或交互事务,而是相关于文档的开头。

例如,以下代码片段将在文档起头后 1 分 30 秒停行动画的反复:

<animate xlink:href="#orange-circle" attributename="cx" from="50" to="450" dur="2s" begin="0s" repeatcount="indefinite" repeatdur="01:30" fill="freeze" id="circ-anim"> </animate>

那是现场演示:

按照反复次数同步动画

如今让我们回到两个动画主题之间的同步。现实上,在 SMIL 中,你能够同步动画,以便一个动画按照另一个动画的反复次数启动。例如,你能够在另一个动画的第 n 次反复之后起头动画,加上或减去你可能想要添加的时间量。

以下示例在圆形动画的第二次反复时启动矩形动画: <animate xlink:href="#blue-rectangle" attributename="x" from="50" to="425" dur="5s" begin="circ-anim.repeat(2)" fill="freeze" id="rect-anim"> </animate>

以下是一个现场演示,此中矩形动画在第二次反复圆形动画后 2 秒起头播放。

https://codepen.io/SaraSoueidan/pen/rNPMJj/366b9fba478e7ac1de2188f5a2594c3c

那是 David Eisenberg 为SVG Essentials(第 2 版) 整理的示例。

控造动画关键帧值:keyTimes和values

在 CSS 中,我们能够指定我们希望动画属性在动画期间的特定帧中接纳的值。例如,若是你正在为元素的左偏移设置动画,而不是间接从 0 到 300 设置动画,你能够为其设置动画,使其在特定帧期间接纳特定值,如下所示:

@keyframes example { 0% { left: 0; } 50% { left: 320px; } 80% { left: 270px; } 100% { left: 300px; } }

、0%、和是动画的帧20%,每个帧的块中的值是每个帧的值。上面描述的效果是一个元素从墙上弹起,然后回到最末位置。80%``100%**

在 SMIL 中,你能够用类似的体例控造每帧的值,但语法完全差别。

要指定关键帧,你能够利用该keyTimes属性。然后利用属性为每个帧指定动画属性的值values。SMIL 中的定名约定十分便利。

若是我们回到我们的挪动圆圈,并利用类似于上面 CSS 关键帧中的值,代码将如下所示:

<animate xlink:href="#orange-circle" attributename="cx" from="50" to="450" dur="2s" begin="click" values="50; 490; 350; 450" keytimes="0; 0.5; 0.8; 1" fill="freeze" id="circ-anim"> </animate>

那么我们在那里做了什么?

那里起首要留意的是关键帧时间和中间值被指定为列表。该keyTimes属性是一个以分号分隔的时间值列表,用于控造动画的节拍。列表中的每个时间对应values属性列表中的一个值,并定义了该值何时在动画函数中利用。列表中的每个时间值keyTimes都指定为 0 到 1(含)之间的浮点值,暗示动画元素的简单持续时间的比例偏移。所以关键时间类似于 CSS 中的关键时间,差别之处在于,不是将它们指定为百分比,而是将它们指定为分数。

以下是上述代码的现场演示。单击圆圈以启动动画。

请留意,若是利用值列表,则动画将在整个动画过程中按挨次应用那些值。若是指定了列表,则忽略values任何和属性值。from``to``by

在那一点上,还值得一提的是,你能够values在没有属性keyTimes的情况下利用属性——值会主动平均地散布在整个时间(关于calcMode除paced(见下一节)之外的每个值)。

利用自定义缓动控造动画节拍:calcMode和keySplines

我将再次停止 CSS-SMIL 比力,因为若是你已经熟悉 CSS 动画,SMIL 语法和概念将更容易理解。

在 CSS 中,你能够选择更改默认的同一动画速度,并利用animation-timing-function属性指定控造动画的自定义缓动函数。计时函数能够是几个预定义关键字之一,也能够是三次贝塞尔函数。后者能够利用东西创建,例如Lea Verou的东西。

在 SMIL 中,动画速度是利用calcMode属性指定的。默认动画速度适用linear于所有动画元素,除了animateMotion(我们将在本文后面介绍)。除了linear值之外,你还能够将值设置为:discrete、paced或spline。

discrete指定动画函数将在没有任何插值的情况下从一个值跳到下一个值。那类似于steps()CSS 中的函数。paced类似于linear,只是它会忽略由 定义的任何中间进度时间keyTimes。它计算出后续值之间的间隔并响应地划分时间。若是你的值全数按线性挨次摆列,你将不会留意到差别。但若是它们来回挪动,或者若是它们是颜色(被视为三维矢量值),你必定会看到中间值。那是 Amelia Bellamy-Royds 供给的演示,calcMode它显示了到目前为行提到的三个值之间的差别。承受的第四个值calcMode是spline。它values按照三次贝塞尔样条定义的时间函数从列表中的一个值插值到下一个值。样条的点在keyTimes属性中定义,每个区间的控造点在keySplines属性中定义。

你可能已经留意到最初一句话中的新属性:keySplines属性。那么,keySplines属性有什么感化呢?

同样,关于 CSS 等价物。

在 CSS 中,你能够在每个关键帧内指定动画速度,而不是为整个动画指定一个动画速度。那使你能够更好地控造每个关键帧动画的处置体例。利用此功用的一个示例是创建弹跳球效果。其关键帧可能如下所示:

@keyframes bounce { 0% { top: 0; animation-timing-function: ease-in; } 15% { top: 200px; animation-timing-function: ease-out; } 30% { top: 70px; animation-timing-function: ease-in; } 45% { top: 200px; animation-timing-function: ease-out; } 60% { top: 120px; animation-timing-function: ease-in; } 75% { top: 200px; animation-timing-function: ease-out; } 90% { top: 170px; animation-timing-function: ease-in; } 100% { top: 200px; animation-timing-function: ease-out; } }

我们能够利用响应的 cubic-bezier 函数,而不是关键字缓动函数:

ease-in=cubic-bezier(0.47, 0, 0.745, 0.715)ease-out=cubic-bezier(0.39, 0.575, 0.565, 1)

让我们起首为我们的橙色圆圈指定关键时间和**列表values**以停止不异的弹跳效果:

<animate xlink:href="#orange-circle" attributename="cy" from="50" to="250" dur="3s" begin="click" values="50; 250; 120;250; 170; 250; 210; 250" keytimes="0; 0.15; 0.3; 0.45; 0.6; 0.75; 0.9; 1" fill="freeze" id="circ-anim"> </animate>

动画将在点击时起头,一旦到达完毕值就会冻结。接下来,为了指定每个关键帧的速度,我们将添加keySplines属性。

该keySplines属性接纳与列表联系关系的贝塞尔「曲线控造点」keyTimes集,定义控造间隔步伐的三次贝塞尔曲线函数。属性值是以分号分隔的控造点描述列表。每个控造点描述都是一组四个值:x1 y1 x2 y2,描述一个时间段的贝塞尔曲线控造点。那些值必需都在 0 到 1 的范畴内,除非将calcMode设置为 ,不然该属性将被忽略spline。

不是将三次贝塞尔函数做为值,keySplines而是接纳用于绘造曲线的两个控造点的坐标。能够在以下从 Lea 的东西截取的屏幕截图中看到控造点。屏幕截图还显示了每个点的坐标,每个点的颜色都与该点自己的颜色不异。关于keySplines属性,我们将利用那些值来定义关键帧动画的速度。

SMIL 允许那些值用逗号和可选的空格分隔,或者只用空格分隔。定义联系关系段的keyTimes值是贝塞尔曲线“锚点”,那些keySplines值是控造点。因而,必需有一组控造点比有少keyTimes。

若是我们回到弹跳球的例子,ease-in和ease-out函数的控造点坐标如下图所示:

因而,为了将其转换为 SVG 动画元素,我们得到以下代码:

<animate xlink:href="#orange-circle" attributename="cy" from="50" to="250" dur="3s" begin="click" values="50; 250; 120;250; 170; 250; 210; 250" keytimes="0; 0.15; 0.3; 0.45; 0.6; 0.75; 0.9; 1" keysplines=" .42 0 1 1; 0 0 .59 1; .42 0 1 1; 0 0 .59 1; .42 0 1 1; 0 0 .59 1; .42 0 1 1; 0 0 .59 1;" fill="freeze" id="circ-anim"> </animate>

那是现场演示:

若是你只想为整个动画指定一个整体缓动函数而没有任何中间值,你仍然必需利用该keyTimes属性指定关键帧,但你只需指定起头和完毕关键帧,即0; 1,而没有中间值values。

加法和累积动画:additive和accumulate

有时,定义一个畴前一个动画完毕的处所起头的动画很有用;或利用先前动画的累积总和做为继续施行的值的动画。为此,SVG 有两个便利定名的属性:additive和accumulate.

假设你有一个要“增加”宽度的元素,或者要增加一条线的长度,或者要在差别的步调中逐渐从一个位置挪动到另一个位置的元素。此功用关于反复动画出格有用。

就像任何其他动画一样,你将指定from和to值。但是,当你设置additive为时sum,它们的每个值都将「相关于动画属性的原始值」。

那么,回到我们的圈子。关于我们的圆,初始位置cx是50,当你设置from="0" to="100"的时候,0其实就是本来的50,100其实就是50+100;换句话说,它现实上有点像“ from="50" to="150"”。

通过如许做,我们得到以下成果:

那就是additive属性的全数感化。它只是指定from和to值能否应该相关于当前值。该属性仅接纳以下两个值之一:sum和replace。后者是默认值,它根本上意味着from和to值将替代当前/原始值,那最末可能会在动画起头之前招致奇异的跳跃。(测验考试在上面的示例中替代sum为replace以获得更好的比力。)

但是,若是我们希望添加的值使得第二次反复畴前一次的完毕值起头怎么办?那就是accumulate属性的用武之地。

该accumulate属性控造动画能否累积。默认值为none,那意味着,例如,当动画反复时,它将从头起头。但是,你能够将其设置为sum,那指定在第一次迭代之后的每个反复迭代都成立在前一次迭代的最初一个值之上。

所以,若是我们回到之前的动画并指定accumulate="sum",我们将得到以下可预知的成果: https://codepen.io/SaraSoueidan/pen/zYeaGp/e21b7dd0af3d0a6db2828362bee24d48

请留意,accumulate若是目的属性值不撑持添加,或者若是动画元素不反复,则忽略该属性。to若是仅利用属性指定动画功用,它也会被忽略。

指定动画的完毕时间end

除了指定动画何时起头外,你还能够利用end属性指定动画何时完毕。例如,你能够将动画设置为无限反复,然后在另一个元素起头动画时停行。属性接纳的end值类似于begin值接纳的值。你能够指定绝对或相对时间值/偏移量、反复值、事务值等。

例如,鄙人面的演示中,橙色圆圈在 30 秒内迟缓挪动到画布的另一侧。绿色圆圈也会动画,但只要在单击时才会动画。当绿色圆圈的动画起头时,橙色圆圈的动画将完毕。点击绿色圆圈能够看到橙色的一站式:

当然,能够为应用于统一元素的两个动画实现不异类型的动画同步。例如,假设我们将圆圈的颜色设置为从一个值无期限地变成另一个值的动画。然后,当单击该元素时,它会挪动到另一侧。我们如今将设置它,以便在单击元素并触发挪动动画时立即停行颜色动画。

begin利用多个和end值定义动画间隔

现实上,begin和end属性都承受以「分号分隔的值列表」。属性中的每个值begin城市对应属性中的一个值end,从而构成活泼和不活泼的动画区间。

你能够将其想象成类似于行驶中的汽车,汽车的轮胎会在一段时间内处于活动形态,然后在一段时间内处于不活动形态,详细取决于汽车能否在挪动。你以至能够通过将动画应用到汽车来创建动画汽车效果:一个平移汽车或沿着途径挪动它也是一种累加和累积动画,另一个动画以同步的间隔扭转汽车轮胎与翻译。

指定多个起头和完毕时间(即间隔)的示例是以下演示,此中矩形按照定义的间隔扭转,响应地从活动变成非活动。(若是你错过了动画,请从头运行演示。)

请留意,在上面的示例中,我利用了元从来围绕此中心扭转矩形。我们将鄙人面的下一节中更详细地讨论那个元素。

另请留意,即便你设置repeatCount为indefinite,它也会被end值笼盖而且不会无期限地反复。

min利用和限造元素的活动持续时间max

就像你能够限造动画的反复时间一样,你以至能够限造动画的「活动持续时间」。min和属性别离指定活动持续时间的max最小值和更大值。它们为我们供给了一种控造元素活动持续时间下限和上限的办法。那两个属性都以时钟值做为值。

关于min,它指定活动持续时间的最小值的长度,以元素活动时间丈量。值必需大于或等于 0,那是默认值,底子不限造活动持续时间。

关于max,时钟值指定活动持续时间更大值的长度,以元素活动时间丈量。值也必需大于 0。默认max值为indefinite。那底子不限造活动持续时间。

若是同时指定了min和max属性,则该max值必需大于或等于该min值。若是不满足此要求,则忽略那两个属性。

但是什么定义了元素的「活动持续时间?」 之前我们提到了反复持续时间,除了“简单持续时间”之外,也就是没有任何反复的动画持续时间(利用 指定dur),那么所有那些是若何协同工做的呢?哪个笼盖什么?那么end将笼盖并简单地完毕动画的属性呢?

它发作的体例是阅读器将起首按照 、 、 和 值计算dur活动repeatCount持续repeatDur时间end。然后min,它按照指定的和max值运行计算的持续时间。若是成果在范畴内,则此第一个计算的持续时间值是准确的而且不会更改。不然可能会呈现两种情况:

若是第一个计算的持续时间大于该max值,则元素的活动持续时间被定义为等于该max值。若是第一个计算的持续时间小于该min值,则元素的活动持续时间变成等于该min值而且该元素的行为如下:若是元素的反复持续时间(若是元素不反复,则为简单持续时间)大于,min则该元素将在(min受限的)活动持续时间内一般播放。不然,元素将在其反复持续时间(若是元素不反复则为简单持续时间)内一般播放,然后按照fill属性值冻结或不显示。

那让我们晓得阅读器现实上是若何计算活动持续时间的。为了简洁起见,我不筹算在那里详细介绍。但是标准中有一个十分全面的表格,显示了 、 、 和 属性的差别组合dur,repeatCount然后repeatDur显示end了基于每个组合的活动持续时间。你能够查看该表并在标准的那一部门阅读更多相关信息。

最初,若是一个元素被定义为在其父元素之前起头(例如,利用简单的负偏移值),则最小持续时间是从计算的起头时间而不是察看到的起头时间起头丈量的。那意味着该min值可能没有察看到的效果。

示例:变形途径

能够在 SMIL 中(但不克不及在 CSS 中)设置动画的属性之一是 SVG 的d属性(data的缩写)。该d属性包罗定义你正在绘造的外形轮廓的数据。途径数据由「一组号令和坐标」构成,那些号令和坐标告诉阅读器在哪里以及若何绘造构成最末途径的点、弧和线。

为该属性设置动画允许我们变形SVG 途径并创建外形补间效果。但是,为了可以变形外形,起头、完毕和任何中间途径外形需要具有完全不异数量的顶点/点,而且它们需要以不异的挨次呈现。若是顶点数量不婚配,动画将无法运行。如许做的原因是外形的改动现实上是通过挪动顶点并插值它们的位置而发作的,所以若是一个顶点丧失或不婚配,途径将不再被插值。

要为 SVG 途径设置动画,你能够将 指定attributeName为d,然后设置指定起头和完毕外形的from和to值,而且你能够利用该values属性指定你希望外形在其间颠末的任何中间值。

为了简洁起见,我不会在那里详细介绍若何施行此操做。相反,你能够阅读Noah Blon 撰写的那篇优良文章,此中他解释了他若何利用 . 诺亚文章的现场演示是如许的:

https://codepen.io/noahblon/pen/wvxmgv

那是 Felix Hornoiu 的另一个变形示例:

https://codepen.io/felixhornoiu/pen/JjmVZw

你以至能够变形用做剪贴蒙版的途径的值!Heather Buchel 的一个例子:

https://codepen.io/hbuchel/pen/YzYMgd

沿肆意途径造做动画:元素

该元素是我最喜好的 SMIL 动画元素。你能够利用它沿途径挪动元素。你能够利用我们接下来要介绍的两种办法之一来指定运动途径,然后设置元素,使其沿着该途径挪动。

该元素承受前面提到的不异属性,外加三个属性:keyPoints、rotate和path。此外,该属性也有一个区别calcMode,默认值为paced,而不是linear。

path利用属性指定运动途径

该path属性用于指定运动途径。它以与元素d上的属性不异的格局暗示并以不异的体例解释。path运动途径动画的效果是将弥补变更矩阵添加到引用对象的当前变更矩阵上,那会招致沿当前用户坐标系的 x 轴和 y 轴平移计算出的 X 和 Y 值时间。换句话说,指定的途径是相关于元素的当前位置计算的,通过利用途径数据将元素转换到途径位置。

关于我们的圆圈,我们将沿着如下所示的途径对其停止动画处置:

圆圈沿着那条途径挪动所需的代码是:

<animatemotion xlink:href="#circle" dur="1s" begin="click" fill="freeze" path="M0,0c3.2-3.4,18.4-0.6,23.4-0.6c5.7,0.1,10.8,0.9,16.3,2.3 c13.5,3.5,26.1,9.6,38.5,16.2c12.3,6.5,21.3,16.8,31.9,25.4c10.8,8.7,21,18.3,31.7,26.9c9.3,7.4,20.9,11.5,31.4,16.7 c13.7,6.8,26.8,9.7,41.8,9c21.4-1,40.8-3.7,61.3-10.4c10.9-3.5,18.9-11.3,28.5-17.8c5.4-3.7,10.4-6.7,14.8-11.5 c1.9-2.1,3.7-5.5,6.5-6.5"></animatemotion>

我想在那里存眷一件事:途径数据中的坐标。该途径起首将 ( 「M」) 挪动到坐标为 的点(0, 0),然后起头绘造一条曲线 ( 「c」) 到另一点。重要的是要留意,该(0, 0)点现实上是圆的位置,无论它在哪里——而不是坐标系的左上角。上面我们说过,path属性中的坐标是相关于元素当前位置的!

上面代码的成果是: https://codepen.io/SaraSoueidan/pen/YzBJxb/184082960ac3cc65d00b22f2551a330a

若是你要指定从点以外的点起头的途径(0, 0),圆将突然跳跃起点中指定的量。例如,假设你在 Illustrator 中绘造一条途径,然后导出该途径数据以用做运动途径(那是我第一次如许做);导出的途径可能看起来像如许:

<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M100.4,102.2c3.2-3.4,18.4-0.6,23.4-0.6c5.7,0.1,10.8,0.9,16.3,2.3 c13.5,3.5,26.1,9.6,38.5,16.2c12.3,6.5,21.3,16.8,31.9,25.4c10.8,8.7,21,18.3,31.7,26.9c9.3,7.4,20.9,11.5,31.4,16.7 c13.7,6.8,26.8,9.7,41.8,9c21.4-1,40.8-3.7,61.3-10.4c10.9-3.5,18.9-11.3,28.5-17.8c5.4-3.7,10.4-6.7,14.8-11.5 c1.9-2.1,3.7-5.5,6.5-6.5"></path>

本例中途径的起点是(100.4, 102.2)。若是我们利用此数据做为运动途径,圆将向右跳约 100 个单元并向下跳约 102 个单元,然后起头沿着相关于新位置的途径运动。因而,当你为动画筹办运动途径时,请务必服膺那一点。

若是利用,属性from, by,to并values在当前画布上指定一个暗示运动途径的外形。

利用元素指定运动途径

还有另一种办法能够指定运动途径。path你能够利用元素引用外部途径,而不是利用相对属性。然后,该元素的子元素将利用该xlink:href属性引用外部途径。

<animatemotion xlink:href="#circle" dur="1s" begin="click" fill="freeze"> <mpath xlink:href="#motionPath"></mpath> </animatemotion>

运动途径能够在文档的任何处所定义;它以至能够从字面上只定义在一个元素内,底子不在画布上呈现。鄙人一个示例中,将呈现途径,因为在大大都情况下,你可能希望显示元素挪动的途径。

请留意,按照标准:

❝外形的各类 (x, y) 点为参考对象供给了一个弥补变更矩阵到 CTM 上,它招致沿当前用户坐标系的 x 和 y 轴平移 (x,y) 值随时间计算的外形。因而,参考对象随时间平移运动途径相关于当前用户坐标系原点的偏移量。因为目的元素的transform属性或因为animateTransform目的元素上的元素而在该属性上的任何动画,弥补转换应用于任何转换之上。

同样,圆的位置与途径数据中的坐标“相乘”或“转换”。

鄙人一个示例中,我们在画布中间有一条途径。圆圈位于途径的开头。然而,当应用运动途径时,圆不会从其当前位置起头运动。请参阅演示以获得更好的解释。单击圆圈使其动画化。

看看圆是若何遵照不异外形的途径,但在差别的位置?那是因为圆的位置由途径数据的值转换所致。

处理此问题的一种办法是从位于 的圆起头(0, 0),如许当利用途径数据对其停止转换时,它将按预期起头并继续停止。

另一种办法是应用“重置”圆坐标的转换,以便在应用途径之前它们计算为零。

以下是上述演示的修改版本,利用闭合途径并没有限反复运动动画。

https://codepen.io/SaraSoueidan/pen/ExrdEe/ef9f0e1242263cf23067b09be894cfa9

笼盖规则<animatemotion></animatemotion>

因为有不行一种办法能够为 做同样的工作animateMotion,所以只要笼盖规则来指定哪些值笼盖其他值才有意义。

的笼盖规则animateMotion如下:

关于运动途径的定义,mpath元素笼盖了path属性,笼盖了values,笼盖了from,by和to。keyTimes关于确定属性对应的点,keyPoints属性笼盖path,笼盖values,笼盖from,by和to。沿运动途径设置元素的标的目的rotate

在我们前面的例子中,我们沿着途径设置动画的元素刚好是一个圆。但是,若是我们正在为具有特定标的目的的元素(例如汽车图标)造做动画怎么办?以下示例中的汽车图标由 Freepik 设想。

在此示例中,我将圆圈替代为 ID 为“car”的组,此中包罗构成该组的元素。然后,为了制止上述途径上的运动问题,我对汽车应用了一个转换,使其平移特定的量,以便初始位置完毕于 (0, 0)。转换中的值现实上是汽车的第一条途径起头绘造的点的坐标(就在挪动号令「M」之后)。

然后汽车起头沿着运动途径挪动。但是……那就是运动的样子:

https://codepen.io/SaraSoueidan/pen/poGxKW/3a300b8c4c0f9db4ff345f5d44992b74

汽车的标的目的是固定的,不会改动以婚配运动途径的标的目的。为了改动那一点,我们将利用该rotate属性。

该rotate属性接纳以下三个值之一:

auto:暗示物体随时间扭转运动途径标的目的(即标的目的切向量)的角度。auto-reverse:暗示物体随时间扭转运动途径的标的目的(即标的目的切向量)的角度加上180度。数字:指示目的元素应用了恒定扭转变更,此中扭转角度是指定的度数。

为了在上面的例子中固定汽车的标的目的,我们起首将扭转值设置为auto。我们最末会得到以下成果:

https://codepen.io/SaraSoueidan/pen/LYqgra/74af0bd0bbc7ca46d4d568ca0d473b40

若是你希望汽车挪动到途径之外,该auto-reverse值会处理那个问题。

https://codepen.io/SaraSoueidan/pen/gOqBja/1027d099f0e9cca94f8f8865d169c49f

那看起来好多了,但我们仍然有一个问题:汽车看起来像是在沿着途径向后挪动!为了改动那种情况,我们需要沿 y 轴翻转汽车。那能够通过沿该轴将其缩放“-1”倍来完成。因而,若是我们将转换应用于g具有carID 的 ,汽车将按预期向前挪动。缩放转换将与我们之前应用的先前转换链接在一路。

最初的演示是如许的:

https://codepen.io/SaraSoueidan/pen/rNPqrK/48caf2f5fa42a8c154fcb5dec0dbe4d5

控造沿运动途径的动画间隔keyPoints

该属性供给了为每个指定值keyPoints指定沿运动途径的进度的才能。keyTimes若是指定,则keyPoints招致keyTimes应用于属性数组中指定的值keyPoints而不是values属性数组中指定的点或属性上的点path。

keyPoints``keyTimes接纳分号分隔的 0 到 1 之间的浮点值列表,并指示对象在响应值指定的时刻应沿着运动途径挪动多远。间隔计算由阅读器的算法决定。列表中的每个进度值对应于keyTimes属性列表中的一个值。若是keyPoints指定了列表,则列表中的值必需与keyPoints列表中的值一样多keyTimes。

那里要留意的一件重要工作是将calcMode值设置为linearfor keyPointsto work。若是你的关键点来回挪动,它看起来也应该在逻辑上与节拍动画一路工做,但事实并不是如斯。

以下是 Amelia Bellamy-Royds 的示例(你应该完全查看其CodePen 设置装备摆设文件keyPoints),该示例用于模仿行为是从预定义的偏移量起头沿途径运动,因为我们目前没有那种才能SMIL 中的默认值。

https://codepen.io/AmeliaBR/pen/VwNvpw

沿肆意途径挪动文本

沿肆意途径挪动文本差别于沿途径挪动其他 SVG 元素。要为文本设置动画,你将不能不利用元素,而不是元素。

起首,让我们从沿着途径定位文本起头。那能够通过在元素内嵌套一个元从来完成。将要沿途径定位的文本将在元素内部定义,而不是做为元素的子元素。

然后textPath将引用我们要利用的现实途径,就像我们在前面的示例中所做的那样。引用途径也能够呈如今画布上,或在 . 把下面的demo中的代码查出来。 https://codepen.io/SaraSoueidan/pen/NWoOEp/ebfc92e45e24b29c266f50e6f617cdf5

为了沿该途径为文本设置动画,我们将利用元素为startOffset属性设置动画。

startOffset暗示文本在途径上的偏移量。0% 是途径的起头;100%代表它的完毕。因而,例如,若是偏移量设置为 50%,文本将从途径的半途起头。我想你能够从那里看到我们要去的处所。

通过为 设置动画startOffset,我们将创建文本沿途径挪动的效果。把下面的demo中的代码查出来。

https://codepen.io/SaraSoueidan/pen/qBgJLw/501308e154923359ed1cdbfa29eadcc0

动画转换:<animatetransform></animatetransform>元素

该元素为目的元素上的转换属性设置动画,从而允许动画控造平移、缩放、扭转和/或倾斜。它接纳与元素不异的属性,外加一个附加属性:type。

该type属性用于指定动画转换的类型。它接纳以下五个值之一:translate、scale、rotate、skewX和skewY。

,from和属性接纳by与to给定转换类型可用的不异语法暗示的值:

关于 a type="translate",每个零丁的值暗示为<tx> [,<ty>]</ty></tx>。关于 a type="scale",每个零丁的值暗示为<sx> [,<sy>]</sy></sx>。关于 a type="rotate",每个零丁的值暗示为<rotate-angle> [<cx> <cy>]</cy></cx></rotate-angle>。关于 atype="skewX"和type="skewY",每个零丁的值暗示为<skew-angle></skew-angle>。

若是你不熟悉 SVGtransform属性函数的语法,而且为了本文的简洁起见,而且因为语法详细信息及其工做原理超出了本文的范畴,我建议你阅读我的文章在继续阅读本指南之前,有一段时间写过那篇文章:“理解 SVG 坐标系和变更(第 2 部门):transform属性”。

回到之前的演示,我们利用<animatetransform></animatetransform>元素扭转粉色矩形。扭转的代码如下所示:

<rect id="deepPink-rectangle" width="50" height="50" x="50" y="50" fill="deepPink"> <animatetransform xlink:href="#deepPink-rectangle" attributename="transform" attributetype="XML" type="rotate" from="0 75 75" to="360 75 75" dur="2s" begin="0s" repeatcount="indefinite" fill="freeze" > </rect>

和属性指定扭转角度(起头和完毕)和扭转中心from。to当然,在两者中,扭转中心连结稳定。若是你不指定中心,它将位于 SVG 画布的左上角。上述代码的现场演示如下: https://codepen.io/SaraSoueidan/pen/OJdBqR/1bb859d4103d5e32b037f69e906319fb

animateTransform那是Gabriel的单曲的另一个有趣示例: https://codepen.io/guerreiro/pen/rNZajZ

为单个变更设置动画很简单,但是,当包罗多个变更时,工作会变得十分紊乱和复杂,出格是因为一个animateTransform能够笼盖另一个,所以不是添加和链接效果,你最末可能会得到完全相反的成果。那,除了 SVG 坐标系和转换的现实工做体例(请参阅前面提到的关于该主题的文章)。那些例子良多,超出了本文的范畴。关于转换 SVG,我建议利用 CSS 转换。实现正在勤奋使后者与 SVG 完美共同,因而你可能底子不需要利用 SMIL 来为 SVG 中的转换设置动画。

<set></set>元素_

该set元素供给了一种在指定持续时间内设置属性值的简双方法。它撑持所有属性类型,包罗那些不克不及合理插入的属性类型,例如字符串和布尔值。该set元素长短添加的。additive 和 accumulate 属性是不允许的,若是指定将被忽略。

因为用于在特按时间和期间将元素设置为特定值,因而它不承受前面提到的动画元素的所有属性。好比它没有a fromorby属性,因为变革的值不会跟着时间的推移递增变革。

关于set,你能够指定你要定位的元素、属性名称和类型、to值,而且动画时间能够通过以下体例控造:begin、dur、end、min、max、restart、repeatCount、repeatDur和fill。

以下是将扭转矩形的颜色设置为单击时的蓝色的示例。颜色连结蓝色 3 秒,然后变回本来的颜色。每次单击矩形时,set城市触策动画,并更改颜色三秒钟。 https://codepen.io/SaraSoueidan/pen/xxMyoe/af159baaf57bc38eb40288db722e1245

能够设置动画的元素、属性和属性

并不是所有 SVG 属性都能够设置动画,也不是所有能够设置动画的属性都能够利用所有动画元素设置动画。有关所有动画属性的完好列表,以及显示哪些属性能够由哪些元素动画的表格,请参阅SVG 动画标准的那一部门。

最初的话

SMIL 有很大的潜力,我只是触及外相,只触及了它们在 SVG 中若何工做的根底常识和手艺细节。能够创建许多十分令人印象深入的效果,尤其是涉及变形和变更外形的效果。天空是极限。疯了!而且不要忘记与社区分享你的做品;我们很想看看你在做什么。感激你的阅读!

文章翻译自:https://css-tricks.com/guide-svg-animations-smil/

0
回帖

SVG 格局的动画用什么东西来做? 期待您的回复!

取消
载入表情清单……
载入颜色清单……
插入网络图片

取消确定

图片上传中
编辑器信息
提示信息