SVG 动画精华

TL;DR

本文主如果解说关于 SVG 的一些高等动画殊效,比方 SVG 动画标签,图形渐变,途径动画,线条动画,SVG 裁剪等。

比方:途径动画

《SVG 动画精华》

图形渐变:

《SVG 动画精华》

线条动画:

《SVG 动画精华》

以及,相干的动画的矩阵学问,这个也是如今 CSS 动画内里最重要,同时也是最为短缺的学问点:

《SVG 动画精华》

文章会先从基础语法入手,然后,逐步深切。引见一些动画基础原理和对应的数学原理学问点。而且文章背面,还附有相干语法的引见,当你在碰到不熟悉语法的时刻可以参考参考。

前面一篇文章,重要引见了一些 SVG 的基础观点和基础图形。接下来我们须要相识一下,SVG 处置惩罚矢量这个特征以外,另有啥内容吸收我们,能让 SVG 如今提高度这么高?

原文参考:前端小吉米

SVG Animation

在 SVG 中,如果我们想完成一个动画效果,可以应用 CSS,JS,或许直接应用 SVG 中自带的 animate 元素增添动画。

应用 CSS 的话,有两种挑选一种是经由历程 style 直接内联在内里,别的是直接应用相干的动画属性– transform

 <use id="star" class="starStyle" xlink:href="#starDef"
       transform="translate(100, 100)"
       style="fill: #008000; stroke: #008000"/>

而应用 SVG 中自定的 animate 重要照样 SVG 本身的东西,比较好用。如果想用 CSS 的动画,这都无所谓。

先看一个 SVG animate DEMO:

<rect x="10" y="10" width="200" height="20" stroke="black" fill="none">
  <animate
    attributeName="width"
    attributeType="XML"
    from="200" to="20"
    begin="0s" dur="5s"
    fill="freeze" />
</rect>

经由历程将 animate 标签嵌套在指定的图形内里,即可完成变更的效果。别的,另有 animateTransform,它主如果用来做变形动画的。

<rect x="-10" y="-10" width="20" height="20"
    style="fill: #ff9; stroke: black;">
    <animateTransform attributeType="XML"
      attributeName="transform" type="scale"
      from="1" to="4 2"
      begin="0s" dur="4s" fill="freeze"/>
</rect>

简朴来讲:

  • animate: 相当于 CSS 中的 transition

  • animateTransform: 相当于 CSS 中的 transform

内里一些手艺细节我们这里就不过量解说了。这里,重要想引见一下 animate 中的 morph 的效果。

animate morph

该效果重要做的就是图形内部的渐变。如图:

《SVG 动画精华》

这类动画是怎样完成呢?

直接看代码吧:

<path fill="#1EB287">
    <animate 
             attributeName="d" 
             dur="1440ms" 
             repeatCount="indefinite"
             keyTimes="0;
                       .0625;
                       .208333333;
                       .3125;
                       .395833333;
                       .645833333;
                       .833333333;
                       1"
             calcMode="spline" 
             keySplines="0,0,1,1;
                         .42,0,.58,1;
                         .42,0,1,1;
                         0,0,.58,1;
                         .42,0,.58,1;
                         .42,0,.58,1;
                         .42,0,.58,1"
             values="M 0,0 
                     C 50,0 50,0 100,0
                     100,50 100,50 100,100
                     50,100 50,100 0,100
                     0,50 0,50 0,0
                     Z;

                     M 0,0 
                     C 50,0 50,0 100,0
                     100,50 100,50 100,100
                     50,100 50,100 0,100
                     0,50 0,50 0,0
                     Z;

                     M 50,0 
                     C 75,25 75,25 100,50 
                     75,75 75,75 50,100
                     25,75 25,75 0,50
                     25,25 25,25 50,0
                     Z;

                     M 25,50 
                     C 37.5,25 37.5,25 50,0 
                     75,50 75,50 100,100
                     50,100 50,100 0,100
                     12.5,75 12.5,75 25,50
                     Z;

                     M 25,50 
                     C 37.5,25 37.5,25 50,0 
                     75,50 75,50 100,100
                     50,100 50,100 0,100
                     12.5,75 12.5,75 25,50
                     Z;

                     M 50,0
                     C 77.6,0 100,22.4 100,50 
                     100,77.6 77.6,100 50,100
                     22.4,100, 0,77.6, 0,50
                     0,22.4, 22.4,0, 50,0
                     Z;
                     
                     M 50,0
                     C 77.6,0 100,22.4 100,50 
                     100,77.6 77.6,100 50,100
                     22.4,100, 0,77.6, 0,50
                     0,22.4, 22.4,0, 50,0
                     Z;
                     
                     M 100,0 
                     C 100,50 100,50 100,100
                     50,100 50,100 0,100
                     0,50 0,50 0,0
                     50,0 50,0 100,0
                     Z;"/>
  </path>

