SVG 学习笔记 - 2
基本上是按照这套教程学习的
SVG 中的坐标系统和坐标变换
视野与世界
世界是无穷大的,视野是观察世界的一个矩形区域
-
width height - 控制视窗,浏览器开辟出来用来渲染SVG内容的区域
-
SVG 代码 - 定义世界
-
viewBox, preserveAspectRatio - 控制视野,观看SVG的矩形区域
红色代表视窗
<svg width="300" height="200"
style="border: 1px solid red;"
viewBox="0 0 600 300"
preserveAspectRatio="xMidYMid meet">
<circle cx="150" cy="150" r="80" stroke-width="20" stroke="#00A5E0" fill="none"></circle>
<rect stroke="blue" stroke-width="3.5" fill="none" x="0" y="0" width="600" height="300"/>
<text>蓝色代表视野</text>
</svg>
SVG 中的图形分组
SVG 中使用
标签进行分组,特点
- 属性继承
- transform 属性定义坐标变换
- 可以嵌套使用
坐标系统
概述
- 笛卡尔直角坐标系 Y轴向下 X轴向右
- 原点
- 互相垂直的两条数轴
- 角度定义 角度是X轴正方向到Y轴正方向的方向
SVG 四个坐标系
1.用户坐标系
原始的坐标系(世界坐标系),viewBox 的基准,其他坐标系也是根据他产生的
2.自身坐标系
每个图形或者图形分组自身带有的坐标系,通过给自身设置 transform 属性 ,可以相对于前驱坐标系,重新修改自身坐标系的位置,相当于坐标系在整体移动,自身设置的相对于自身坐标系的x\y不会改变
3.前驱坐标系
就是父容器的坐标系
4.参考坐标系
就是任意的坐标系,选取参考坐标系,是为了方便描述图形情况
坐标变换
数学上:坐标变换就是采用一定的数学方法将一个坐标系的坐标变换为另一个坐标系坐标的过程
SVG 中:坐标变换指对一个坐标系到另一个坐标系的变换描述
线性变换
本质是线性方程
transform 属性
定义前驱坐标系到自身坐标系的线性变换
rotate(<deg>)
translate(<x>, <y>)
scale(<sx>, <sy>)
matrix(<a>, <b>, <c>, <d>, <e>, <f>)
渐变等绘图
颜色表示
SVG 支持css3的颜色表示方法
RGB 表示法
rgb(r,g,b) 每个分量取值范围[0,255],优势:显示器容易解析;劣势:不符合人类描述颜色的习惯
HSL 表示法
hsl(h, s%, l%) 三个分量分别表示颜色、饱和度、亮度,取值范围h:[0,359] s,l:[0, 100]
优势是符合人类描述习惯
透明度 rgba() hsla() opacity
-
1
<svg width="100" height="100">
<rect x="0" y="0" width="70" height="30" rx="10" fill="rgba(220,20,20,0.5)" />
<rect x="0" y="40" width="70" height="30" rx="10" fill="hsla(200,90%,80%,0.8)" />
</svg>
渐变
线性渐变
<linearGradient>
和<stop>
<linearGradient>
参数 x1,y1, x2,y2 分别代表起始点和结束点;gradientUnits 设置参考坐标系,默认为当前图形,x1等单位为百分比,设置为 userSpaceOnUse 则定义为用户坐标系,x1等单位为长度
- 1
<svg width="100" height="100">
<defs>
<linearGradient id="grad1" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#1497fc" />
<stop offset="0.6" stop-color="#a478be" />
<stop offset="1" stop-color="#ff8c00" />
</linearGradient>
<linearGradient id="grad2" gradientUnits="userSpaceOnUse"
x1="10" y1="10" x2="100" y2="100">
<stop offset="0" stop-color="#1497fc" />
<stop offset="0.4" stop-color="#a478be" />
<stop offset="1" stop-color="#ff8c00" />
</linearGradient>
</defs>
<rect x="0" y="0" width="70" height="30" rx="10" fill="url(#grad1)" />
<rect x="0" y="40" width="70" height="30" rx="10" fill="url(#grad2)" />
</svg>
径向渐变
<radialGradient>
和<stop>
<radialGradient>
参数 cx, cy:圆形中心坐标 r : 半径 fx,fy : 焦点坐标
-
1
<svg width="300" height="350">
<defs>
<radialGradient id="grad12" cx="0.5" cy="0.5" r="0.5" fx="0.1" fy="0.7">
<stop offset="0" stop-color="#1497fc" />
<stop offset="0.6" stop-color="#a478be" />
<stop offset="1" stop-color="#ff8c00" />
</radialGradient>
<radialGradient id="grad22" gradientUnits="userSpaceOnUse" x1="10" y1="10" x2="100" y2="100">
<stop offset="0" stop-color="#1497fc" />
<stop offset="0.4" stop-color="#a478be" />
<stop offset="1" stop-color="#ff8c00" />
</radialGradient>
</defs>
<rect x="0" y="0" width="200" height="150" rx="10" fill="url(#grad12)" />
<rect x="0" y="160" width="200" height="150" rx="10" fill="url(#grad22)" />
</svg>
笔刷 绘制文理
<pattern>
标签 patternUnits patternContentUnits 属性
-
1
<svg width="300" height="150">
<defs>
<pattern id="p1" x="0" y="0" width="20" height="20"
patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="5" fill="hsla(8,90%,70%,0.9)" />
</pattern>
</defs>
<rect x="0" y="0" width="300" height="150" rx="10" fill="url(#p1)" stroke="red" stroke-width="1" />
</svg>
Path 路径
可以绘制任意图形
path 字符串
<path d="M0,0L10,20C30-10,40,20,100,100" stroke="red" />
- 1
<svg>
<path d="M0,0L10,20C30-10,40,20,100,100" stroke="red" fill="none"/>
</svg>
d 属性就是path 字符串 L : 命令; 10,20 :参数 参数之间可以用空格或","
命令基本规律
- 区分大小写:大写表示坐标参数为绝对位置,小写则是相对位置(相对上一个命令结束画笔停留位置)
- 最后的参数表示画笔最终要到达的位置
- 上一个命令结束后的位置,就是下一个命令开始的位置
- 命令可以重复参数表示重复执行同一条命令
移动和直线命令
-
M(x, y) 移动画笔,后面如果有重复参数,会当做是L命令处理
-
L(x, y) 绘制直线到指定的位置
-
H(x) 绘制水平线到指定的x位置
-
V(y) 绘制水平线到指定的y位置
-
m、l、h、v使用相对位置绘制(相对上一个命令的结束点)
-
1
<svg>
<path d="M10,10L40,40l20,10h100v50l50,0"
stroke="red" fill="none"/>
</svg>
弧线命令
A(rx, ry, xr, laf, sf, x, y)
绘制弧线(定义为椭圆的一部分)
-
rx 弧线所在椭圆的 x 半轴长
-
ry 弧线所在椭圆的 y 半轴长
-
xr 弧线所在椭圆的旋转角度
-
laf 1:选择大角度对应弧线 0:选择小角度对应弧线
-
sf 1:选择顺时针方向的弧线 0:选择逆时针方向的弧线
-
x,y 弧的终点位置
<svg width="200" height="200">
<path d="M10,10h100M10,10v150A100,150,0,0,0,110,10" stroke="red" fill="hsla(110,80%,80%,0.9)"/>
</svg>
贝塞尔曲线命令
1.二次贝塞尔曲线命令(Q),需要知道三个点的位置(起始点、结束点、控制点)
Mx0,y0Qx1,y1,x,y
-
x0,y0 起始点坐标
-
x1,y1 控制点坐标
-
x,y 结束点坐标
<svg >
<path d="M10,10Q100,60,50,100" stroke="red" fill="none"/>
</svg>
2.三次贝塞尔曲线命令©,需要知道四个点的位置(起始点、结束点、两个控制点)
Mx0,y0Cx1,y1,x2,y2,x,y
-
x0,y0 起始点坐标
-
x1,y1 控制点1坐标
-
x2,y2 控制点2坐标
-
x,y 结束点坐标
<svg width="150" height="150">
<path d="M0,50C50,10,30,100,100,50" stroke="red" fill="none"/>
</svg>
光滑贝塞尔曲线
将上一个贝塞尔曲线(控制点数量相同)的最后一个控制点的镜像作为光滑版的第一个控制点,得到的是一个连续的光滑曲线
-
T:Q的光滑版本(二次)
Mx0,y0Qx1,y1,x,yTx2,y2
-
S:C的光滑版本(三次)
Mx0,y0Cx1,y1,x2,y2,x,ySx3,y3,x4,y4
<svg width="100" height="100">
<path d="M0,50C20,10,30,100,50,50S50,120,100,100" stroke="red" fill="none"/>
</svg>
<svg width="100" height="100">
<path d="M0,50Q20,10,50,50T20,100" stroke="red" fill="none"/>
</svg>
SVG 文本
<text>
和 <tspan>
标签
<text x="0"></text>
-
x,y : 起始位置坐标
-
dx,dy : 相较于前一个字符的偏移值
-
1
ABCDEFGHIGKLMNOPPQRSTUVWXY
<svg width="100%" height="300">
<defs>
<!-- 背景 -->
<pattern id="p2" x="0" y="0" width="20" height="20"
patternUnits="userSpaceOnUse">
<path stroke="#ccc" fill="none" d="M0,0H20V20">
</pattern>
</defs>
<!-- 背景平铺 -->
<rect x="0" y="0" width="100%"
height="300" rx="10"
fill="url(#p2)"
stroke="red"
stroke-width="1" />
<!-- 坐标线 -->
<path d="M100,0V900M0,100H900" stroke="red"/>
<!-- dy 的值 需要根据 dx 的值 进行 sin 运算 ,这里直接复制 -->
<text id="sintext" x="100" y="100" dx="20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20" dy="0 7.788366846173011 14.347121817990455 18.640781719344528 19.9914720608301 18.185948536513635 13.509263611023012 6.699763003118093 -1.1674828685516017 -8.85040886589705 -15.136049906158565 -19.032041477790322 -19.92329217671681 -17.66909311440306 -12.625332757446417 -5.588309963978517 2.330984097009873 9.88226702277218 15.873357276983064 19.35839344062973 19.787164932467636 17.09197816176561 11.698343857835233 4.4577982820049185 -3.486535624459628 -10.880422217787395" style="font-size:14px">
ABCDEFGHIGKLMNOPPQRSTUVWXY
</text>
</svg>
<tspan>
标签,文字样式
-
dx,dy : 相较于前一个字符的偏移值
-
1
<svg width="300" height="150">
<defs>
<pattern id="p2" x="0" y="0" width="20" height="20"
patternUnits="userSpaceOnUse">
<path stroke="#ccc" fill="none" d="M0,0H20V20">
</pattern>
</defs>
<rect x="0" y="0" width="300" height="150" rx="10" fill="url(#p2)" stroke="red" stroke-width="1" />
<path d="M100,0V900M0,100H900" stroke="red"/>
<text id="sintext" x="100" y="100" style="font-size:30px">
<tspan fill="red"> SVG </tspan>
<tspan stroke="green" fill="none"> TEXT </tspan>
</text>
</svg>
注意 嵌套的dy dx 会覆盖 而不是叠加
居中
水平居中属性
text-anchor
- start : 起始
- middle : 居中
- end : 结尾
路径文本 <textpath>
使用方法
-
1
<svg width="100%" height="300">
<defs>
<pattern id="p2" x="0" y="0" width="20" height="20"
patternUnits="userSpaceOnUse">
<path stroke="#ccc" fill="none" d="M0,0H20V20">
</pattern>
</defs>
<rect x="0" y="0" width="100%" height="300" rx="10" fill="url(#p2) stroke="red stroke-width="1"/>
<path d="M150,0V900M0,150H900" stroke="red"/>
<path id="path1" d="M150,150C290,10,500,290,800,150" fill="none" stroke="hsl(126, 100%, 20%)"/>
<text id="text" style="font-size: 26px" fill="#c29" dy="-10">
<textpath id="textpath" xlink:href="#path1">
文字会按照曲线路径走动 Text will walk according to the curve path
</textpath>
</text>
</svg>
超链接 <a>
-
可以添加到任意图形上
-
xlink:href 指定链接地址
-
xlink:title 指定链接提示
-
target指定打开目标
<svg xmlns:“http://www.w3.org/2000/svg” width=“100%” height=“200”>
<svg xmlns:"http://www.w3.org/2000/svg" width="100%" height="200">
<a xlink:href="http://www.baidu.com">
<rect x="50" y="50" width="100" height="100" fill="rgba(255, 0, 0, .5" stroke="rgb(200,0,0)" />
</a>
</svg>