本文主要是讲解关于 SVG 的一些高级动画特效,好比 SVG 动画标签,图形渐变,路径动画,线条动画,SVG 裁剪等。html
例如:路径动画前端
图形渐变:浏览器
线条动画:markdown
以及,相关的动画的矩阵知识,这个也是如今 CSS 动画里面最重要,同时也是最为欠缺的知识点:svg
文章会先从基本语法入手,而后,慢慢深刻。介绍一些动画基本原理和对应的数学原理知识点。而且文章后面,还附有相关语法的介绍,当你在遇到不熟悉语法的时候能够参考参考。工具
前面一篇文章,主要介绍了一些 SVG 的基本概念和基本图形。接下来咱们须要了解一下,SVG 处理矢量这个特性以外,还有啥内容吸引咱们,能让 SVG 如今普及度这么高?oop
完整版能够关于个人公众号:前端小吉米。字体
分享吉米的前端路,后面也会按期推出当前热门的前端技术~ 好比,直播,VR动画
在 SVG 中,若是咱们想实现一个动画效果,可使用 CSS,JS,或者直接使用 SVG 中自带的 animate
元素添加动画。ui
使用 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 中的 morph 的效果。
该效果主要作的就是图形内部的渐变。如图:
这种动画是怎么实现呢?
直接看代码吧:
<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
中的 keyTimes
,calcMode
,keySplines
,以及 values
这几个属性。不急,咱们一个一个来解释一下。
@keyframes
同样。经过 0-1 之间的值,定义每段动画完成的时间。格式为:value;value...
。例如 0;.0625;.208333333;.3125;.395833333;.645833333;.833333333;1
。从第一个动画,到第二个动画经历的时间比例为 6.25%。而且,keyTimes 须要和 values 里面定义的帧数一致。discrete | linear[default] | paced | spline
。具体能够参考 MDN。这里咱们主要介绍一下 spline。该值表示每一个动画间使用自定的贝塞尔变换曲线。若是没有特殊要求,使用 linear 其实已经足够了,这样就不用麻烦去定义下面的 keySplines
属性。;
来分隔每个值。即,cubic-bezier(.31,.57,.93,.46)
为一组。使用 keySplines 表达,则为:keySplines = ".31,.57,.93,.46;"
。固然,里面的贝塞尔曲线组数为 整个动画帧数 - 1
。而 values 就很简单了。它是直接结合 attributeName
属性,来设置具体的值,每一个值之间使用 ;
进行分隔。
像上面那样,能够在指定元素里面嵌套多个 animate,既实现了形状的改变,又实现了颜色的改变。Morph 比较经常使用于数字的更迭,好比,倒数 10s 的相关动画。到这里,Morpah 相关的知识点就结束了。
接着,让咱们来看一下 SVG 中,另一很是重要的标签 – animateMotion
。
该标签可让指定的元素,绕着指定的路径进行运动。因此这对于复杂的路径来讲很是有用,由于咱们很难使用 transform 去模拟复杂的变换路径。看一个 DEMO
animateMotion 大体的属性和 animate
差很少,不过,它还拥有本身特有的属性,好比 keyPoints
、rotate
、path
等。不过,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>
复制代码
freeze
和 remove
效果。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>
复制代码
动画效果为:
因此,通常而言咱们在定义 AM 的路径的时候,只用一种方式定义便可,不然会发生相应的覆盖:mpath
>path
>values
>from/to
。
在 AM 运动中,还有一个很重要的概念就是旋转角。默认状况下,运动物体的角度是按照它和坐标轴的初始角度肯定的。例如:
这样看起来确实有些别扭,那能不能让物体垂直于路径进行运动呢?
有的,根据 rotate
属性值,一共有 3 个值可供选择。
例如:
在动画设置标签中,还有一个更简单的–set
。
该标签也是用来模拟 transition
效果的。它和 animate
的主要区别是,它仅仅须要 to
的指定属性,而不须要其余的参考属性,好比 from
,by
等。那它有啥特别的存在乎义吗?
有的,由于 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 分的同窗应该说是如韭菜地般,一抓一大片(对不起,我没能和他们同流合污。)
那矩阵是如何在动画中使用的呢?
简单的说,矩阵中的每一个元素其实能够等价代换为每一个因式里面的系数:
上面也叫做 三维矩阵。即,它涉及到 x,y,z 轴的计算。那对于咱们平面 2D 变换来讲,那么此时矩阵又是哪一种形式呢?
很简单,只要将 z 轴永远置为一个常数就 OK。这里,惯例上是直接取 0 0 1 来设置。
不信的话,你们只要代进去乘以乘,应该就能够获得结果了。因此,在二维中,具体变换方式为:
后面,咱们也会依据这个公式进行相关的变形操做。那矩阵变换是怎么运用到 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);
复制代码
对应于咱们上面的公式有:
在接触 transform
的时候,你们应该了解到 transform
里面有不少固定的动画属性:
实际上,在底层仍是使用 matrix 实现的变换。就拿 translate 举个例子吧。
translate 的格式为:
translate(dx,dy)
复制代码
至关于参考当前原点,在 x/y 轴上移动 dx/dy 的距离。那么映射到矩阵,应该如何表示呢?
很简单,它等同于:
matrix(1 0 0 1 dx dy);
复制代码
使用代数证实一下:
假设有 matrix(1 0 0 1 20 30)
变为矩阵为:
根据,上面的表达式有:
X = x'*1 + y'*0 + 20 = x' + 20
Y = x'*0 + y'*0 + 30 = y' + 30
复制代码
因此,就是 X 在原有 X 轴坐标上向右移动 20 的距离,Y 相对于原有移动 30 的距离。
那么其余几个属性呢?也是怎么变化的吗?
恩,相似。只是里面取值不同:
注意,上面三个都会改变原有物体的坐标系!!! 这点很重要,换句话说,后面每次变换都是基于前面一个的变换结果的。
详情看图:
详情能够参考:MDN matrix
不过,这并非咱们使用 matrix 的重点,也不是它的优点。它的优点在于可计算,即,可以将复杂的动画集合到一个表达式中,而且,后续的变换能够直接基于当前的 matrix。
咱们先来了解一下,若是多个变换动画一块儿使用,matrix 应该如何表达呢?
**只须要找到咱们变换动画对应的矩阵,而后相乘便可。**例如,先旋转 45°,而后放大 1.5 倍,则有变换动画为:
transform: rotate(45deg) scale(1.5,1.5);
复制代码
注意,虽然,你定义动画是分开的,但此时的动画是同时进行的。为啥?由于,这两个动画实际上能够整合成为一个变换矩阵:
而且,位置是不能够调换的。好比,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段。
如图:
那么接下来就是抠细节。这里,依次取倾角为 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)中。例如:
或者,一些比较炫酷的 LOGO 中,好比 AllowTeam 的:
看到这些炫酷的效果,你们有没有动心想学一学,看看本身到底可否作的这么好呢?
OK,咱们如今来正式介绍一下线条动画。在 SVG 中,最长用到的线条标签就是 Path
。这里我前面一篇文章已经作了介绍,我这里就不赘述了。
而在具体变化当中用到的是关于 stroke
的相关属性:(下面的属性均可以直接用在 CSS 当中!)
stroke="green"
,
来分隔 实线 和 间隔 的值。例如:stroke-dasharray="5, 5"
表示,按照 实线为 5,间隔为 5 的排布重复下去。以下图:放大看有:
另外,stroke-dasharray 并不局限于只能设置两个值,要知道,它自己的含义是设置最小重复单元,即,dash,gap,dash,gap...
。好比,我定义 stroke-dasharray="15, 10, 5"
则至关于,[15,10,5] 为一段。则有:
放大看则有:
number || percentage
。百分数是相对于 SVG 的 viewport。一般结合 dasharray 能够实现线条的运动。而实际理解的话,就是假设当 width 为 1。此时比例为 2。那么 miter = 2。那么超过 2 的 miter 部分则会被 cut 掉。能够参照:
他主要是配合 linejoin
一块儿使用。由于 linejoin 默认取值就是 miter
。因此,默认状况下就可使用该标签属性。它默认值为 4。其他的你们下去实践一下便可。详细能够参考: miter
OK,介绍完关于 path 的全部 stroke 属性以后,咱们就要开始动手写一下让线条动起来的代码。简单来讲,就是经过 stroke-dashoffset
和 stroke-dasharray
来作。整个动画能够分为两个过程:
dasharray: 0,1000
变为 dasharray: 1000,1000
。dashoffset:0
,变为 dashoffset:1000
。不过,这里咱们不打算使用 Path 来作啥复杂的动画,这主要考虑到手头没有一些 SVG 生成工具。因此,这里咱们就以 Text 来作吧(由于作起来真的简单)。
这里,先以 IV-WEB 这段文字来作动画。
先给你们看一下最终结果:
那么这种动画是怎么作的呢?
这里,我主要介绍一下关于 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 线条动画。
这里再给你们布置一个练习做业,如何实现无线连续的分段动画呢?
具体效果如图:
给点提示:
将多个文字重叠,取不一样的 offset 和 array 便可。动画的终止位置通常取一个 gap + dash 的周期长便可。
后面看看这篇文章反响如何,到时候再决定是否再写一篇续集,介绍该做业的原理。
在 SVG 中定义文字直接使用 text
标签便可。关于文字来讲,通常而言须要注意的点就那么便可,文字的排列,间距等等。这些均可以直接使用 CSS 进行控制。不过,有几个属性比较特殊,这里须要额外提一下。
用来定义参考点和实际字符之间的定位关系。格式为:
直接看代码解释吧:
<!-- 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
,那么参考点应该在字符的前面。
而剩下两个也是一样的道理:
如今,假如咱们想在 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 我这里就不详述了。
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>
复制代码
如图:
具体细节我这里就很少说了。
在 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);"/>
复制代码
或者说,若是咱们想画一个圆的裁剪区域的话:
<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);" />
复制代码
分组标签应该毫无心外排第一,由于其实做为绘制图形中最常和最基本的标签。前面一篇文章也主要介绍过了,这里作点补充。
每个分组标签都带有 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>
复制代码
该标签就是结合 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,而后经过 x
,y
属性指定副本放置的位置。不过,有一个限制,use 标签的 style 属性,并不能覆盖点原始的 group style 样式。并且,有时候,咱们只是想使用一些模板,即,图形并未被解析,只有代码存在。这时候,就须要使用 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;"/>
复制代码
该标签和 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
标签来完成。
既然 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 的效果。
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)" />
复制代码
如图:
这里咱们只须要里了解便可,由于在实际画的时候,直接使用相关工具生成更加方便。
这里的 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