这么多,是不是是觉得有点懵逼。不过,我们细分来看一下实在很简朴。内里主如果应用 animate 中的 keyTimescalcModekeySplines,以及 values 这几个属性。不急,我们一个一个来诠释一下。

  • keyTimes: 这实在和 CSS 中定义的 @keyframes 一样。经由历程 0-1 之间的值,定义每段动画完成的时候。花样为:value;value...。比方 0;.0625;.208333333;.3125;.395833333;.645833333;.833333333;1。从第一个动画,到第二个动画阅历的时候比例为 6.25%。而且,keyTimes 须要和 values 内里定义的帧数一致。

  • calcMode: 用来定义动画细致的插值模子。取值有: discrete | linear[default] | paced | spline。细致可以参考 MDN。这里我们重要引见一下 spline。该值示意每一个动画间应用自定的贝塞尔变更曲线。如果没有特别请求,应用 linear 实在已足够了,如许就不必贫苦去定义下面的 keySplines 属性。

  • keySplines:该值用来细致定义动画实行时的 贝塞尔曲线。应用花样是经由历程 ; 来离开每一个值。即,cubic-bezier(.31,.57,.93,.46) 为一组。应用 keySplines 表达,则为:keySplines = ".31,.57,.93,.46;"。固然,内里的贝塞尔曲线组数为 全部动画帧数 - 1

而 values 就很简朴了。它是直接连系 attributeName 属性,来设置细致的值,每一个值之间应用 ; 举行离开。

像上面那样,可以在指定元素内里嵌套多个 animate,既完成了外形的转变,又完成了色彩的转变。Morph 比较常用于数字的更迭,比方,倒数 10s 的相干动画。到这里,Morpah 相干的学问点就完毕了。

接着,让我们来看一下 SVG 中,别的一异常重要的标签 — animateMotion

该标签可以让指定的元素,绕着指定的途径举行活动。所以这关于庞杂的途径来讲异常有效,因为我们很难应用 transform 去模仿庞杂的变更途径。看一个 DEMO

《SVG 动画精华》

animateMotion

animateMotion 大抵的属性和 animate 差不多,不过,它还具有本身特有的属性,比方 keyPointsrotatepath 等。不过,calcMode 在 AM(animateMotion) 中的默许属性由,linear 变成 paced

这些属性,我们逐步引见,先从最简朴的最先吧。起首,我们来看一个 DEMO:

<g>
  <rect x="0" y="0" width="30" height="30" style="fill: #ccc;"/>
  <circle cx="30" cy="30" r="15" style="fill: #cfc; stroke: green;"/>
  <animateMotion from="0,0" to="60,30" dur="4s" fill="freeze"/>
</g>
  • from,to:指定两点的位置,位置参数是以元素的坐标为原点的。

  • dur:实行衬着时候

  • fill:指定动画完毕后停止的装填。有 freezeremove 效果。remove 示意回到动画最先的位置,freeze 示意停止在动画完毕的位置。

如果,你想要更庞杂的途径,可以直接应用 path 属性来指定途径。用法和 path 标签中 d 属性是一样的。

