SVG入门指引

概念

SVG全称是可缩放矢量图(Scalable Vector Graphics),是一种基于XML语法,用于描述二维矢量图形的图形格式。jpg,png等其他图像格式都是基于像素处理的,而SVG是用文本格式的描述性语言来描述图像内容,因此是一种和图像分辨率无关的矢量图形格式,可以无损进行缩放。

SVG格式的优点:

  1. 图像文件可读,易于修改和编辑
  2. 与现有技术可以互动融合。例如,SVG技术本身的动态部分(包括时序控制和动画)就是基于SMIL标准。SVG文件还可嵌入JavaScript脚本来控制SVG对象
  3. SVG图形格式可以方便的创建文字索引,从而实现基于内容的图像搜索
  4. SVG图形格式支持多种滤镜和特殊效果,在不改变图像内容的前提下可以实现位图格式中类似文字阴影的效果
  5. SVG图形格式可以用来动态生成图形。例如,可用SVG动态生成具有交互功能的地图

SVG格式的缺点:

  1. 较老的IE浏览器不支持(需要IE9+)
  2. 由于原始的SVG档是遵从XML语法,导致数据采用未压缩的方式存放,因此相较于其他的矢量图形格式,同样的文件内容会比其他的文件格式稍大
  3. SVG标准不兼容,旧版的SVG Viewer无法正确显示出使用新版SVG格式的矢量图形

SVG使用方式

SVG的基础知识

SVG必须使用<svg>元素进行声明,表示一个SVG文档片段。可以直接嵌入HTML,也可以在直接存为一个svg文件。

使用图形元素来绘制图形,常用的图形元素有:矩形<rect>、圆<cicrle>、椭圆<ellipse>、多边形<polygon>、直线<line>、折线<polyline>、任意曲线<path>等。

可以使用<g>元素来做组合对象的容器,其子元素可以继承其属性。此外,<g>元素也可以用来定义复杂的对象,之后可以通过<use>元素来引用它们。

可以使用<defs>元素来预定义图形,并且在其他元素中引用。

可以直接在元素上定义属性来设置图形的线宽,颜色,填充色等;也可以使用css来定义,但是属性和普通css不相同。

svg的坐标体系。如下图,取svg元素左上角为坐标原点,X轴向右递增,Y轴向下递增。进行图形绘制时,以此坐标来定位。但是需要注意的是text元素的x,y属性定位时是该元素的左下角。

axis.png

如何在HTML中使用SVG

SVG在网页中使用有很多种方式,即可像其他图片文件一样直接引用,也可以做像其他DOM元素一样嵌入其中。示例如下:

  // SVG 文件可以直接插入网页,成为 DOM 的一部分,然后用 JavaScript 和 CSS 进行操作。
  <!DOCTYPE html>
  <html>
  <head></head>
  <body>
    <svg id="mysvg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
      <circle id="mycircle" cx="400" cy="300" r="50" />
    </svg>
   </body>
  </html>
  
  // SVG代码也可以写在一个独立文件中,然后用<img>、<object>、<embed>、<iframe>等标签插入网页。
  <img src="circle.svg">
  <object id="object" data="circle.svg" type="image/svg+xml"></object>
  <embed id="embed" src="icon.svg" type="image/svg+xml"/>
  <iframe id="iframe" src="icon.svg"></iframe>

  //SVG文件还可以转为 BASE64 编码,然后作为 Data URI 写入网页。
    <img src="data:image/svg+xml;base64,[data]"/>

  // CSS 也可以使用 SVG 文件。
  .logo {
    background: url(icon.svg);
  }

SVG常用元素介绍

SVG标准中的元素,主要分为:容器元素,基本图形元素,描述性元素,动画元素,滤镜元素,字体元素等等。本文只介绍前三类元素中最基本元素的使用,后续再描述其他元素的使用方法。

容器元素

svg

<svg>元素是SVG图片的根元素/容器,表示一个SVG文档片段。其主要属性如下。

