SVG 入门学习笔记 (1W字)
最近因为公司业务需要,需要做大屏可视化组件,技术库D3.js,翻阅D3.js官方文档,也是基于SVG的,那就从SVG开始入坑吧!!
ps:感觉可视化的东西都好麻烦好麻烦
无聊的概念
图形系统
我们的计算机有两种图形系统: 栅格图形 和 矢量图形 。
- 栅格图形系统就是那种越放大越模糊的图片。
- 矢量图形就是怎么放大都好清晰的辣种。 (比如这个炸鸡emoji)。用官方的回答翻译过来就是: 矢量图形中图形被描述为一系列几何形状,通过矢量图形阅读器在指定的坐标集上绘制形状。
SVG(Scalable Vector Graphics)可拓展矢量图形
看这名字又能 拓展 又是 矢量 ,很高端有没有 。
矢量是什么,上面提到啦,怎么放大都很清晰。
SVG是一种XML应用(XML啊,就是跟HTML差的多 的一种 标记语言 ),用来表示矢量图形。
SVG所有的图形有关信息被存储为 纯文本 ,因为SVG也是XML的一种应用嘛,所以理应继承XML的开放性、可移植性和可交互性。
所以到此我们应该懂啦,SVG就是定义了一些图形信息,比如坐标啥的,然后浏览器会根据这些坐标去进行绘制。
举个栗子 :像emoji这种,有时候有没有发现,你在输入法点的emoji跟显示的不一样,其实它发的就是一段编号,然后浏览器在字体里面找,但是每个电脑装的字体不一定一样,所以就显示出来有差异啦。
所以SVG保存的也是定义的信息,并不是用图像进行传输。
开始使用SVG
如果此时设计师给了一个SVG图片,怎么使用嘞~~
将SVG作为图像
<img src="./404.svg" alt="404" />
将svg作为图像包含在HTML标记的img元素内,但是这样有一定的局限性:SVG转为栅格图像时与主页面分离(也就是会分开渲染 ),并且无法在两者之间通信(SVG渲染过程与主页面独立)。
主页面上的样式对SVG无效,运行在主页面上的脚本无法感知或者修改SVG文档结构。
将SVG作为应用程序
<html>
<object type="image/svg+xml" data="MySVG.svg"
width="300" height="200">
</object>
</body>
</html>
使用object元素将SVG嵌入HTML文档中,object元素的type属性表示要嵌入的文档类型,对用SVG应该是type="image/svg+xml"。object元素必须有起始标签和结束标签,这两个标签之间的内容为对象数据本身不能被渲染时显示。
感觉这种用不上啊有没有
或者直接把svg放到html里也行
<html>
</svg>
</body>
</html>
坐标系统
视口
视口代表文档想使用的区域,用width和height确当视口大小,单位可以仅仅是数字也可以是带单位的数字
<html>
<svg width="200" height="100">
</svg>
</body>
</html>
默认用户坐标
SVG会设置坐标系统,原点(0,0)位于视口的左上角,x从左向右依次递增,y从上到小依次递增。
SVG的元素的单位可以不统一。(看下面的示例代码 )
<svg width="600" height="300" style="outline: 5px solid #e6e6e6">
//x y 设定位置
<rect x="10px" y="10px" width="10" height="10" fill="blue" />
<rect x="4em" y="1em" width="10" height="10" fill="pink" />
<rect x="10" y="50" width="10" height="10" fill="yellow" />
</svg>
指定用户坐标
可以自己为视口设置坐标系,通过SVG元素上的viewBox属性。viewBox分别代表叠加再坐标系上的四个属性
viewBox( minX, minY, width, height)
那么如何使用嘞,举个栗子 :
比如定义了一个圆形,
<svg width="300" height="300" style="outline: 5px solid #e6e6e6">
<circle cx="200" cy="200" r="200" fill="#fdd" stroke="none"></circle>
</svg>
如果是在一个400*400的画布上,圆正好撑满整个画布,挺好的。
好了,然后我要把这个圆嵌入到自己的页面里的svg标签里去,页面的svg标签尺寸是由实际业务需要来定的,不一定正好是,可能大可能小,还可能不是正方形。(比如上图是300*300的正方形)
可以看到圆形都没显示完全,这该怎么办呢
svg尺寸不能更改,那就到了viewBox的用武之地了 嘿嘿
<svg width="300" height="300" viewBox="0 0 400 400" style="outline: 5px solid #e6e6e6">
<circle cx="200" cy="200" r="200" fill="#fdd" stroke="none"></circle>
</svg>
圆变小了,展示全了,还垂直居中了。 nice
viewBox的四个参数分别代表:最小X轴数值;最小y轴数值;宽度;高度。
前两个暂时用不到,个人理解除非要对内部svg做整体位移,否则一般都是0 0,暂时先不做解释,重点关注后两个参数。
想象一下viewBox是个400*400的正方形,但是单位不是px,也不是任何一个css单位,就当是一个假的单位吧。在viewBox放了一个圆,这个圆的半径是200,单位也不是px,而是变成了和viewBox的单位一模一样的那个假的单位。为啥说是假的呢?因为这个单位代表的长度是会变的,接着看。
svg有个特点,在默认情况下,会调整这个viewBox的大小,让这个viewBox正好能被放进svg里去。拿上面例子来说,viewBox是个正方形,而svg的宽度比高度小,所以就把viewBox的大小缩小到和svg宽度一样,就能正好将viewBox放进svg里来了。所以现在viewBox的实际大小是个150px*150px的正方形。
所以现在可以确定的是,viewBox的一个单位代表的长度 = 150px/400 = 0.375px。 而viewBox内部的所有数值*0.375px才是真正的长度。那个circle的圆心实际上是在坐标75px, 75px的位置上,半径为75px。
圆的具体大小大概就是这么回事。
为了解决SVG视口长宽比例和viewBox定义的长宽比例不同的问题以及如何对齐问题。这个时候就需要preserveAspectRatio属性了。
如果viewBox的比例与视口比例不同,则有三种可能:
-
a. 按较小的尺寸等比例缩放图形,使图形完全填充视口
-
b. 按较大的尺寸等比例缩放图形,病裁减掉超出视口的部分
-
c. 拉伸和压缩绘图以使其恰好填充视口
PreserveAspectRadio 属性
英文直译:维持外观比例。好像还挺语义化 的一属性名。
preserveAspectRatio属性允许指定被缩放的图形相对视口的对齐方式,格式为preserveAspectRatio = "alignment[meet|slice]"
默认值为"xMidYMid meet"
<svg style="width:150px; height:300px" viewBox="0 0 400 400" preserveAspectRatio="xMidYMid meet">
meet 说明符在图形超出视口时候会对图形适当缩小调整适配可用的空间
slice 说明符直接裁剪超出视口的部分
总共有9个值可选:
| ||| |----|----|----| | xMinYMin| xMinYMid | xMinYMax| |xMidYMin |xMidYMid|xMidYMax| |xMaxYMin|xMaxYMid|xMaxYMax|
x和y表示对齐的轴线,min,mid,max表示对齐的方式。min是往坐标小的方向对齐;mid居中对齐;max是往坐标大的方向对齐(顺带一提svg的坐标0刻度在左上角)。
第二个参数有两个值可选:meet和slice meet就是前面那种自动调整viewBox到可以在svg画布中完全展示。非常类似css里background-size:contain 而slice是自动调整viewBox到撑满整个svg画布。非常类似background-size:cover
再回看第二张图里那个垂直居中的圆,就能明白为什么会“圆变小了,展示全了,还垂直居中了”。
还可以指定preserveAspectRatio="none",用于在viewBox和视口宽高比不同时缩放图像,此时图像不会被等比例缩放,会被拉伸、挤压、变形。
参考文章链接
链接: https:// segmentfault.com/a/1190 000009226427?utm_source=tag-newest
基本形状
线段
line元素,使用x1,y1,x2,y2属性指定线段的起止点坐标。
<svg width="300" height="300" style="outline: 5px solid #e6e6e6">
<line x1="50" y1="50" x2="300" y2="300" stroke="crimson" stroke-width="2" />
</svg>
- stroke定义笔画颜色
- stroke-width定义笔画宽度
当然你也可以把以上两个属性写到style里
矩形
rect元素,使用x,y,width,height表示一个矩形
<svg width="300" height="300" style="outline: 5px solid #e6e6e6">
<rect x="50" y="50" width="100" height="50"></rect>
</svg>
圆和椭圆
circle元素表示圆,由cx,cy,r属性界定 ellipse元素表示椭圆,由cx,cy,rx,ry界定
<svg width="300" height="300" style="outline: 5px solid #e6e6e6">
<circle cx="100" cy="100" r="50"></circle>
<svg width="300" height="300" style="outline: 5px solid #e6e6e6">
<ellipse cx="100" cy="100" rx="50" ry="60"></ellipse>
</svg>
多边形
polygon元素指定一个多边形,由points属性指定的一系列坐标点界定,会自动封闭
<svg width="300" height="300" style="outline: 5px solid #e6e6e6">
<polygon points=" 50,50 100,100 30,60" stroke="crimson" stroke-width="2"></polygon>
</svg>
折线
polyline元素表示一个折线,使用points属性指定一系列点,不自动封闭图形。 注意下图红线没有封闭哦
<svg width="300" height="300" style="outline: 5px solid #e6e6e6">
<polyline points=" 50,50 100,100 30,60" stroke="crimson" stroke-width="2"></polyline>
</svg>
特性总结
| 特性 | 说明 | | ---- | ---- | | stroke| 笔画颜色| |stroke-width| 笔画宽度| |stroke-opacity| 笔画不透明度| |stroke-dasharray| 虚线笔画| |stroke-linecap| 笔画头的形状 butt(默认),round,square| |stroke-linejoin| 图形棱角,有miter(默认),round和bevel三个取值| |stroke-miterlimit| 相交处显示宽度与线宽的最大比例,默认为4| |fill |填充颜色 默认black| |fill-opacity|填充不透明度| |fill-rule| 填充规则|
是不是感觉还挺简单哒,继续
文档结构
结构与表现
SVG允许文档表现和文档结构分离(就是跟CSS一样,能写成单独的文件 ),SVG支持四种方式指定表现信息:内联样式、内部样式表、外部样式表(跟CSS一毛一样 )以及表现属性。
- 表现属性 SVG允许以属性的形式指定表现样式,但是表现属性的优先级最低,如果以其他三种形式指定了相同的样式属性,则将覆盖通过表现属性指定的样式
分组和引用
g元素用来将其子元素作为一个组合,可以使文档结构更清晰。除此之外,在g标签中指定的所有样式会应用于组合内的所有子元素,可以不用在所有子元素上指定属性。
举个栗子 :
如上图的鸟的每一部分都是由一个个图形组合而成,而在软件中当需要整体移动时,则需要
在svg中同理,如下代码将bird分为一个大组
<svg width="1144.12px" height="400px" viewBox="0 0 572.06 200">
<style>
svg{background-color:white;}
#wing{fill:#81CCAA;}
#body{fill:#B8E4C2;}
#pupil{fill:#1F2600;}
#beak{fill:#F69C0D;}
.eye-ball{fill:#F6FDC4;}
</style>
<g id="bird">
<g id="body">
<path d="M48.42,78.11c0-17.45,14.14-31.58,31.59-31.58s31.59,14.14,31.59,31.58c0,17.44-14.14,31.59-31.59,31.59
S48.42,95.56,48.42,78.11"/>
<path d="M109.19,69.88c0,0-8.5-27.33-42.51-18.53c-34.02,8.81-20.65,91.11,45.25,84.73
c40.39-3.65,48.59-24.6,48.59-24.6S124.68,106.02,109.19,69.88"/>
<path id="wing" d="M105.78,75.09c4.56,0,8.84,1.13,12.62,3.11c0,0,0.01-0.01,0.01-0.01l36.23,12.38c0,0-13.78,30.81-41.96,38.09
c-1.51,0.39-2.82,0.59-3.99,0.62c-0.96,0.1-1.92,0.16-2.9,0.16c-15.01,0-27.17-12.17-27.17-27.17
C78.61,87.26,90.78,75.09,105.78,75.09"/>
<g id="head">
<path id="beak" d="M50.43,68.52c0,0-8.81,2.58-10.93,4.86l9.12,9.87C48.61,83.24,48.76,74.28,50.43,68.52"/>
<path class="eye-ball" d="M60.53,71.68c0-6.33,5.13-11.46,11.46-11.46c6.33,0,11.46,5.13,11.46,11.46c0,6.33-5.13,11.46-11.46,11.46
C65.66,83.14,60.53,78.01,60.53,71.68"/>
<path id="pupil" d="M64.45,71.68c0-4.16,3.38-7.53,7.54-7.53c4.16,0,7.53,3.37,7.53,7.53c0,4.16-3.37,7.53-7.53,7.53
C67.82,79.22,64.45,75.84,64.45,71.68"/>
<path class="eye-ball" d="M72.39,74.39c0-2.73,2.22-4.95,4.95-4.95c2.73,0,4.95,2.21,4.95,4.95c0,2.74-2.22,4.95-4.95,4.95
C74.6,79.34,72.39,77.13,72.39,74.39"/>
</svg>
use元素用来复用图形中重复出现的元素,需要为use标签的xlink:href指定URI来引用指定的图形元素。同时还要指定x和y属性以表示组合应该移动到哪个位置。use元素并不限制只能使用同一个文件内的对象,xlink:href属性可以指定任何有效的文件或URI。
举个栗子 :
<svg width="1144.12px" height="400px" viewBox="0 0 572.06 200">
<style>
</style>
<g id="bird">
<!--在这使用use-->
<use x="130" y="50" xlink:href="#bird" />
</svg>
引用链接
https:// blog.csdn.net/a46055054 2/article/details/79695747
坐标系统变换
translate变换
translate用来对坐标进行平移,通过制定transform属性值来设置transform=transform(x,y)
<svg width="1144.12px" height="400px" viewBox="0 0 572.06 200" style="outline: 5px solid #e6e6e6">
<style>
svg{background-color:white;}
#wing{fill:#81CCAA;}
#body{fill:#B8E4C2;}
#pupil{fill:#1F2600;}
#beak{fill:#F69C0D;}
.eye-ball{fill:#F6FDC4;}
</style>
<g id="bird">
<g id="body">
<path d="M48.42,78.11c0-17.45,14.14-31.58,31.59-31.58s31.59,14.14,31.59,31.58c0,17.44-14.14,31.59-31.59,31.59
S48.42,95.56,48.42,78.11"/>
<path d="M109.19,69.88c0,0-8.5-27.33-42.51-18.53c-34.02,8.81-20.65,91.11,45.25,84.73
c40.39-3.65,48.59-24.6,48.59-24.6S124.68,106.02,109.19,69.88"/>
<path id="wing" d="M105.78,75.09c4.56,0,8.84,1.13,12.62,3.11c0,0,0.01-0.01,0.01-0.01l36.23,12.38c0,0-13.78,30.81-41.96,38.09
c-1.51,0.39-2.82,0.59-3.99,0.62c-0.96,0.1-1.92,0.16-2.9,0.16c-15.01,0-27.17-12.17-27.17-27.17
C78.61,87.26,90.78,75.09,105.78,75.09"/>
<g id="head">
<path id="beak" d="M50.43,68.52c0,0-8.81,2.58-10.93,4.86l9.12,9.87C48.61,83.24,48.76,74.28,50.43,68.52"/>
<path class="eye-ball" d="M60.53,71.68c0-6.33,5.13-11.46,11.46-11.46c6.33,0,11.46,5.13,11.46,11.46c0,6.33-5.13,11.46-11.46,11.46
C65.66,83.14,60.53,78.01,60.53,71.68"/>
<path id="pupil" d="M64.45,71.68c0-4.16,3.38-7.53,7.54-7.53c4.16,0,7.53,3.37,7.53,7.53c0,4.16-3.37,7.53-7.53,7.53
C67.82,79.22,64.45,75.84,64.45,71.68"/>
<path class="eye-ball" d="M72.39,74.39c0-2.73,2.22-4.95,4.95-4.95c2.73,0,4.95,2.21,4.95,4.95c0,2.74-2.22,4.95-4.95,4.95
C74.6,79.34,72.39,77.13,72.39,74.39"/>
<!--我们在use上使用tranform-->
<use x="1" y="50" xlink:href="#bird" transform="translate(0,0)" />
</svg>
在use上使用translate(0,0),将图像移动到了原图像的中心点上。ps:这说明移动的点基于原图像的中心哒
- 工作原理:首先获取整个表格,然后将其移动到画布的新位置,而不是移动到所在的元素,所以说 移动的是坐标系 而不是元素本身。
scale变换
缩放坐标系统,transform = "scale(value)"或者transform="scale(x-value,y-value)"。
使用scale(n)变换时,网格系统的原点没有改变,只是用户坐标变成了原来的n倍,也就是网格变大了,因此线也会变粗。
<use x="1" y="50" xlink:href="#bird" transform="scale(0.5)" />
可以看到小鸟变小啦
缩放变换永远不会改变图形对象的网格坐标或者笔画宽度,仅仅改变对应画布上的坐标系统网格的大小。
rotate变换
根据指定的角度旋转坐标系统,默认的坐标系统中,角度的测量顺时针增加,0度为3点钟方向。
<use x="1" y="50" xlink:href="#bird" transform="rotate(30,100,100)" />
可以看到小鸟转了30度 哈哈哈
注意 ,除非另行指定,否则旋转以原点为中心。 此时可以通过平移+旋转的方式来指定旋转中心: translate(centerX,centerY) rotate(angle) translate(-centerX,-centerY)
但是有个更简单的方式:rotate(angle,centerX,centerY)
skewX和skewY变换
这两个变换用来倾斜某个轴,一般形式为skewX(angle),skewY(angle)。这样的结果就是使得x轴和y轴不再垂直。
<use x="1" y="50" xlink:href="#bird" transform="skewX(30)" />
矩阵变换
计算机图形学中坐标变换都通过矩阵来实现,除上述变换方法之外,还可以直接为变换指定变换矩阵,变换矩阵为matrix(a,b,c,d,e,f),此时指定的变换矩阵为:
a c e
b d f
0 0 1
<use x="1" y="50" xlink:href="#bird" transform="matrix(2,1,1,0,1,1)" />
矩阵转换依据,参考线性代数哦
路径
Path命令
SVG中所有基本形状都是path的简写形式,但是建议使用简写形式,因为这样可以使SVG文档更可读
path元素更通用,可以通过制定一系列相互连接的线、弧、曲线来绘制任意形状的轮廓,这些轮廓也可以填充或者绘制轮廓线,也可以用来定义裁剪区域或蒙版。
举个例子 :
<svg width="1144.12px" height="400px" viewBox="0 0 572.06 200" style="outline: 5px solid #e6e6e6">
<path d="M150 0 L75 200 L225 200 Z" />
</svg>
参考下面的表,可以看到,它开始于位置150 0,到达位置75 200,然后从那里开始到225 200,最后在150 0关闭路径。 Z = closepath,下面没写
ps:这就可以解释为啥SVG是矢量的了
下表为path命令总结,其中大写表示绝对坐标,小写表示相对坐标:
| 命令 | 参数| 说明| | ---- | ---- | ---- | |M m |x y |移动画笔到制定坐标| |L l| x y| 绘制一条到给定坐标的线| |H h| x |绘制一条到给定x坐标的横线| |V v| y |绘制一条到给定y坐标的垂线| |A a| rx ry x-axis-rotation large-arc sweep x y| 圆弧曲线命令有7个参数,依次表示x方向半径、y方向半径、旋转角度、大圆标识、顺逆时针标识、目标点x、目标点y。大圆标识和顺逆时针以0和1表示。0表示小圆、逆时针| |Q q |x1 y1 x y |绘制一条从当前点到x,y控制点为x1,y1的二次贝塞尔曲线| |T t |x y |绘制一条从当前点到x,y的光滑二次贝塞尔曲线,控制点为前一个Q命令的控制点的中心对称点,如果没有前一条则已当前点为控制点。| |C c| x1 y1 x2 y2 x y| 绘制一条从当前点到x,y控制点为x1,y1 x2,y2的三次贝塞尔曲线 |S s| x2 y2 x y| 绘制一条从当前点到x,y的光滑三次贝塞尔曲线。第一个控制点为前一个C命令的第二个控制点的中心对称点,如果没有前一条曲线,则第一个控制点为当前的点。|
maker元素
marker元素用来在path上添加一个标记,比如箭头之类的。
举个栗子 :
SVG 中并没有箭头,可以通过进行扩展。
先定义一个箭头 defs理解的话就很定义一个函数一样
<defs>
<marker id="markerArrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
</marker>
</defs>
其中orient="auto"设置箭头的方向为自动适应线条的方向。
而后,画line ,line的marker-end引用上面定义好的markerArrow即可
<svg width="300" height="300" style="outline: 5px solid #e6e6e6">
<marker id="markerArrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
</marker>
</defs>
<line x1="0" y1="0" x2="100" y2="50" stroke="red" stroke-width="1" marker-end="url(#markerArrow)" />
</svg>
首先需要定义好marker元素,然后在path中引用,一个marker标记是一个独立的图形,有自己的私有坐标。
⛳图案和渐变
填充图形或笔画除了使用fill,stroke纯色之外,还可以使用图案和渐变填充。
图案
使用图案填充图形,首先要定义一个水平或垂直方向的重复的图案对象,然后用它填充另一个对象或者作为笔画使用。这个图形对象呗称为"tile"(瓷砖)。
举个栗子 :
<svg width="1000" height="1000" xmlns ="http://www.w3.org/2000/svg">
<!--先定义一个图案-->
<pattern id="strip" patternUnits="userSpaceOnUse" x="0" y="0" width="6" height="6">
<path d="M0 0 6 0" style="stroke: black;fill: none"/>
</pattern>
<pattern id="polkadot" patternUnits="userSpaceOnUse" x="0" y="0" width="36" height="36" >
<circle cx="12" cy="12" r="12" style="fill: url(#strip);stroke: black"/>
</pattern>
</defs>
<!--使用-->
<rect x="36" y="36" width="100" height="100" style="fill: url(#polkadot);fill:url(#polkadot);stroke: black"/>
</svg>
图案对象使用pattern元素定义,pattern元素内部包裹了图案的path元素。定义好之后下一个需要解决的问题是如何排列图案,那就需要使用patternUnits属性.
patternUnits = objectBoundingBox
如果希望图案的大小基于要填充对象的大小计算,则需要设置patternUnits属性为objectBoundingBox(0到1之间的小数或百分比),并需要指定图案左上角的x和y坐标。
patternUnits = userSpaceOnUse
除了基于被填充对象尺寸方式之外,还可以按用户单位制定图案的width和height。此时要设置patternUnits值为userSpaceOnUse。
patternContentUnits属性
在上面两个例子中,pattern元素内的path元素的坐标都是用户坐标,如果想基于被填充图形设置,则需要设置patternContentUnits属性。patternContentUnits属性默认为userSpaceOnUse,当设置patternContentUnits属性为objectBoundingBox时就可以使用百分比来设置图案的大小。 基本看上面辣个栗子就懂啦 。
线性渐变
线性渐变是一系列颜色沿着一条直线过渡,在特定的位置指定想要的颜色,被称为渐变点。渐变点是渐变结构的一部分,颜色是表现的一部分。
线性渐变使用linearGradient元素表示:
<defs>
<linearGradient id="linear">
<stop offset="0%" style="stop-color:#ffcc00;"></stop>
<stop offset="100%" style="stop-color:#0099cc;"></stop>
</linearGradient>
</defs>
<rect x="20" y="20" width="200" height="100" style="fill:url(#linear);stroke:black;">
</rect>
径向渐变
径向渐变的每个渐变点是一个圆形路径,从中心点向外扩散。设置方式与线性渐变大致相同。如果填充对象边界框不是正方形的,则过渡路径会变成椭圆来匹配边界框的长宽比。
<defs>
<radialGradient id="radial" cx="50%" cy="50%" >
<stop offset="0%" style="stop-color:#f00;"></stop>
<stop offset="50%" style="stop-color:#0f0;"></stop>
<stop offset="100%" style="stop-color:#00f;"></stop>
</radialGradient>
</defs>
<rect x="20" y="20" width="200" height="200" style="fill:url(#radial);stroke:black;"></rect>
文本
相关术语
看一眼就好,跟CSS属性差不多
|术语| 说明| | ---- | ---- | |字符| XML中,字符是指带有一个数字值得一个或多个字节,数字值与Unidode标准对应| |符号| 字符的视觉呈现。每个字符可以有多种视觉呈现| |字体| 代表某个字符集合的一组符号| |基线| 字体中所有符号以基线对齐| |上坡度| 基线到字体中最高字符的顶部距离| |下坡度| 基线到最深字符底部的距离| |大写字母高度、x高度| 大写字母高度是指基线上大写字母的高度,x高度是基线到小写字母x顶部的高度|
text元素的基本属性
text元素以指定的x和y值作为元素内容第一个字符的基线位置,默认样式黑色填充、没有轮廓。
与css的text属性类似
<svg width="1000" height="1000">
<text x="0" y="15" fill="red">I am Leon</text>
</svg>
tspan元素
text元素无法对文本进行换行操作,如果需要分行显示文本,则需要使用tspan元素。tspan元素与html的span元素类似,可以嵌套在文本内容中,并可以单独改变其内部文本内容的样式。
<text x="10" y="20" style="fill:red;">Several lines:
<tspan x="10" y="45">First line</tspan>
<tspan x="10" y="70">Second line</tspan>
</text>
tspan元素除大小,颜色等表现样式之外,还可以设置以下属性:
|属性 | 说明| |----|----| |dx,dy| x和y方向的偏移| |x,y| 对tspan进行绝对定位| |rotate| 旋转字符,可以同时设置多个值,这些值会依次作用在tspan包裹的字母上| |baseline-shift| 与dy属性设置上下标相比,这个属性更方便,当为super时,会上标。sub时为下标。仅仅在所在的tspan内有效|
纵向文本
文本一般从左到右排列,如果需要上下排列,则需要使用writing-mode属性。
设置writing-mode属性值为tb(top to bottom),可以将文本上下排列。
<svg width="1000" height="1000" xmlns ="http://www.w3.org/2000/svg">
<text x="10" y="20" style="fill:red;writing-mode:tb">I am Leon</text>
</svg>
文本路径
如果要使得文本沿着某条路径排列,则需要使用textPath元素。需要将文本放在textPath元素内部,然后使用textPath元素的xlink:href属性引用一个定义好的path元素。
举个栗子 :
<svg width="1000" height="1000" >
<path id="circlePath"
d="M10,50
C10,50 50,0 100,50
C100,50 150,100 190,50
M10,150
C10,150 50,100 100,150
C100,150 150,200 190,150" />
</defs>
<g fill="dodgerblue" font-size="15" font-family="楷体">
<text x="20" y="40">
<textPath xlink:href="#circlePath">
SVG与文本:使用textPath进行字符串的显示
</textPath>
</text>
<use xlink:href="#circlePath" fill="none" stroke="blue" />
</svg>
裁剪和蒙版
裁剪路径
clip-path属性可以防止部分元素通过定义的剪切区域来显示,仅通过显示的特殊区域。
我的天,这又是个啥
通俗的来说,就是在纸上面剪了个洞,然后你能看到的就是洞的区域。
举个栗子 :
我们先来绘制一个圆:
<svg width="200" height="200" style="outline: 5px solid #e6e6e6">
<circle cx="60" cy="60" r="50" fill="#34538b" />
</svg>
再定义一个正方形让其成为裁剪路径
<svg width="200" height="200" style="outline: 5px solid #e6e6e6">
<defs><!-- 定义 -->
<clipPath id="clipPath"><!-- 定义剪裁路径 -->
<rect x="0" y="0" width="80" height="80" /><!-- 路径详细 -->
</clipPath>
</defs>
<circle cx="60" cy="60" r="50" fill="#34538b" clip-path="url(#clipPath)" />
</svg>
如图所示,被裁剪成了银杏叶 牛逼
在创建SVG文档时,可以通过指定感兴趣的区域的宽度和高度建立视口,这个视口就会变成默认的裁剪区域,裁剪区域外的任何部分都不会被显示。裁剪区域可以通过clipPath元素建立自己的裁剪区域。
参考链接
https://www. mybj123.com/4544.html
蒙版
SVG的蒙版会变换对象的透明度,如果蒙版是不透明的,则被蒙版覆盖的对象的像素就是不透明的,如果蒙版是半透明的,则对象就是半透明的。
举个栗子 :
黑色代表不可见(opacity: 0),白色代表可见(opacity: 100%)。
<svg> <defs> <linearGradient id='white2black'> <stop offset="0" stop-color="white"></stop> <stop offset="100%" stop-color="black"></stop> </linearGradient> <mask id="small-rect"> <rect x="0" y="0" width="400" height="300" fill="url(#white2black)"></rect> </mask> </defs> <rect id="back" x="0" y="0" width="400" height="300" fill="#d4fcff"></rect> <rect id="front" x="0" y="0" width="400" height="300" fill="#fcd3db" mask="url(#small-rect)"></rect> </svg>
参考链接
这里讲的更细
参考链接: https:// segmentfault.com/a/1190 000008903026
滤镜
工作原理
SVG阅读器处理一个图形对象时,会将对象呈现在位图输出设备上,它可以将对象的描述信息转化为一组对应的像素。在使用滤镜时,SVG阅读器不会直接将图形渲染为最终结果,而是先将像素保存到临时位图中,然后将滤镜指定的操作应用到该临时位图,其结果作为最终图形。
在SVG中,使用filter元素指定一组操作(也叫基元),在渲染图形对象时,将该操作应用在最终图形上。
filter标记之间就是我们想要的滤镜基元,每个基元有一个或多个输入,但是只有一个输出,输入可以是原始图形(SourceGraphic)、图形的阿尔法通道(不透明度,SourceAlpha)或者是前一个滤镜基元的输出。
创建投影效果
filter元素有一些属性用来描述该滤镜的裁剪区域。通过x,y,width,height属性定义一个滤镜范围,这些属性默认情况是按照对象的边界框计算的,即filterUnits属性的默认值为objectBoundingBox,如果要按照用户单位制定边界,则需要设置该属性值为userSpaceOnUse。
发光滤镜
feColorMatrix元素用来以一种通用的方式改变颜色值,可以用来创建一个发光的区域。
feImage滤镜
SVG的feImage滤镜允许使用任意的JPG\PNG\SVG文件或带有id属性SVG元素作为输入源。
光照效果
可以通过滤镜为图形添加光照效果,添加光照效果必须指定以下信息:
-
反射类型:漫反射(feDiffuseLighting)或镜面反射(feSpecularLighting)
-
想要照亮的对象
-
使用的灯光颜色
-
想要的光源类型:点光源(fePointLight),远光(FeFistantLight)或聚光灯(feSpotLight)
访问背景
除了SourceGraphic和SourceAlpha作为滤镜输入之外,还可以访问以及渲染到画布上的图片的某一部分,这部分内容称为backgroundImage和backgroundAlpha。为了访问这些输入信息,滤镜对象必须位于enable-background属性值为new的容器元素之内。
SVG动画
动画基础
SVG动画特性基于"同步多媒体集成语言"(SMIL)规范。在这个动画系统中,可以指定想要进行的动画的属性(颜色、动作或者变形等)的起始值和初始值,以及动画开始的时间和持续时间。
<rect x="10" y="10" width="200" height="200" stroke="black" fill="none">
<animate
attributeName="width"
attributeType="XML"
from="200" to="20"
begin="0s" dur="5s"
fill="freeze">
</animate>
</rect>
上述示例中,rect的宽度从200变化到20,历时5秒。rect不再是一个空元素,包含了动画元素animate。 如果需要在一个元素上指定多个属性的过渡则需要同时使用多个animate元素,分别指定过渡的这些元素的过渡属性。
animate元素指定了以下信息:
|属性| 说明| |----|----| |attributeName| 动画中改变的值| |attributeType| width是一个XML属性,另一个常用的值是CSS,如果忽略这个值,则默认是auto,会先搜索CSS属性,再搜索XML属性| |from to| 起始值和结束值| |values |from和to只能指定两个值,使用values时可以以列表形式同时指定多个中间值,变换会依次使用列表内的值。如果要交替动画,则指定为start,end,start三个即可实现| |dur| 持续时间| |fill| 结束时该怎么做,freeze表示冻结,如果不指定会使用默认值:remove,表示动画完成后会返回原始值。| |repeatCount| 动画重复次数| |repeatDur| 重复应该进行多长时间| |calcMode| 过渡类型,可以为线性(linear),直接跳转(不支持过渡时直接跳转到结束值discrete),spline,paced等。|
动画时间与同步动画
SVG动画用到的动画时钟在SVG加载完成时开始启动计时,当用户离开页面时停止计时。因此可以以下列任意一种方式指定动画开始和持续时间为一个数值。
|时间| 说明| |----|----| |时分秒的完整时间值 |例如1:20:23| |分秒形式| 例如02:15| |以h、min、s或者ms结尾的时间值| 例如begin="3.5s" dur="1min" 值和单位之间不能有空格|
可以将一个动画的开始时间设置另一个动画的结束或开始,而不是固定的时间值。
<rect x="10" y="10" width="200" height="25" stroke="black" fill="none">
<animate
id="c1"
attributeName="width"
attributeType="XML"
from="200" to="20"
begin="0s" dur="5s"
fill="freeze">
</animate>
</rect>
<circle cx="120" cy="60" r="10" stroke="black" fill="none">
<animate
attributeName="r"
attributeType="XML"
begin="c1.end"
from="10" to="20"
dur="4s"
></animate>
</circle>
多边形和path动画
多边形和path的值为数字列表,也可以对这些属性进行过渡,但是要保证数字列表中数字的数字数量没有变即可。列表中的每个点都是单独变换的。
<polygon points="30 30 70 30 90 70 10 70" style="fill:#fcc;stroke:black">
<animate
attributeName="points"
attributeType="XML"
to="50 30 70 50 50 90 30 50"
begin="0s" dur="5s" fill="freeze"
></animate>
</polygon>
<path d="M15 50 Q40 15,50 50,65 32,100 40" style="fill:#fcc;stroke:black" transform="translate(0,50)">
<animate
attributeName="d"
attributeType="XML"
to="M50 15Q15 40,50 50,32 65,40 100"
begin="0s" dur="5s" fill="freeze"
></animate>
</path>
对坐标变换进行过渡
animate元素不适合对平移、旋转、缩放进行过渡,因为这些坐标变换被包裹在transform属性内。animateTransform元素可以解决这个问题。
<g transform="translate(100,60)">
<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"
dur ="3s"
begin = "0s" fill="freeze"
></animateTransform>
</rect>
</g>
上述示例中,会对矩形的transform属性进行过渡,通过type指定是对scale进行过渡。可以对矩形进行缩放。缩放的中心为100,60(因为矩形被包裹在g中,g被平移了100,60)
沿着path运动
我们已经可以在animateTransform元素中通过translate对过渡对象进行平移变换,但是如果需要让过渡对象沿着更复杂的路径运动,则需要使用animateMotion元素。
<rect x="-10" y="-10" width="20" height="20" style="fill:#ff9;stroke:black">
<animateMotion
path="M50,135C100,25 150,225 200,125"
dur="6s" fill="freeze"
></animateMotion>
</rect>
上述示例中,可以使矩形沿着path="M50,135C100,25 150,225 200,125"做轨迹运动,但是运动过程中,矩形不会自动根据轨迹方向旋转,因此需要设置animateMotion元素的rotate属性值为auto。
CSS处理SVG动画
骤:一是选中要运动的元素,然后设置将动画属性作为一个整体进行设置。二是告诉浏览器改变选中元素的哪个属性以及在动画的什么阶段。这些都定义在@keyframes说明符中。
|动画属性| 说明| |----|----| |animation-name| @keyframes说明符的名称| |animation-duration| 动画持续时长| |animation-timing-function| 如何计算中间值,也就是动画类型:线性,缓入缓出等等| |animation-iteration-count| 重复次数| |animation-direction| 动画是反向还是正向或者交替执行| |animation-play-state| 可以设置为running或paused| |animation-delya| 延迟时间| |animation-fill-mode |动画不再执行时使用什么属性,可以为forwards(结束时属性)、backwards(开始时属性值)、both|
<defs>
<g id="starDef">
<circle cx="50" cy="50" r="10"></circle>
</defs>
<use id="star" class="starStyle" xlink:href="#starDef" fill="#008000"></use>
对应的css代码
.starStyle{
animation-name:starAnim;
animation-duration: 2s;
animation-iteration-count: 4;
animation-direction: alternate;
animation-timing-function: ease;
animation-play-state: running;
@keyframes starAnim{
fill:red;
transform: translate(100px,100px);
fill:green;
transform: translate(120px,100px);