<rect x="0" y="0" width="30" height="30" style="fill: #ccc;">
    <animateMotion
    path="M50,125 C 100,25 150,225, 200, 125"
    dur="6s" fill="freeze"/>
</rect>

或许应用 mpath 标签,援用外部的 path

  <path d="M10,110 A120,120 -45 0,1 110 10 A120,120 -45 0,1 10,110"
      stroke="lightgrey" stroke-width="2" 
      fill="none" id="theMotionPath"/>
  <circle cx="10" cy="110" r="3" fill="lightgrey"  />
  <circle cx="110" cy="10" r="3" fill="lightgrey"  />

  <!-- Red circle which will be moved along the motion path. -->
  <circle cx="" cy="" r="5" fill="red">

    <!-- Define the motion path animation -->
    <animateMotion dur="6s" repeatCount="indefinite">
      <mpath xlink:href="#theMotionPath"/>
    </animateMotion>
  </circle>

动画效果为:

《SVG 动画精华》

所以,平常而言我们在定义 AM 的途径的时刻,只用一种体式格局定义即可,不然会发生响应的掩盖:mpath>path>values>from/to

在 AM 活动中,另有一个很重要的观点就是扭转角。默许情况下,活动物体的角度是根据它和坐标轴的初始角度肯定的。比方:

《SVG 动画精华》

如许看起来确切有些别扭,那能不能让物体垂直于途径举行活动呢?

有的,根据 rotate 属性值,一共有 3 个值可供挑选。

  • auto:让物体垂直于途径的切线方向活动。不过,如果你的途径是闭合曲线的话,须要注重起始点的位置。

比方:

《SVG 动画精华》

  • auto-reverse:让物体垂直于途径的切线方向并 + 180°。也就是和 auto 活动关于切线对称。

《SVG 动画精华》

  • Number:让物体以牢固的扭转角度活动。这个就相当于应用 transform:rotate(deg) 举行掌握。

在动画设置标签中,另有一个更简朴的–set

set

该标签也是用来模仿 transition 效果的。它和 animate 的重要区别是,它仅仅须要 to 的指定属性,而不须要其他的参考属性,比方 fromby 等。那它有啥迥殊的存在意义吗?

有的,因为 set 针关于一切属性,以至包含 style 内里的相干 CSS 属性。所以,可以靠它来很好形貌一些非 number 的属性值。

<text text-anchor="middle" x="60" y="60" style="visibility: hidden;">
  <set attributeName="visibility" attributeType="CSS"
    to="visible" begin="4.5s" dur="1s" fill="freeze"/>
  All gone!
</text>

矩阵动画

上面差不多简朴论述了关于 SVG 一些比较有特性的动画。固然,另有比较重要的线条动画,这个我们放到背面举行解说。这里先来看一下一切动画中,异常重要的矩阵原理。线性代数应当是大学内里来讲,最容易学的一门科目,MD。。。还记得,大学线代期末考试的时刻,100 分的同砚应当说是如韭菜地般,一抓一大片(对不起,我没能和他们与世浮沉。)

那矩阵是如安在动画中应用的呢?

简朴的说,矩阵中的每一个元素实在可以等价代换为每一个因式内里的系数:

《SVG 动画精华》

上面也叫作 三维矩阵。即,它触及到 x,y,z 轴的盘算。那关于我们平面 2D 变更来讲,那末此时矩阵又是哪一种情势呢?

很简朴,只需将 z 轴永久置为一个常数就 OK。这里,通例上是直接取 0 0 1 来设置。

《SVG 动画精华》

不信的话,人人只需代进去乘以乘,应当就可以获得效果了。所以,在二维中,细致变更体式格局为:

《SVG 动画精华》

背面,我们也会根据这个公式举行相干的变形操纵。那矩阵变更是怎样应用到 CSS/SVG 当中呢?

在 CSS 中,是直接应用 transform 中的属性:

transform: matrix(a,b,c,d,e,f);

固然,在 SVG 中也是一样的:

<g transform="matrix(1,2,3,4,5,6)">
    <line x1="10" y1="20" x2="30" y2="40" style="stroke-width: 10px; stroke: blue;"/>
  </g>

所以,我们重要的重点就是解说一下 matrix 这个属性。它的花样为:

matrix(a,b,c,d,e,f);

对应于我们上面的公式有:

《SVG 动画精华》

在打仗 transform 的时刻,人人应当相识到 transform 内里有许多牢固的动画属性:

  • translate()

  • rotate()

  • scale()

  • skew()

现实上,在底层照样应用 matrix 完成的变更。就拿 translate 举个例子吧。

translate 的花样为:

translate(dx,dy)

相当于参考当前原点,在 x/y 轴上挪动 dx/dy 的距离。那末映射到矩阵,应当怎样示意呢?

很简朴,它等同于:

matrix(1 0 0 1 dx dy);

应用代数证实一下:

假定有 matrix(1 0 0 1 20 30)

变成矩阵为:

《SVG 动画精华》

根据,上面的表达式有:

X = x'*1 + y'*0 + 20 = x' + 20
Y = x'*0 + y'*0 + 30 = y' + 30

所以,就是 X 在原有 X 轴坐标上向右挪动 20 的距离,Y 相关于原有挪动 30 的距离。

那末其他几个属性呢?也是怎样变化的吗?

恩,相似。只是内里取值不一样:

  • scale(x,y): 放大 X/Y 轴,矩阵的表达为 matrix(x 0 0 y 0 0)。

  • rotate(θ): 坐标扭转,矩阵的表达为 matrix(cosθ sinθ -sinθ cosθ 0 0)。

  • skew(θx,θy): X/Y 轴拉伸,矩阵的表达为 matrix(1 tanθx tanθy 1 0 0)。

注重,上面三个都邑转变原有物体的坐标系!!! 这点很重要,换句话说,背面每次变更都是基于前面一个的变更效果的。

概况看图:

《SVG 动画精华》

概况可以参考:MDN matrix

不过,这并非我们应用 matrix 的重点,也不是它的上风。它的上风在于可盘算,即,可以将庞杂的动画集合到一个表达式中,而且,后续的变更可以直接基于当前的 matrix。

我们先来相识一下,如果多个变更动画一同应用,matrix 应当怎样表达呢?

只须要找到我们变更动画对应的矩阵,然后相乘即可。比方,先扭转 45°,然后放大 1.5 倍,则有变更动画为:

transform: rotate(45deg) scale(1.5,1.5);

注重,虽然,你定义动画是离开的,但此时的动画是同时举行的。为啥?因为,这两个动画现实上可以整合成为一个变更矩阵:

《SVG 动画精华》

而且,位置是不可以换取的。比方,transform: scale(2,2) translate(20px,30px)。即,你先放大两倍,然后挪动 20,30 的距离。注重,这里挪动的 20,30 相对的是已放大事后的坐标,相关于原坐标而言就是 40,60 了。 如果,你换取位置,即 transform: translate(20px,30px) scale(2,2)。就变成如今原坐标挪动 20,30,然后再放大两倍。

而上面强调的递次关联,现实上就可以明白为矩阵不满足交流律的准绳。因为一旦交流,效果极可能不一样。

矩阵高等用法

上面的内容只是简朴的形貌了关于矩阵的观点。在现实中,矩阵可以说是真正利器。

假定如今有一个动画,请求你将一个物体从一个点经由历程抛物线的体式格局挪动到别的一个点,那末此时请求 JS/CSS 随你挑。此时,你会不会觉得,呼吸短促,头脑发热呢?

恩,matrix 可以治,而且包治百病。不过,matrix 有一个限定点,它只能用于一次线性动画表达式。即,针关于抛物线,椭圆曲线这类庞杂曲线来讲,不太适宜。那末有什么方法吗?

有的,微分头脑。每一段动画实在都可以经由历程肯定局限内的直线拼接而成,那末如许,我们就可以将一段抛物线拆分为由几段线段组成的曲线。固然,如果你分的越细,拟合度就越高。这里我们不盘算过分你和,我们简朴的将一段抛物线分为 5段。