属性 描述 默认值
width SVG片段的宽度,可以是像素也可以是百分比 100%
height SVG片段的高度,可以是像素也可以是百分比 100%
viewBox 用来控制实际显示的内容,即只显示svg元素内部分区域,并缩放。该属性是一个包含4个参数的列表start-x,start-y,width和height,以空格或者逗号分隔开。用以设置实现显示区域的初始坐标和宽高。如果x+width>svg width,则会向右移,以保证最终显示区域的width不变。height规则相同。不允许宽度和高度为负值,0则禁用元素的呈现。 0,0,svg width,svg height,全部显示
preserveAspectRatio 表示对viewBox选中的区域是否强制进行统一缩放.规则过于复杂,这里不再转述,详见preserveAspectRatio none,根据显示区域决定是否缩放

defs

<defs>元素来自定义图形,它内部的图形不会显示,仅供在其他元素中引用。例如定义一个箭头图形,供其他连线使用。

<defs>
  <marker id="markerArrow" markerWidth="4" markerHeight="4" refX="0" refY="2" orient="auto">
    <path d="M0,0 L4,2 L0,4 z" class="axis-arrow"></path>
  </marker>
</defs>

<path d="M100,10 L150,10 L150,60" style="stroke: #6666ff; stroke-width: 1px; fill: none;
      marker-end: url(#markerArrow) "></path>
arrow.png

g

<g>元素来做组合对象的容器,其子元素可以继承其属性。此外,<g>元素也可以用来定义复杂的对象,之后可以通过<use>元素来引用它们。

<defs>
  <g id="ShapeGroup">
    <rect x="0" y="0" width="100" height="100" fill="#69C" stroke="red" stroke-width="2"/>
    <circle cx="50" cy="50" r="40" stroke="#00f" fill="none" stroke-width="5"/>
  </g>
</defs>
<use xlink:href="#ShapeGroup" x="0" y="0" transform="scale(0.5)"/>
<use xlink:href="#ShapeGroup" x="10" y="10" transform="scale(1)"/>
<use xlink:href="#ShapeGroup" x="30" y="30" transform="scale(1.5)"/>
use.png

常用属性介绍

在绘制图形时,经常使用如下一些属性,用来定义图形的样式,可以直接在元素上直接设置属性,也可以类似CSS一样使用。

属性 描述 默认值
fill 图形内填充颜色,与css颜色定义相同,可以预定义,长/短十六进制和rgb方式定义 none,无填充色
stroke 图形外轮廓线条的颜色,与css颜色定义相同 none,无颜色
stroke-width 图形外轮廓线条的宽度像素值,如果使用了一个百分比,这个值代表当前视图的百分比 1

SVG的相关属性,同样也可以采用css样式来定义

.myrect{
  fill: red;
  stroke: #0FF;
  stroke-width: 1;
}

基本图形元素

rect矩形

<rect>元素用来绘制矩形,属性x,y指定矩形左上角的坐标,属性width设置宽度,属性height设置高度。

<rect x="2" y="2" width="90" height="90" fill="#69C" stroke="red" stroke-width="2"/>
rect.png

cicrle圆

<cicrle>元素用来绘制圆形,属性cx,cy指定圆形的圆心坐标,属性r设置圆的半径。

<circle cx="50" cy="50" r="40" stroke="#00f" fill="none" stroke-width="2"/>
circle.png

ellipse椭圆

<ellipse>元素用来绘制椭圆,属性cx,cy指定椭圆的中心坐标,属性rx设置椭圆的横轴半径,属性ry设置椭圆的纵轴半径。

<ellipse cx="50" cy="50" rx="40" ry="30" stroke="#00f" fill="none" stroke-width="2"/>
ellipse.png

polygon多边形

<polygon>元素用来绘制多边形,属性point用来设置多边形的各端点。points默认会自动闭合,无需最后添加起始点。

<polygon points="2,2 98,2 80,50 98,98 2,98 " stroke="#00f" fill="none" stroke-width="2"/>
polygon.png

line直线

<line>元素用来绘制直线,x1属性和y1属性,表示线段起点的横坐标和纵坐标;x2属性和y2属性,表示线段终点的横坐标和纵坐标。

<line x1="10" y1="10" x2="100" y2="100" stroke="#00f" fill="none" stroke-width="2"/>
line.png

polyline折线

<polyline>元素用来绘制折线,属性point用来设置折形的各端点。。

<polyline points="2,2 98,2 80,50 98,98 2,98" stroke="#00f" fill="none" stroke-width="2"/>
polyline.png

path任意曲线

<path>元素用来绘制任意曲线,属性d设置曲线的定义。

<path fill="none" stroke="red"
    d="M 10,30
       A 20,20 0,0,1 50,30
       A 20,20 0,0,1 90,30
       Q 90,60 50,90
       Q 10,60 10,30 z" />
path.png

d属性中路径的设置有以下几种类型,可以任意组合,空格分隔,最后生成实际的曲线。简单的曲线直接定义,复杂的曲线一般是使用那个其他工具自动生成。

类型 参数形式 说明 实例
M x,y moveTo,移动到[x,y] M10,10
L x,y lineTo,绘制一条到[x,y]的直线 L100,10
H x horizontal,绘制一条到 [x,currentY] 的横线 H100
V y vertical,绘制一条到 [currentX,y] 的竖线 V100
A rx,ry rotation arc sweep x,y arc,绘制椭圆弧,参数分别为半径、旋转角度,是否超过180,是否逆时针,终点坐标 A30,50 0 0 1 162.55,162.45
Q x1,y1 x2,x2 quadratic,绘制一条控制点为 [x1,y1],目标点为 [x2,y2]的二次贝塞尔曲线 L100,10
T x,y 绘制一条目标点为 [x,y]的二次贝塞尔曲线,控制点是当前到目标的中心对称点。 L100,10
C x1,y1 x2,y2 x3,y3 绘制一条目标点为 [x3,y3],开始控制点为[x1,y1],结束控制点为[x2,y2] 的三次贝塞尔曲线 L100,10
S x1,y1 x2,y2 绘制一条目标点为[x2,y2],以[x1,y1]和当前点与结束点的中心对称点为控制点的三次贝塞尔曲线 L100,10
Z - 闭合路径 Z

关于贝塞尔曲线,这里是示意图:

1
2

如需进一步了解path相关特性,建议参考
《深度掌握SVG路径path的贝塞尔曲线指令》
《MDN-Path—d》

文本和其他元素

text文本

<text>元素用来绘制文本图形,而且可以将渐变、图案、剪切路径、遮罩或者滤镜应用到text上。属性x,y指定文本图形左下角的坐标。注意此时的strok是指文字的线条而不是图形的边框。css中关于文字的相关属性,此处同样有效。

<text x="40" y="40" stroke="#0ff" fill="none" stroke-width="1">text文本</text>

foreignObject容器

<foreignObject>元素也是一个容器元素,用来在SVG中引入其他XML定义,常用来引入HTML元素。

<foreignObject>
  <p>foreignObject容器</p>
  <ul>
    <li>嵌入HTML</li>
    <li><a>插入超链接</a></li>
  </ul>
</foreignObject>

实例

由于SVG可以看作是HTML元素,所以可以使用JS和CSS精确控制,同样可以使用在Vue等前端框架中。这里演示一个里程碑的实例。

landmark.png

参考资料

维基百科——可縮放向量圖形
MDN-SVG
《SVG图像入门教程》——阮一峰

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • @(HTML5)[canvas与SVG] [TOC] 十一 、SVG HTML体系中,最常用的绘制矢量图的技术是S...
    踏浪free阅读 4,473评论 0 2
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,036评论 1 32
  • 阅读原文 SVG矢量动画机制   Google在Android 5.X中增加了对 SVG 矢量图形的支持, 这对于...
    GeekGray阅读 5,707评论 0 4
  • 使用XML描述的矢量文件W3C标准(1.1):http://www.w3.org/TR/SVG11/浏览器支持情况...
    没汁帅阅读 5,871评论 0 16
  • 即将要看到这篇小说的各位,我本来是要写长篇小说,后来知道只能写短篇小说,我就想能不能分好几篇来写?你们说行吗?
    离血孤冥阅读 193评论 0 0