SVG (一) 图形, 路径, 变换总结; 以及椭圆弧线, 贝塞尔曲线的详细解释

原文发表自我的博客

近期工作中要处理很多 SVG 图片, 所以从零开始学习了 SVG 的相关内容.
我看的是这本书 SVG Essentials, 2nd Edition,以及它的中译版 SVG精髓(第2版).
这本书深入浅出, 例子很多, 非常不错. 因为 svg 涉及到很多关于颜色的内容, 所以还是建议大家看电子版.

工作中的任务是实现一个相框功能, 当中涉及到了诸如 use, image, clip-path 的内容, 学习了一段时间后总算解决了, 所以希望记录一下学习内容和解决方案.
内容比较多, 所以准备开一个系列, 这是 SVG 系列的第一篇, 基础知识总结. 后续将会有更多关于 SVG 的内容. 敬请期待!

SVG basics

Shape Reference Summary

形状 描述
<line x1="start-x" y1="start-y" x2="end-x" y2="end-y"/> 直线: 起点(start-x, start-y) 终点(end-x, end-y);
<rect x="left-x" y="top-y" width="width" height="height" /> 矩形: 左上角(left-x, top-y), 宽高 width, height
<circle cx="center-x" cy="center-y" r="radius"/> : 圆心(center-x, center-y) 半径 r
<ellipse cx="center-x" cy="center-y" rx="x-radius" ry="y-radius"/> 椭圆: 圆心(center-x, center-y) xy轴半径 rx, ry
<polygon points="points-list"/> 多边形: 由一系列坐标组成, points-list: x1 y1 x2 y2 x3 y3 ....
<polyline points="points-list"/> 折线: 由一系列坐标组成, points-list: x1 y1 x2 y2 x3 y3 ....

Path Reference Summary

本质上, 上述基本形状都是路径(path)的简写. 简写可以使得 svg 文档更具有可读性. 但是当碰到复杂路径时, 就需要 path 来描述. 以下总结中, 凡是出现大写字母表示后续坐标为绝对坐标, 凡是小写字母都代表相对于上一个坐标的相对位移. Z 同 z 无差别. 因为表示闭合, 其后不用跟坐标