如图:

《SVG 动画精华》

那末接下来就是抠细节。这里,顺次取倾角为 45°,30°,0°,-45°,-30° 这 5 段直线。每段分派的时候比例为 20%、25%、10%、25%、20% 这主如果用于 keyframe 的设定。如今,用数学来剖析一下,这个动画究竟该怎样弄。

如今,已知两点之间的距离为 100px。那末我们一样根据上述比例分,则有 20px, 25px, 10px, 25px, 20px。

这里我们以 45° 倾角为参考点,则尽头坐标为 (20,20); 。那末,该段的矩阵为:

// 注重 Y 轴须要取负值!

 1 0 20
 0 1 -20
 0 0 1

CSS 中的变形动画为:

transform: matrix(1,0,0,1,20,-20);

然后,第二段就为:

1 0 25
0 1 -14.4
0 0 1

应用矩阵的乘法法,则有:

 1 0 45
 0 1 -34.4
 0 0 1

变形动画为:

transform: matrix(1,0,0,1,45,-34.4);

盈余几段也是如许的做法。终究,全部 keyframe 就应当示意为:

@keyframe Parabola{
    20%{
        transform: matrix(1,0,0,1,20,-20);
    }
    45%{
        transform: matrix(1,0,0,1,45,-34.4);
    }
    ...
}

全部动画历程差不多都是如许。固然,矩阵也不单单议局限于这几个动画,凭借著高度定制化和灵活性的特性,这它还经常用于举行回弹,弹跳等动画中。如果人人有兴致,后期也可以对这类动画举行简朴的解说。

背面,我们末了来相识一下 SVG 中很重要的线条动画。

线条动画

SVG 中的线条动画经常用作过渡屏(splash screen)中。比方:

《SVG 动画精华》

或许,一些比较炫酷的 LOGO 中,比方 AllowTeam 的:

《SVG 动画精华》

看到这些炫酷的效果,人人有无动心想学一学,看看本身究竟可否做的这么好呢?

OK,我们如今来正式引见一下线条动画。在 SVG 中,最长用到的线条标签就是 Path。这里我前面一篇文章已做了引见,我这里就不赘述了。

而在细致变化当中用到的是关于 stroke 的相干属性:(下面的属性都可以直接用在 CSS 当中!)

  • stroke*:定义笔触的色彩。比方:stroke="green"

  • stroke-dasharray*:定义 dash 和 gap 的长度。它主如果经由历程应用 , 来离开 实线距离 的值。比方:stroke-dasharray="5, 5" 示意,根据 实线为 5,距离为 5 的排布反复下去。如下图:

《SVG 动画精华》

放大看有:

《SVG 动画精华》

别的,stroke-dasharray 并不局限于只能设置两个值,要知道,它本身的寄义是设置最小反复单位,即,dash,gap,dash,gap...。比方,我定义 stroke-dasharray="15, 10, 5" 则相当于,[15,10,5] 为一段。则有:

《SVG 动画精华》

放大看则有:

《SVG 动画精华》

  • stroke-dashoffset*: 用来设置 dasharray 定义实在 dash 线条最先的位置。值可认为 number || percentage。百分数是相关于 SVG 的 viewport。平常连系 dasharray 可以完成线条的活动。

  • stroke-linecap: 线条的端点款式。

  • stroke-linejoin: 线条衔接的款式

  • stroke-miterlimit: 一个比较庞杂的观点,如果我们只是画一些平常的线段,应用上面 linejoin 即可。如果触及对边角请求比较高的,则可以应用该属性举行定义。它的值,实在就是角长度比上线宽:

《SVG 动画精华》

而现实明白的话,就是假定当 width 为 1。此时比例为 2。那末 miter = 2。那末凌驾 2 的 miter 部份则会被 cut 掉。可以参照:

《SVG 动画精华》

