即SVG,是W3C XML的分支语言之一,用于标记可缩放的矢量图形。
元素是SVG基本形状中最强大的一个,它不仅能创建其他基本形状,还能创建更多其他形状。
先欣赏下svg path的魅力
基础直线命令
M x y
M 指moveto 这里可以认为是move to (x,y)
这里是不会显示任何东西的 因为一个二维图形是需要三个点
这时候就需要我们使用
H x (or h dx)
V y (or v dy)
绘制下一个移动方向
比如
从(10,10)出发至 (90,10) 打下断点 再跑到 (90,90)
这里注意下 H 是绘制水平线 后面是终点
V 是绘制垂直线
恭喜你 学会用svg画一个三角形了
通过一个“闭合路径命令”Z我们可以完成闭合
基础曲线命令
绘制平滑曲线的命令有三个,其中两个用来绘制贝塞尔曲线,另外一个用来绘制弧形或者说是圆的一部分
C命令创建三次贝塞尔曲线,需要设置三组坐标参数:
C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)
绘制半椭圆形
这里大家可能不太明白
我们由mdn的官方图片可以看出
贝尔曲线由四个控制点来控制
即(10 10)(20 20)(40 20)( 50 10)
Q命令
C命令很强大 但是如果全部使用C命令 代码就会变得又乱又难懂
那么有没有简便的写法呢
Q命令 了解下
Q x1 y1, x y (or q dx1 dy1, dx dy)
使用Q命令画一个曲线
从(10, 60) 经过中心点 (95,10) 至 结束点 (180,60)
弧形命令
那么有没有快速话椭圆的方法呢
弧形命令是一个比较复杂的命令弧形命令A是另一个创建SVG曲线的命令。基本上,弧形可以视为圆形或椭圆形的一部分。假设,已知椭圆形的长轴半径和短轴半径,另外已知两个点(它们的距离在圆的半径范围内),这时我们会发现,有两个路径可以连接这两个点。每种情况都可以生成出四种弧形。所以,为了保证创建的弧形唯一,A命令需要用到比较多的参数:
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
rx: 弧形的x轴长度
ry: 弧形的y轴长度
x-axis-rotation: x轴旋转角度
large-arc-flag: large-arc-flag决定弧线是大于还是小于180度,0表示小角度弧,1表示大角度弧
sweep-flag: 表示弧线的方向,0表示从起点到终点沿逆时针画弧,1表示从起点到终点沿顺时针画弧
x: 终点x
y: 终点y
这里我们一个一个解析
先移动到 (80,80) 展开一个45 45的圆 终点(125 125)
那么L 125 80命令呢
先看下没有这命令会怎么样
z命令闭合时 就会画出一个去了直角三角形部分弧形
large-arc-flag决定弧线是大于还是小于180度,0表示小角度弧,1表示大角度弧。
如果我们这时候改变为1
上面的原理图也早就说 明了 两个点之间 有内圆 外圆
sweep-flag表示弧线的方向,0表示从起点到终点沿逆时针画弧,1表示从起点到终点沿顺时针画弧
sweep-flag 实际上就是改变两个圆之间裁剪选择 大家可以尝试下
水波浪svg 的分布解析
好了我们现在来逐步解析水波浪的代码
第一步我们先实现一个波浪曲线
从(0 150)点出发 中心点(75 120) 到 (150 150)结束
从(150 150) 开始画一条 到(150 300)的垂直线
从 (150 300)开始画一条 到 (0 300)的垂直线
从 (0 300)开始画一条 到 (0 150)的垂直线
熟悉了第一步我们在尝试一下画个下波峰
Q命令 从(0 150)点出发 中心点(75 120) 到 (150 150)结束
Q命令 从(150 150)点出发 中心点(225 180) 到 (300 150)结束
从(300 150) 开始画一条 到(300 300)的垂直线
从 (300 300)开始画一条 到 (0 300)的垂直线
从 (0 300)开始画一条 到 (0 150)的垂直线
水波是有规律的 一个波峰 一个波谷 顺序前行
根据这个规律 我们使用javascript 动态生成一条波浪
// 75 120 150 150
// 225 180 300 150
// 375 120,450 150
// 525 180,600 150
var pathd = "M 0 150 ";
var bofeng = [
[75, 120],
[150, 150]
]
var boguo = [
[225, 180],
[300, 150]
]
function nextCircle(bofeng) {
var center = bofeng[0];
var end = bofeng[1];
center[0] = center[0] + 300;
end[0] = end[0] + 300;
}
var width = 0;
function genNode(node) {
width = node[1][0];
return ` Q ${node[0][0]} ${node[0][1]}, ${node[1][0]} ${node[1][1]}`;
}
// nextBofeng(bofeng);
pathd += genNode(bofeng);
pathd += genNode(boguo);
for (var i = 2; i <= 5; i++) {
if (i % 2 === 1) {
nextCircle(boguo);
pathd += genNode(boguo);
}
if (i % 2 === 0) {
nextCircle(bofeng);
pathd += genNode(bofeng);
}
}
pathd += " V 300 H 0 V 150 z";
document.getElementById("svgcontainer").setAttribute("width", width);
document.getElementById("wave_loading").setAttribute("d", pathd)