内容简介:SVG基础知识
写在前面
之前有提到过SVG描边动画,可以实现很神奇的手写签名动画效果,当然,理论上可以用来实现任意 不规则路径填充动画
在支持SVG的场景,可以考虑采用强大的SVG描边动画,能够实现一些incredible效果,在处理不规则描边、填充动画方面疗效确切
一.兼容性
SVG(Scalable Vector Graphics)是一种基于XML的标记语言,用来描述二维矢量图
基础兼容性( Can I use SVG ):
桌面 [IE9+] 移动 [Android4.4+] [Android3-4.3]部分支持
SVG动画元素兼容性( Can I use SVG animation ):
移动 [Android3+] iOS[6.1+]
在移动端早就可以随便玩了,比如用 animateMotion
实现沿不规则路径运动效果
二.应用场景
1.icon
iconfont兼容性确实比SVG好,但有一些限制:
-
只支持font相关的CSS规则
-
浏览器对字体的优化(抗锯齿等等),导致不同浏览器下icon显示效果有差异
-
依赖字体文件,糟糕情况(下载失败,或者用户偏好自定义字体)下,会显示框框,甚至与emoji冲突
只能纯色或者渐变,而且大小定位受 line-height
, vertical-align
, letter-spacing
等影响,实际尺寸可能存在偏差(很难对齐)
SVG icon的优势:
-
矢量图,随便缩放
-
可以控制icon不同部分的样式,描边颜色等等
-
实际尺寸精确,占据空间与SVG元素尺寸一致
-
糟糕情况下,可以用png做平滑fallback
关于SVG icon的更多信息,请查看:
2.动画
SVG结合animation能够实现很多神奇的效果:
-
不规则描边动画(手写签名)
-
填充动画(手绘)
-
不规则路径动画( 让元素沿不规则路径运动 )
一个印象深刻的SVG动画: Animated line drawing in SVG ,更多SVG动画案例见 30 Awesome SVG Animation For Your Inspiration
3.图表
一些很受欢迎的图表库都采用SVG来实现,例如 d3
、 google charts
等等
相比 canvas
图表, SVG
图表在过渡动画方面有先天优势,能够实现很漂亮的过渡效果,例如 D3 Tree
三.SVG元素
SVG有一套自己的元素定义(与HTML元素类似),用来描述二维图形。用 svg
标签包裹起来,可以直接嵌入HTML中,例如:
<h3>svg demo</h3> <svg width="300" height="200" xmlns="http://www.w3.org/2000/svg"> <rect x="10" y="10" width="30" height="30"></rect> </svg> <span>sibling</span>
显示 30x30px
的黑方块, svg
元素尺寸为 100x100px
, svg
元素默认 display: inline
,所以”sibling”文本与黑方块并列
P.S. width, height, x, y
等属性不带单位的话,默认是 px
,也可以带 em, ex, in, cm, mm, pt, pc, %
等单位
SVG元素比较多,且与HTML元素有交集,见 SVG element reference
1.形状元素
基本形状有6种: <circle>, <ellipse>, <line>, <polygon>, <polyline>, <rect>
,另外 <path>
可以用来定义任意形状,包括4中基本形状
rect
<rect x="50" y="10" width="30" height="30" rx="5" ry="5"></rect>
其中 rx, ry
用来定义圆角,分别表示四角的椭圆在 x
轴、 y
轴方向的半径。当然,用圆角画圆的技巧仍然适用:
<rect x="50" y="10" width="30" height="30" rx="50%" ry="50%"></rect>
x, y
表示左上角的坐标,坐标系与 canvas 2d
相同,左上角为 (0, 0)
circle
<circle cx="150" cy="25" r="15"></circle>
cx, cy
表示圆心位置
ellipse
<ellipse cx="200" cy="30" rx="25" ry="20"></ellipse>
rx, ry
分别表示 x
轴方向半径和 y
轴方向半径
line
<line x1="250" y1="10" x2="300" y2="30" style="stroke: black"></line>
注意,默认没有描边,看不见线,这里用 stroke
设置描边颜色
polygon
<polygon points="60,50 100,70 100,110 60,130 20,110 20,70"></polygon>
给定一组点,画出闭合多边形
polyline
<polyline points="150,50 190,70 190,110 150,130 110,110 110,70" style="fill: none; stroke: black"></polyline>
与多边形类似,折线不自动连接首尾
注意,默认填充黑色且没有描边,与上例多边形没有任何区别,这里用 fill
去掉填充色,用 stroke
添上黑色描边
2.path
通用形状定义,可以用来实现上面提到的所有形状,例如:
<path d="M 10 10 L 100 10 L 100 80 Z" style="fill: orange; stroke: black; stroke-width: 1"></path>
一个带黑色描边用橘黄色填充的直角三角形,属性 d
表示一系列路径描述,包含一些指令:
Moveto M提笔到 Lineto L画直线到 H画水平直线到 V画竖直直线到 Curveto C画三次贝塞尔曲线到(需要提供2个控制点) S与上一条三次贝塞尔曲线连起来(只需要提供第二个控制点和终点,第一个控制点是上一条曲线的第二个控制点的对称点) Q画二次贝塞尔曲线到(需要提供1个控制点) T与上一条二次贝塞尔曲线连起来(只需要提供终点,控制点是上一条曲线控制点的对称点) Arcto A画椭圆曲线到 ClosePath Z直线连接当前点和起点
注意,用 Z/z
闭合路径,与手动 L 起点
不同,因为闭合指令会让把线段端点拼接起来
各指令具体用法:
M x,y 绝对坐标 m dx,dy 相对坐标 L/l 同上 H/h 同上 V/v 同上 C/c c1x,c1y c2x,c2y x,y 控制点1 控制点2 终点 S/s cx,cy x,y 控制点2 终点 Q/q cx,cy x,y 控制点 终点 T/t x,y 终点 A rx,ry xAxisRotate LargeArcFlag,SweepFlag x,y x,y方向半径 x轴与水平轴顺时针夹角 [1/0]大/小角度弧线 [1/0]顺/逆时针到终点 终点 Z/z 无参,Z和z没有区别
例如:
<!-- 矩形 --> <path d="M 10 10 H 70 80 V 70 80 H 10 10 z" style="stroke: black"></path> <!-- 三次贝塞尔曲线 --> <path d="M 10 10 C 30 40 90 60 30 100 S 50 50 150 10 S 100 130 100 120" style="fill: none; stroke: black"></path>
P.S.关于 d
属性的更多信息,请查看:
3.文本
<text x="100" y="40" dx="10" dy="10" text-anchor="middle" rotate="10 10" style="font-family: Consola monospace; font-size: 24px; stroke: skyblue; fill: pink;"> SVG text styling </text>
x, y
, dx, dy
用于定位,前者绝对定位,后者相对自身偏移, text-anchor
用来定位文本(相对 x, y
左/右/居中对齐)
注意: rotate
属性很 神奇
,与 style="transform: rotate(10deg);"
整体旋转不同, rotate
属性是针对字符(glyph)的,可以传入一组值,按顺序分别作用于各个字符,所以可以用来实现类似于 斜体的效果
P.S.关于 rotate
属性的更多信息,请查看 Chapter 11: Text
4.样式
除了CSS支持的样式属性,SVG还支持一些特有的,例如 stroke
、 fill
等等,常见的如下:
fill 填充色,文本颜色也由该属性控制 stroke 描边颜色 stroke-width 描边宽度 stroke-linecap 端点样式,圆角,直角等等,与canvas一致,butt | round | square stroke-dasharray 虚线样式
也可以通过CSS选择器对SVG元素应用样式,例如:
<style>.line {stroke: red;}</style> <svg> <line class="line" x1="10" y1="10" x2="100" y2="80"></line> </svg>
但 SVG
里的 style
元素与HTML的不同,上面的方式等价于:
<svg> <style><![CDATA[ .newLine {stroke: red;} ]]></style> <line class="newLine" x1="10" y1="10" x2="100" y2="80"></line> </svg>
把样式规则用 CDATA
包起来是为了避免XML解析出错:
Note how the CSS style sheet is placed within a CDATA construct (i.e., <![CDATA[ … ]]>). Placing internal CSS style sheets within CDATA blocks is sometimes necessary since CSS style sheets can include characters, such as “>”, which conflict with XML parsers. Even if a given style sheet does not use characters that conflict with XML parsing, it is highly recommended that internal style sheets be placed inside CDATA blocks.
(引自 Styling-SVG 1.1(Second Edition) )
5.marker
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> <path d="M 10 10 C 50 80 40 20 120 50" fill="none" stroke="black" stroke-width="1" marker-end="url(#Triangle)"></path>
通过 defs
来定义可复用的元素,通过 id
来引用之前定义的 marker
元素, url(#Triangle)
叫Functional IRI reference
这里定义了一个箭头,并添到路径曲线的终点处,可选位置为:
marker-start 起点 marker-mid 各个中间点 marker-end 终点
marker
各属性含义如下:
viewBox 坐标系区域 refX/Y 参照点,绘制时该点与端点重合 markerUnits 定义坐标系单位 userSpaceOnUse当前坐标系单位 | strokeWidth线宽(默认) markerWidth/Height 标记宽高,默认值为3 orient 绘制方向,值为auto或角度值
默认 markerUnits="strokeWidth"
根据图形线宽自适应 marker
尺寸,如果 markerUnits="userSpaceOnUse"
的话,指定 marker
单位为当前坐标系单位,不会相对图形线宽调整
默认 orient="auto"
自动计算朝向角度,曲线上的箭头指向斜率方向,非常 精细自然
P.S.关于 marker
的更多信息,请查看 11 Painting: Filling, Stroking and Marker Symbols
6.滤镜
通过应用 filter
来改变渲染效果,让显示效果更好。使用方式与 marker
类似:
<defs> <filter id="blur"> <feGaussianBlur in="SourceGraphic" stdDeviation="5"/> </filter> </defs> <path d="M 10 20 C 50 80 40 20 120 60" fill="none" stroke="black" stroke-width="1" filter="url(#blur)"></path>
通过 feGaussianBlur
元素定义高斯模糊滤镜(毛玻璃效果),并设置模糊程度参数 stdDeviation
, in
用来设置应用滤镜的对象,这里 SourceGraphic
表示原图,也可以只对alpha通道或者背景图片(应用滤镜的整片区域快照)应用
此外还支持阴影、光照、颜色等滤镜,具体信息请查看 SVG element reference
7.渐变
支持线性渐变和放射性渐变,用法与 marker
类似,例如:
<defs> <linearGradient id="linear" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="0%" stop-color="#000"/> <stop offset="100%" stop-color="#fff"/> </linearGradient> <radialGradient id="radial"> <stop offset="10%" stop-color="#eee"/> <stop offset="95%" stop-color="#ccc"/> </radialGradient> </defs> <rect x="0" y="0" width="100%" height="50%" fill="url(#linear)"></rect> <rect x="0" y="50%" width="100%" height="50%" fill="url(#radial)"></rect>
分别定义了纯黑到纯白的竖直线性渐变、中心亮周围渐暗的放射性渐变
四.在线Demo
上文提到的所有示例: http://www.ayqy.net/temp/svg/svg.html
以上所述就是小编给大家介绍的《SVG基础知识》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。