他主如果合营 linejoin 一同应用。因为 linejoin 默许取值就是 miter。所以,默许情况下就可以应用该标签属性。它默许值为 4。其他的人人下去实践一下即可。细致可以参考: miter

  • stroke-opacity:线段的透明度

  • stroke-width:线的粗细。

OK,引见完关于 path 的一切 stroke 属性以后,我们就要最先动手写一下让线条动起来的代码。简朴来讲,就是经由历程 stroke-dashoffsetstroke-dasharray 来做。全部动画可以分为两个历程:

  • 经由历程 dasharray 将实线部份隐蔽,空余为全线段长。然后,将实线部份增添至全长。比方:dasharray: 0,1000 变成 dasharray: 1000,1000

  • 同时,经由历程 dashoffset 来挪动新增的实线部份,形成线段挪动的效果。有: dashoffset:0,变成 dashoffset:1000

不过,这里我们不盘算应用 Path 来做啥庞杂的动画,这重要考虑到手头没有一些 SVG 生成东西。所以,这里我们就以 Text 来做吧(因为做起来真的简朴)。

这里,先以 IV-WEB 这段笔墨来做动画。

先给人人看一下终究效果:

《SVG 动画精华》

那末这类动画是怎样做的呢?

这里,我重要引见一下关于 CSS 相干,SVG 就一个 Text 我直接贴代码了:

<svg viewBox="0 0 1320 300">

  <!-- Symbol -->
  <symbol id="s-text">
    <text text-anchor="middle"
          x="50%" y="50%" dy=".35em">
      IV-WEB
    </text>
  </symbol>  

  <!-- Duplicate symbols -->
  <use xlink:href="#s-text" class="text"
       ></use>
  <use xlink:href="#s-text" class="text"
       ></use>
  <use xlink:href="#s-text" class="text"
       ></use>
 

</svg>

上面是经由历程建立一个居中定位的字体,然后应用 3 个 text 堆叠。细致 CSS 我们下面来讲一下。起首,我们营建的效果是从无到有,就须要应用 dasharray 将 gap 设置的足够大。这里我取 300 即可。

stroke-dasharray: 0 300;

然后,经由历程 nth-child 挑选器,给每一个笔墨应用差别的色彩值:

.text:nth-child(3n + 1) {
  stroke: #F60A0A;
}
.text:nth-child(3n + 2) {
  stroke: #F2FF14;
}

.text:nth-child(3n + 3) {
  stroke: #FB9505;
}

下面才是重点内容。此时,这 3 个 text 的起始点重合。我如今既要他们在运行时不完全重合,又要他们的线条能举行转动。不烦琐了,直接看代码吧:

@keyframes stroke {
  100% {
    stroke-dashoffset: 1000;
    stroke-dasharray: 80 160;
  }
}

@keyframes stroke1 {
  100% {
    stroke-dashoffset: 1080;
    stroke-dasharray: 80 160;
  }
}


@keyframes stroke2 {
  100% {
    stroke-dashoffset: 1160;
    stroke-dasharray: 80 160;
  }
}

这就是上面 3 个差别的 text 应用的动画。dashoffet 由 0 到 1000。这完成了转动的目标。同时,为了让字体不重合,我还须要在对应字体的 dashoffset 上,加上差别的距离距离。比方,第一个字体 offset 为 1000。那末第二个字体,我须要加上前一个字体 dash 的长度,即,80。所以,第二个字体就变成 1080。那末第三个就是加上前两个的 dash 长度,即 1160

大抵历程就是如许,概况可以检察: IVWEB 线条动画

这里再给人人安排一个演习功课,怎样完成无线一连的分段动画呢?

细致效果如图:

《SVG 动画精华》

给点提醒:

将多个笔墨堆叠,取差别的 offset 和 array 即可。动画的停止位置平常取一个 gap + dash 的周期长即可。

背面看看这篇文章回响怎样,到时刻再决议是不是再写一篇续集,引见该功课的原理。

SVG 笔墨

在 SVG 中定义笔墨直接应用 text 标签即可。关于笔墨来讲,平常而言须要注重的点就那末即可,笔墨的分列,间距等等。这些都可以直接应用 CSS 举行掌握。不过,有几个属性比较特别,这里须要分外提一下。