command 描述
M(m) x y 移动到(x, y) (小写表示相对于上个坐标的位移, 下同)
L(l) x y 画一条直线到(x, y)
H(h) x 水平画一条直线到 x
V(v) y 竖直画一条直线到 y
A(a) rx ry x-axis-rotation large-arc sweep x y 画一段到(x,y)的椭圆弧. 椭圆弧的 x, y 轴半径分别为 rx,ry. 椭圆相对于 x 轴旋转 x-axis-rotation 度. large-arc=0表明弧线小于180读, large-arc=1表示弧线大于180度. sweep=0表明弧线逆时针旋转, sweep=1表明弧线顺时间旋转. 具体解释看如何绘制椭圆弧
Q(q) cx cy x y 从当前点画一条到(x, y)的二次贝塞尔曲线, 曲线的控制点为(cx, cy). 关于二次贝塞尔曲线请看[二次贝塞尔曲线详解](#articleHeader6
T(t) x y 此命令只能跟在一个 Q 命令使用, 假设 Q 命令生成曲线 s, T 命令的作用是从 s 的终点再画一条到(x y)的二次贝塞尔曲线, 曲线的控制点为 s 控制点关于 s 终点的对称点. T 命令生成的曲线会非常平滑
C(c) cx1 cy1 cx2 cy2 x y 从当前点画一条到(x, y)的三次贝塞尔曲线, 曲线的开始控制点和终点控制点为别为 (cx1, cy1), (cx2, cy2). 关于三次贝塞尔曲线请看三次贝塞尔曲线详解
S(s) cx2 cy2 x y 此命令只能跟在 C 命令后使用, 假设 C 命令生成曲线 s, S 命令的作用是再画一条到 (x, y)的三次贝塞尔曲线, 曲线的终点控制点是 (cx2, cy2), 曲线的开始控制点是 s 的终点控制点关于 s 终点的对称点.

Transformation Reference Summary

transform 描述
translate(x, y) 平移: 将用户坐标系统的坐标原点移动到(x, y)
scale(xFactor, yFactor) 缩放: 将用户坐标系统的xy轴单位长度分别乘(xFactor, yFactor)倍
scale(factor) 缩放: 同 scale(factor, factor)
rotate(angle, centerX, centerY) 旋转: 将用户坐标系统以(centerX, centerY)为旋转中心顺时针旋转 angle 度
rotate(angle) 旋转: 同 rotate(angle, 0, 0)
skewX(angle) 倾斜: 根据 angle 倾斜所有 x 轴坐标, 视觉上会看到 y 轴倾斜...
skewY(angle) 倾斜: 根据 angle 倾斜所有 y 轴坐标, 视觉上会看到 x 轴倾斜...
matrix(a b c d e f) 矩阵变换: 将坐标系统进行矩阵变换, 详细内容请参考后续文章

Details

Ellipse

一种直观的表示椭圆弧线的方式是, 根据椭圆中心 (x, y), x 轴半径 rx, y 轴半径 ry, 开始角度 startAngle, 结束角度 endAngle.
但是为什么 SVG 会采用 A(a) rx ry x-axis-rotation large-arc sweep x y 这样的形式呢,
主要是因为在 SVG 中, 弧线并不是孤立的存在, 他要成为整体的一部分. 所以 SVG 采用了起始点这样的方式.
那么其他的 x-axis-rotation, large-arc, sweep 又是什么意思呢? 我们现在来看下面这张图.

图片描述

当确定了两个点已经椭圆的 rx, ry 后并不能唯一确定一条椭圆弧, 实际上根据是否是大圆, 路径是否是逆时针可以产生四条 (b, c, d, e)
其中, large-arc-flag=0 表示小圆, sweep-flag=0 表示逆时针.

那么 x-axis-rotation 又是什么意思呢? b, c, d, e 产生的前提是 椭圆的 x 轴与用户坐标系的 x 轴是平行的.
f 图表示椭圆 x 轴相对于用户坐标系的 x 轴旋转30度所产生的椭圆弧. 灰色的部分表示原来产生的椭圆弧.

Quadratic Bezier

关于贝塞尔曲线的数学含义请看Bézier curve
这里直观的讲一下

图片描述

以上曲线的路径表示是: <path d="M200,300 Q400,50 600,300 T1000,300"/>
我们可以看出:
A 是起点, B 是终点, C 就是控制点.
找出 AC 的重点 D, BC 的重点 E, 连接 DE, 找出其中点 F, F 即这条曲线前半段的一个切点.

这里不谈数学含义, 这样的几何意义更加直观.

再来看 T 命令, 其实 T 命令是 Q 的一个简写.
其控制点 H 就是上个 Q 命令的控制点 C 关于终点 B 的对称点.
使用 T 命令产生的曲线往往比较顺滑 :)

Cubic Bezier

再来看一下三次贝塞尔曲线

图片描述

<path d="M100,200 C100,100 250,100 250,200 S400,300 400,200"/>

前半段曲线(C 命令) s1:
起点 A, 终点 B, 起点控制点 C, 终点控制点 D, 连接 AC, BD, CD;
找到 CD 中点 F, 连接 AC 中点 E 与 F, 连接 BD 中点 G 与 F;
连接 EF, FG, 连接 EF 中点 H 与 FG 中点 I;
I 即为前半段曲线的切点;

后半段曲线(S 命令) s2:
S 只能跟在 C 命令后使用;
s2 的起点 B, 终点 L, 终点控制点 K;
s2 的起点控制点是 s1 的终点控制点 D 关于 s1终点 B 的对称点

下图是更多关于三次贝塞尔曲线的例子:

图片描述

Reference

阅读 16.3k

推荐阅读

前端打怪升级记录 分享即进步 :)

15 人关注
9 篇文章
专栏主页