L o a d i n g . . .
SHIWIVI-文章

//sunny forever
while(life<end){
love++;
beAwesome :)}

    <
  • 主题:
  • + -
  • 清除背景
  • 禁用背景

SVG矢量图

字数:11370 写于:2023-05-19
最新更新:2023-05-19 阅读本文预计花费您33分钟

简介

SVG(Scalable Vector Graphics)全称为可缩放矢量图形,是一种用 XML 标记语言描述二维矢量图形的技术,它有以下特点:

  • 使用XML语法文本定义图形,因此SVG图形可以被索引、搜索、选中,很适合制作地图
  • SVG提供的是矢量图,可以被无限放大且不会失真,也可以在任何分辨率下被高质量地打印
  • SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强

使用

在HTML中使用SVG,可以直接在文档中直接创建SVG标签,也可以先创建svg文件或者xml文件,再引入到HTML中

svg文件

SVG文件通常以.svg作为文件后缀,使用gzip压缩的SVG文件以.svgz为后缀名

<svg version="1.1" baseProfile="full" width="300" height="200" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> </svg>
  • version属性用于验证识别SVG版本,SVG 2之后的版本不再推荐使用该属性值
  • baseProfile 属性用于描述作者认为正确呈现内容所必需的最小SVG语言配置文件,当用户修改内容超出所指定的基准概述范围时,编辑工具会发出警告,一般可以不指定,即使用默认值none,可取值:
    • none(默认),代表作者无观点,使用最小的 SVG 语言配置
    • full(正常),适用于PC
    • basic(轻量级),适用于平板电脑等PDA
    • tiny(更轻量级),适用于手机
  • width和height属性用于指定画布大小,单位会自行解析为px而无需指定,默认大小为300px*150px
  • viewBox属性用于指定显示区域,上述参数解析为仅显示从(0,0)坐标开始,长宽均为100px的矩形区域内的图形
  • xmlns属性用于声明命名空间,这里的URL只做该命名空间的字符串名称,并不是要”链接”到某个地址。命名空间用于多个文档声明了相同的标签时,帮助XML内容的使用者区别该标签属于哪一个命名空间
  • 拥有命名空间后意味着该<svg> 标签和它的子节点都属于该命名空间
svg写入xml文件
<?xml version="1.0" ?> <svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg"> <circle cx="150" cy="100" r="80" fill="green" /> </svg>

引入

直接插入<svg>标签

可以直接在HTML所需位置插入<svg>标签

<body> <svg width="400" height="300"> <!--svg内容--> </svg> </body>
通过img标签引入

可以将svg定义为一个单独文件,然后通过img标签引入图片

<img src="./index.svg" alt="未加载SVG">
CSS引入

在CSS样式中将svg作为背景图引入

.svgPic{ width: 400px; height: 300px; background-image: url(./index.svg); background-repeat: no-repeat; }
object标签引入

object标签可用于包含音视频及图形对象,并且支持.svg.xml格式的文件

<object data="./index.svg" type="image/svg+xml" width="400" height="300">未加载SVG</object>
<object data="./index.xml" type="image/svg+xml" width="400" height="300">未加载SVG</object>
iframe标签引入

使用内联框架引入svg数据,该标签也同时支持.svg.xml文件

<iframe src="./index.svg" width="400" height="300">浏览器不支持iframe标签</iframe>
<iframe src="./index.xml" width="400" height="300">浏览器不支持iframe标签</iframe>

基本图形

矩形

rect标签

<rect x="10" y="10" rx="20" ry="40" width="200" height="200" ></rect>
  • (x,y)为矩形左上角坐标
  • width,height为矩形长和高,不能为负值!(与canvas不同)
  • rx为矩形与x轴平行的两条边的圆角半径,默认为0
  • ry为矩形与y轴平行的两条边的圆角半径,默认为0

circle标签