text-anchor

用来定义参考点和现实字符之间的定位关联。花样为:

  • text-anchor: start | middle | end | inherit

直接看代码诠释吧:

<!-- Anchors in action -->
    <text text-anchor="start"
          x="60" y="40">A</text>

    <text text-anchor="middle"
          x="60" y="75">A</text>

    <text text-anchor="end"
          x="60" y="110">A</text>

第一个 A,参考的是 (60,40) 的点,定义为 start ,那末参考点应当在字符的前面。

《SVG 动画精华》

而剩下两个也是一样的原理:

《SVG 动画精华》

tspan

如今,如果我们想在 text 内里增添一些特别的字符效果,比方斜体,加粗等。因为,text 标签不能完成嵌套,所以,为相识决这个痛点,提出了 tspan 的标签。它实在就是一个可以嵌套的 text 标签。

<text x="10" y="30" style="font-size:12pt;">
  Switch among
  <tspan style="font-style:italic">italic</tspan>, normal,
  and <tspan style="font-weight:bold">bold</tspan> text.
</text>

tspan 内里一样可以自定义相干的本身属性。细致的可以参考 tspan 我这里就不详述了。

在 Path 展现 text

Text 平常可以横放,竖放。那有无啥方法让笔墨可以根据肯定的途径恣意排放呢?

有的,这里可以应用 textPath 标签,来定义细致参考途径。

<path id="sharp-corner"
    d="M 30 110 100 110 100 160"
    style="stroke: gray; fill: none;"/>

<text>
    <textPath xlink:href="#sharp-corner">
    Making a quick turn
    </textPath>
</text>

如图:

《SVG 动画精华》

细致细节我这里就不多说了。

Clip

在 DOM 中如果想展现一个图片的部份,或许以某种外形展现图片的部份,平常是经由历程一个 cover div 来完成的。不过,如果触及到不规则图形的话,那末 DOM 就有生成缺点了(固然应用 CSS 里的 clip-path 可以完成,不过兼容性不太好)。而在 SVG 中,供应了 clipPath 标签,可以让我们自定义裁剪图片的局限和外形。

clipPath 内里可以接任何图形,比方,path,rect 以至是 text。应用的时刻,直接在 style 中,指定 clip-path 即可,或许直接应用 clip-path 属性指定。

<defs>
  <clipPath id="textClip">
    <text id="text1" x="20" y="20" transform="rotate(60)"
      style="font-family: 'Liberation Sans';
        font-size: 48pt; stroke: black; fill: none;">
CLIP
    </text>
  </clipPath>
 </defs>
 
 <use transform="translate(100, 0)"
  xlink:href="#shapes" style="clip-path: url(#textClip);"/>
  
   <use transform="translate(100, 0)"
  xlink:href="#shapes" clip-path="url(#textClip);"/>

《SVG 动画精华》

或许说,如果我们想画一个圆的裁剪地区的话:

<defs>
     <clipPath id="circularPath" clipPathUnits="objectBoundingBox">
     <circle cx="0.5" cy="0.5" r="0.5"/>
    </clipPath>
</defs>

<use xlink:href="#shapes" style="clip-path: url(#circularPath);" />

Appendix 参考标签

g

分组标签应当毫无意外排第一,因为实在作为绘制图形中最常和最基础的标签。前面一篇文章也重要引见过了,这里做点补充。

每一个分组标签都带有 id 属性,唯一标识该分组,为何呢?

因为,背面我们可以应用该 id 标签增添动画,重用该分组等。

<g id="demo" stroke="green" fill="white" stroke-width="5">
     <circle cx="25" cy="25" r="15"/>
     <circle cx="40" cy="25" r="15"/>
     <circle cx="55" cy="25" r="15"/>
     <circle cx="70" cy="25" r="15"/>
   </g>

每一个分组内里可以含有一些形貌标签,比方 desc。 这些形貌内容是不会被衬着的。

