SVG基础知识

栏目: 后端 · 前端 · 发布时间: 6年前

内容简介: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来实现,例如 d3google 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 元素尺寸为 100x100pxsvg 元素默认 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, ydx, dy 用于定位,前者绝对定位,后者相对自身偏移, text-anchor 用来定位文本(相对 x, y 左/右/居中对齐)

注意: rotate 属性很 神奇 ,与 style="transform: rotate(10deg);" 整体旋转不同, rotate 属性是针对字符(glyph)的,可以传入一组值,按顺序分别作用于各个字符,所以可以用来实现类似于 斜体的效果

P.S.关于 rotate 属性的更多信息,请查看 Chapter 11: Text

4.样式

除了CSS支持的样式属性,SVG还支持一些特有的,例如 strokefill 等等,常见的如下:

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 元素定义高斯模糊滤镜(毛玻璃效果),并设置模糊程度参数 stdDeviationin 用来设置应用滤镜的对象,这里 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基础知识》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

超越门户

超越门户

吴晨光 / 中国人民大学出版社 / 2015-4-17 / 39.80

在这个PC端影响力下降、人们对手机的依赖与日俱增的时代,这种探索的意义非同寻常,可以说是试图树立新媒体时代的行业标准。 ——陈彤(小米内容投资与运营副总裁、新浪网前总编辑、资深网络媒体人) 我将对此书的阅读,视作对往日岁月的怀念,它提醒我,自己曾 投身于多么富有蓬勃朝气和探索精神的事业。而对这种事业的原则、逻辑和方法的继承和继续学习,对于互联网时代的企业形象塑造 ,同样有融会变通的参考......一起来看看 《超越门户》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器