<circle cx="100" cy="100" r="50"></circle>
  • (cx,cy)为圆心坐标
  • r为圆的半径

椭圆

ellipse标签

<ellipse cx="200" cy="200" rx="100" ry="50"></ellipse>
  • (cx,cy)为椭圆中心的坐标
  • rx为椭圆的 x 半径,ry为椭圆的 y 半径

线段line

<line x1="150" y1="300" x2="300" y2="350"stroke="#fff" stroke-width="5"></line>
  • (x1,y1)为线段起始坐标
  • (x2,y2)为线段终点坐标
  • stroke指定线段绘制颜色

折线polyline

<polyline points="0 0,10 10,20 0,30 10" style="stroke:#fff;" />
  • points属性指定折线折点,每个折点必须指定x,y坐标
  • 坐标之间可以用空白符、逗号、或者可附带空格的换行符分隔开
以下写法均可以表示(0,0)、(10,10)、(20,0)、(30,10)四个坐标点,也可以用换行替代 points="0 0 10 10 20 0 30 10" points="0 0,10 10,20 0,30 10" points="0,0 10,10 20,0 30,10"

多边形polygon

<polygon points="10 10,60 30,120 10" style="stroke:#fff;" />
  • points属性与polyline类似
  • 坐标最后一个点会和第一个点闭合

path路径

通过描述路径坐标理论上可绘制任意图形,路径坐标的表示方法与上述points属性坐标表示方法相同,可以用空白符、逗号、或者可附带空格的换行符进行分隔

命令参数

<path d="M250 150 L150 350 L350 350 Z" />
  • d属性通过”命令+坐标参数”的组合来描述路径
  • 命令为大写字母时表示绝对定位,即相对于svg左上角坐标原点的坐标,命令为小写字母时表示相对定位,即相对于上一个命令终点的相对位移

命令包括以下:

  • M = moveto,移动画笔
  • L = lineto,绘制直线
  • H = horizontal lineto,绘制水平直线,只需要x一个参数
  • V = vertical lineto,绘制垂直直线,只需要y一个参数
  • C = curveto,绘制三次贝塞尔曲线
  • S = smooth curveto,可衔接的三次贝塞尔曲线
  • Q = quadratic Belzier curve,绘制二次贝塞尔曲线
  • T = smooth quadratic Belzier curveto,绘制可衔接的二次贝塞尔曲线
  • A = elliptical Arc,绘制弧线
  • Z = closepath,闭合路径,一般用于路径最后

二阶贝塞尔曲线

通过给定一个控制点坐标和曲线终点坐标绘制贝塞尔曲线
Q x1 y1, x y

  • 只需要一个控制点(x1,y1)
  • (x,y)为终点坐标
延长的平滑二阶贝塞尔曲线

可以将多个贝塞尔曲线衔接起来,形成一条更长的曲线
T x y

  • 只需要指定曲线终点坐标(x,y)
  • 如果该命令前为另一个Q命令或T命令,该命令会把上一个命令控制点关于曲线终点的中心对称点作为其控制点
  • 如果该命令单独使用,则会认为控制点和终点为同一点,绘制一条直线
    <path d="M 10 80 Q 50 200 100 100 T 200 120"/>

三阶贝塞尔曲线

通过指定两个控制点,一个终点坐标绘制曲线
C x1 y1, x2 y2, x y

  • (x1,y1)(x2,y2)为控制点坐标
  • (x,y)为曲线终点坐标
  • c小写时(x,y)应当为上一个路径终点的相对坐标(dx,dy)
    <path d="M 10 10 C 0 200, 150 20, 300 300 "/>

同理,可以将多个三阶贝塞尔曲线衔接起来,形成一条更长的曲线
S x2 y2, x y

  • (x2,y2)为控制点坐标
  • (x,y)为终点坐标
  • 如果该命令跟在一个 C 或 S 命令后面,则该曲线的第一个控制点会被设置为前一个曲线第二个控制点关于曲线终点的中心对称点(以此保持斜率不变来保证曲线可以平滑衔接)
    <path d="M 10 10 C 10 150, 150 20, 200 50 S 160 150, 400 100 "/>