<g id="demo" stroke="green" fill="white" stroke-width="5">
    <desc>Just Demo</desc>
     <circle cx="25" cy="25" r="15"/>
   </g>

use

该标签就是连系 g 标签一同应用,作用是可以复用 g 分组的款式。

<g id="Port">
      <circle style="fill: inherit;" r="10"/>
</g>
<use x="50" y="30" xlink:href="#Port" class="classA"/>

内里应用 xlink:href 加上指定 group 的 id,然后经由历程 xy 属性指定副本安排的位置。不过,有一个限定,use 标签的 style 属性,并不能掩盖点原始的 group style 款式。而且,有时刻,我们只是想应用一些模板,即,图形并未被剖析,只要代码存在。这时刻,就须要应用 defs 来包裹了。

defs

用来保留一些代码,使其不会被浏览器剖析。而且内里的分组可以被 use 属性的 style 款式所掩盖。

<defs>
    <g id="Port">
      <circle style="fill: inherit;" r="10"/>
    </g>
  </defs>

 <use x="50" y="50" xlink:href="#Port" style="fill: blue;"/>

symbol

该标签和 g 标签相似,也是用来举行分组。不过,它有个特性,即,不会被浏览器所衬着。那它不和 defs 差不多吗?

恩,确切。不过,defs 是官方引荐,用来包裹一些模板 svg 代码而制造出来,用来增添可读性的标签。而 symbol 是存粹的作为一个模板。它可以独立于 svg 的 viewbox 来自定义子 viewbox 和 preserveAspectRatio。

<symbol id="sym01" viewBox="0 0 150 110">
  <circle cx="50" cy="50" r="40" stroke-width="8"
      stroke="red" fill="red"/>
  <circle cx="90" cy="60" r="40" stroke-width="8"
      stroke="green" fill="white"/>
</symbol>

<use href="#sym01"
     x="0" y="0" width="100" height="50"/>

一样应用该模板,也是应用 use 标签来完成。

image

既然 use 可以重用 SVG 代码,那末 SVG 内里能不能重用已画好的 png/jpg 的图片呢?

这时刻,就须要用到 image 标签。其可以用来加载外部的 PNG, JPEG 图片,注重,官方规定是前两种,别的图片支撑不支撑官方没做回复。即,如果你应用 GIF 图片,并不能保证一切的浏览器都能一般显现。

<image xlink:href="kwanghwamun.jpg"
  x="72" y="92"
  width="160" height="120"/>
</svg>

一样,该 image 标签也具有自定义 preserveAspectRatio 的效果。

  • x: 定义程度位置

  • y: 定义垂直位置

  • width: 图片衬着的宽度,必须有。

  • height: 图片衬着的高度,必须有。

  • preserveAspectRatio: 掌握图片的缩放

marker

marker 平常是用来画箭头或许线段委曲的标识图形。

<defs>
    <marker id="Triangle" viewBox="0 0 10 10" refX="1" refY="5"
        markerWidth="6" markerHeight="6" orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" />
    </marker>
  </defs>

  <polyline points="10,90 50,80 90,20" fill="none" stroke="black" 
      stroke-width="2" marker-end="url(#Triangle)" />

如图:

《SVG 动画精华》

这里我们只须要里相识即可,因为在现实画的时刻,直接应用相干东西生成越发轻易。

a

这里的 a 标签和我们直接在 HTML 应用的超链接 a 标签相似。也是用来定义一个外链的。

<a xlink:href="https://developer.mozilla.org/en-US/docs/SVG"
      target="_blank">
    <rect height="30" width="120" y="0" x="0" rx="15"/>
    <text fill="white" text-anchor="middle" 
          y="21" x="60">SVG on MDN</text>
  </a>

个人民众号

更多内容,可以关注我的民众号:前端小吉米。

分享吉米的前端路,背面也会按期推出当前热点的前端手艺~ 比方,直播,VR

《SVG 动画精华》

    原文作者:villainhr
    原文地址: https://segmentfault.com/a/1190000009378881
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