颜色与样式

描边

默认情况下,创建路径后不会进行描边,需要使用stroke属性指定描边颜色

  • stroke=”颜色” 指定描边颜色,取值同CSS
  • stroke-opacity=”值” 单独指定不透明度
  • stroke-width=”值” 指定描边线宽度

描边终点与折点样式

  • stroke-linecap=”butt/round/square” 描边终点为正常(平头截断)/圆形线帽/矩形线帽
  • stroke-linejoin=”miter/round/bevel” 描边折点为尖角/圆角/切角
  • stroke-miterlimit=”值” 设置折点斜切面的限制长度
具体样式区别可以参考这篇博文:canvas绘制线段-实线部分

填充

默认情况下,闭合图形或路径的填充色为黑色,可以通过fill属性修改

  • fill=”颜色” 指定填充颜色,取值同CSS
  • fill-opacity=”值” 单独指定填充不透明度

虚线

  • stroke-dasharray=”值,值…” 设置虚线线段和间隙的长度
  • stroke-dashoffset=”值” 设置虚线偏移值

使用CSS定义样式

svg的属性除了能在标签属性中定义外,也能在CSS中直接声明,但仅适用于部分属性

  • stroke
  • fill

特殊标签

defs标签

defs标签用于定义需要重复使用的图形元素,该标签中定义的图形元素不会直接呈现,只供后续调用

g标签

容器标签,用于包含一组标签,然后将该组标签的共同样式属性添加到g标签上,这样该属性值会对所有子标签继承。注意:g标签不支持使用x,y属性来进行定位,需要修改位置时,可以使用transform属性或CSS修改

渐变

线性渐变

<defs>标签内创建一个<linearGradient>标签,在该标签内定义线性渐变,并通过<stop/>标签的属性定义颜色、渐变位置、不透明度,然后在需要调用的图形中,用fill属性或stroke属性调用url引用<linearGradient>标签的ID值(调用类名无效)

<linearGradient x1=”0” x2=”1” y1=”0” y2=”0”></linearGradient>

  • x1,x2,y1,y2通过确定两个点来定义渐变路径走向,一般取值0-1间的小数,取大于1的值将导致渐变超出图形范围(溢出的渐变部分不可见)
  • 默认从左往右,即x1=”0” x2=”1” y1=”0” y2=”0”
  • x1=”0” x2=”0” y1=”0” y2=”1”即调整为从上到下

<stop offset=”50%” stop-color=”#00f” />

  • offset属性定义颜色渐变(偏移)位置,可以取0%-100%,也可以取0-1间的小数
  • stop-color定义颜色,取值同CSS
  • stop-opacity定义不透明度
<defs> <linearGradient id="G1"> <stop offset="0%" stop-color="red"/> <stop offset="50%" stop-color="yellow"/> <stop offset="100%" stop-color="blue"/> </linearGradient> </defs> <rect x="0" y="0" rx="10" ry="10" width="300" height="300" fill="url(#G1)"/>

径向渐变

与线性渐变类似,径向渐变需要在<defs>标签内创建一个<radialGradient>标签,然后通过<stop/>标签的属性定义颜色、渐变位置、不透明度

<radialGradient cx=”.5” cy=”.5” r=”.5” fx=”.2” fy=”.2”><radialGradient>

  • cx,cy定义渐变结束所围绕的圆环,取值0-1
  • r定义渐变圆在当前图形中的占用半径,一般取值0-1,大于1将导致渐变溢出图形
  • fx,fy定义渐变开始的位置
<defs> <radialGradient cx=".5" cy=".5" r=".5" fx=".2" fy=".2" id="R1"> <stop offset="0%" stop-color="red"/> <stop offset="25%" stop-color="yellow"/> <stop offset="50%" stop-color="blue"/> <stop offset="75%" stop-color="green"/> <stop offset="100%" stop-color="purple"/> </radialGradient> </defs> <rect class="fillRect" x="0" y="0" width="200" height="200" fill="url(#R1)"/> 1. 渐变开始位置为矩形图20%,20%位置 2. 渐变结束所形成的圆环:圆心位于矩形50%,50%点处,半径为矩形长的50%

spreadMethod属性

spreadMethod属性用于指定渐变到达终点的行为,默认情况下,offset为100%时的颜色会填充剩余部分,该属性对线性渐变和径向渐变均生效

  • pad(默认),渐变结束后使用终点颜色填充剩下区域
  • reflect,渐变结束后按反向颜色顺序填充剩下区域
  • repeat,渐变结束后从头开始填充剩下区域
<linearGradient id="g2" x1="0" x2=".5" y1="0" y2="0" spreadMethod="pad">// <stop offset="0%" stop-color="red"/> <stop offset="33%" stop-color="yellow"/> <stop offset="66%" stop-color="blue"/> <stop offset="100%" stop-color="green"/> </linearGradient> 1. x2=".5"指定了颜色渐变填充到矩形的50%位置 2. pad值会用终点颜色填充剩下区域 3. reflect值会按绿,蓝,黄,红顺序(与原顺序相反)填充剩下区域 3. repeat值会按颜色顺序(从头开始)填充剩下区域

Pattern

与canvas相同,svg也有一个模板对象,常用于定义需要重复填充的背景图等。与渐变一样,<pattern> 也需要定义在的 <defs> 内部,然后使用其他图形引用Patterns的ID
<pattern x=”0” y=”0” width=”.25” height=”.25”></pattern>

  • x,y定义Pattern图形的开始位置
  • width,height决定该Pattern图形会在x轴和y轴上重复几次,0.25意味着将在横轴和纵轴方向上均重复4次
<svg width="200" height="200"> <defs> <pattern id="Pattern" x="0" y="0" width=".25" height=".25"> <rect x="0" y="0" width="50" height="50" fill="skyblue"/> <circle cx="25" cy="25" r="20" fill="yellow" fill-opacity="0.5"/> </pattern> </defs> <rect fill="url(#Pattern)" stroke="black" x="0" y="0" width="200" height="200"/> </svg>


文本

text标签

<text x=”0” y=”0”></text>

  • x,y定义文字左下角在SVG中的开始位置(y值)
  • 通过fill属性和stroke属性指定文字填充/描边颜色
  • text-anchor属性决定文本开始方向,可取值:start、middle、end、inherit(该属性一般用于阿拉伯语等从右到左阅读的语言)
  • 以下属性定义文字大小、字间距等,可以直接定义在标签中,也可以定义在CSS中,取值和CSS大致相同:font-familyfont-stylefont-weightfont-sizeletter-spacingword-spacingtext-decorationfont-variantfont-size-adjust等,注意,文字的填充和描边需要使用fillstroke属性指定颜色
<style> #svgText{ text-anchor:start; fill: red; font-size: 20px; font-weight: 900; } </style> <svg width="600" height="600" xmlns="http://www.w3.org/2000/svg"> <text id="svgText" x="10" y="30">手写的从前</text> </svg>

tspan标签

tspan标签常用于标记出一段文本中的特殊部分,如将某句话的关键词加粗标识,该标签必须包含于text标签或tspan标签中
<tspan>文本内容</tspan>

  • 该标签需要置于父级text标签或tspan标签内,且文本在svg的位置跟随父级标签
  • x,y属性可以为该标签设置一个新的位置坐标,该坐标是相对于svg的坐标原点,无视父级坐标
  • dx,dy属性可以在父级坐标的基础上,进行偏移
  • rotate属性可以将文字 进行旋转
  • 上述属性都允许赋值一个数列,表示为tspan标签中的每个字符设置单独的坐标/旋转值
1. x和y属性是相对于SVG的坐标,可能导致tspan标签内容覆盖到父级文本之上 <text y="20" fill="#fff">父级标签<tspan x="20" fill="red">x属性</tspan>父级标签</text> 2. dx,dy属性是在父级坐标基础上进行位移 <text y="20" fill="#fff">父级标签<tspan dx="20" fill="red">dx属性</tspan>父级标签</text> 3. x,y,dx,dy的属性值可以为一组数列值,依次指定标签中每个字符的坐标 <text y="20" fill="#fff">父级标签<tspan dx="20,25,30,35" fill="red">dx属性赋值数列</tspan>父级标签</text> 4. rotate属性值也可以是单个,或者为一组数列,对字符进行旋转 <text y="20" fill="#fff">父级标签<tspan rotate="20,30,40,50,60,70,80" fill="red">dx属性赋值数列</tspan>父级标签</text>

1.父级标签x属性父级标签2.父级标签dx属性父级标签3.父级标签dx属性赋值数列父级标签4.父级标签rotate属性赋值数列父级标签

textPath标签

textPath可创建出跟随路径排列的文本,需要通过xlink:href属性引用路径ID

<path d="M 10 80 Q 50 200 100 100 T 200 120" id="my_path" fill="none" stroke="red"/> <text fill="skyblue" font-size="20"> <textPath xlink:href="#my_path">So live a life you will remember</textPath> </text>

So live a life you will remember

变形、剪切、遮罩、图片

变形

  • transform=”translate(x,y)” 平移(如果只指定一个值,则默认第二个值为0)
  • transform=”rotate(角度值)” 沿着图形左上角顺时针(正值)旋转
  • transform=”skewX(角度值)或skewY(角度值)” 在x/y轴方向上斜切
  • transform=”scale(x缩放,y缩放)” 在x/y轴进行缩放(如果只指定一个值,则默认第二个值等于第一个值)
  • 多个属性值可以写到一个transform中,用空格隔开
<rect x="0" y="0" width="200" height="200" fill="red" transform="translate(50,10) scale(.2,1.2) rotate(60)"/>

clipPath剪切

定义一个clipPath标签并指定路径或图形,然后在需要裁剪的目标元素上使用clip-path属性调用clipPath标签的ID值进行裁剪,剪裁会保留二者相同部分,对其余部分进行裁剪。该标签一般定义于defs标签中

<defs> <clipPath id="cut"> <rect x="200" y="200" width="200" height="100"/> </clipPath> </defs> <circle cx="300" cy="300" r="100" fill="yellow" clip-path="url(#cut)"/>

mask遮罩

遮罩常用于制作淡出淡入效果,mask标签定义于defs标签中,然后在需要添加遮罩的标签中使用mask属性引用遮罩ID

<defs> <linearGradient id="Gradient"> <stop offset="0" stop-color="white" stop-opacity="0"/> <stop offset="1" stop-color="white" stop-opacity="1"/> </linearGradient> <mask id="Mask"> <rect x="0" y="0" width="200" height="200" fill="url(#Gradient)"/> </mask> </defs>

<rect x=”0” y=”0” width=”200” height=”200” fill=”green”/>
<rect x=”0” y=”0” width=”200” height=”200” fill=”red” mask=”url(#Mask)” />

图片

SVG使用image标签插入图片,并且可以在图像上使用剪切、变形、遮罩等SVG提供的功能
<image xlink:href=””/>

  • 可以使用x,y属性指定图片位置
  • 可以使用width,height属性指定图片宽高
  • xlink:href属性用于指定图片地址
    <image x="50" y="50" width="300" height="300" xlink:href="../dog.jpg"/>
SVG中还有链接、动画、滤镜等标签,详见MDN文档:https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element
上一篇:xml
下一篇:Canvas
z z z z z