前言
本文是在SVG.js 3.0
的前提上,和2.x
的API不一致。
官方文档:https://svgjs.dev/docs/3.0/getting-started/
这个库相比原生开发有以下几点优点:
- API调用简单
- 组件定位方式统一,比如原生圆形设置的是中心点,而矩形就又是左上角,这样设置位置的时候还要判断是什么图形,分别计算设置。
引用
1 | <script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js"></script> |
或者
1 | import { SVG } from '@svgdotjs/svg.js' |
简单示例
1 |
|
SVG()
1 | // 创建使用该方法 |
各种图形
1 | <!DOCTYPE html> |
效果
注意
polygon的实例生成后调用move方法会报错,这里建议用g包裹一下。
绘制虚线框
1 | var border_color = "#67aeef"; |
主要就是添加属性.attr("stroke-dasharray", "5,15")
;
更新线
1 | var line = that.mSvg.findOne(".line_" + lineid); |
获取线的数组 line.array();
这是一个二位数组。
更新线
1 | line.plot([ |
更新Path
1 | var path = draw.path('M10 10L90 90'); |
查找
1 | var path = SVG(".line_" + id); |
绘制线与箭头
1 | var path = draw.path("M0 0 A50 50 0 0 1 50 50 A50 50 0 0 0 100 100"); |
效果
直线和箭头
1 | var line = draw |
效果
容器
SVG.G
1 | var group = draw.group(); |
SVG.Symbol
Symbol相当于模板,模板中能够添加多个元素。
1 | var symbol = draw.symbol(); |
SVG.Defs
基本用法
1 | var defs = draw.defs(); |
对比
1 | var r1 = draw.rect(100, 100).fill("#f09"); |
我们会发现
前者相当于创建的模板定义,再使用,模板本身是不显示的。
后者是以现存的元素为模板复制了一份,两个元素都会显示。
Defs和Symbol
defs
与symbol
的相同点
defs
元素用于预定义一个元素使其能够在SVG图像中重复使用。symbol
元素用于定义可重复使用的符号。- 嵌入在
defs
或symbol
元素中的图形是不会被直接显示的,除非你使用
defs
与symbol
的不同点
- xlink定义了一套标准的在 XML 文档中创建超级链接的方法,可以用它来引用
元素或 内定义的元素和组。 - 一个
symbol
元素可以有preserveAspectRatio
和viewBox
属性。而g
元素不能拥有这些属性。
因此相比于在defs
元素中使用g
的方式来复用图形,使用symbol
元素也许是一个更好的选择。
Defs也相当于定义,不同与Symbol,定义本身不能直接use
,定义下的元素才能使用,要实现上面的效果还要用group
把多个元素包起来。
同样功能两者实现对比:
Symbol
1 | var symbol = draw.symbol(); |
Defs
1 | var defs = draw.defs(); |
SVG.A
1 | var link = draw.link('https://www.psvmc.cn') |
事件
1 | element.on(['click', 'mouseover'], function(event){ |
或者
1 | element.on('click mouseover', function(event){ |
标记
DOM添加类
1 | path.addClass("zline"); |
获取方式
1 | SVG.find(".zline").on('click', function (event) { |
可以通过选择器查找
1 | this.drawObj.find(".line_" + id); |
或者
1 | SVG(".line_" + id); |
DOM添加ID
1 | path.attr({id: "line_" + id}); |
获取方式
1 | SVG.find(".zline").on('click', function (event) { |
可以通过选择器查找
1 | this.mSvg.find("#line_" + id); |
或者
1 | SVG("#line_" + id); |
对象添加ID
下面这种是添加在了对象上,不是DOM上,不能通过选择器来查找
1 | path.id = "line_" + id; |
获取方式
1 | SVG.find(".zline").on('click', function (event) { |
查找元素
示例
SVG查找元素时支持按样式查找,所以在查找前,我们要先把元素添加样式元素上添加样式
我推荐的命名方式为,如果分组下的元素
分组的样式为g_{id}
,里面的元素为text_{id}
等。
1 | //文字的宽度 |
查找返回数组
1 | watch: { |
当然我们在查找时也可以取一个
1 | var t_obj = this.mSvg.findOne(".text_" + this.select_sharp.id); |
也可以这样写
1 | SVG(".text_" + this.select_sharp.id).text(this.select_sharp.text); |
官方文档
SVG()
returns
SVG.Dom
返回首个匹配的元素
1 | var rect = SVG('rect.my-class').fill('#f06') |
element.findOne()
returns
SVG.Dom
返回首个匹配的元素
1 | var rect = group.findOne('rect.my-class').fill('#f06') |
SVG.find()
returns
SVG.List
返回匹配到的元素列表
1 | var list = SVG.find('.someClass') |
可以设置第二个参数来限制搜索范围:
1 | var list = SVG.find('.someClass', group) |
element.find()
returns
SVG.List
返回匹配到的元素列表
1 | var list = group.find('.someClass') |
常用方法
删除
1 | element.remove() |
hide()
returns
itself
Hide element:
1 | element.hide() |
show()
returns
itself
Show (unhide) element:
1 | element.show() |
visible()
returns
boolean
To check if the element is visible:
1 | element.visible() |
SVG转图片
https://github.com/exupero/saveSvgAsPng
原生线的绘制
先看看原生的怎么实现
1 | <svg |
效果
三次贝塞尔曲线
我们先看一条贝塞尔曲线
1 | <path d="M10 10 C 50 10, 70 110, 110 110" stroke="1" fill="none"/> |
其中
M 是移动到,这里是曲线的起点。
后面的C/S是贝塞尔曲线的指令。
- C = curveto
- S = smooth curveto
三次贝塞尔曲线需要两个控制点。
假如我们要绘制的线的两个控制点(x1,y1)
和(x2,y2)
,曲线的终点(x,y)
。
使用C
三次贝塞尔曲线指令:
C x1 y1, x2 y2, x y
使用S
C指令有三个坐标参数,而S指令自动对称一个控制点,因此,跟在C指令之后的S指令,只需要2个参数哦,如下:
三次贝塞尔曲线指令:
S x2 y2, x y
S自动生成的另一个辅助点可能跟预想的不一样,建议使用C。
其他命令
其中路径描述包含如下命令:
- M = moveto 移动到某点。
- L = lineto 画一条直线到某点。
- H = horizontal lineto 画一条水平线到某点。
- V = vertical lineto 画一条垂直线到某点。
- Q = quadratic Bézier curveto 二次贝塞尔曲线
- T = smooth quadratic Bézier curveto 平滑二次贝塞尔曲线
- C = curveto 三次贝塞尔曲线
- S = smooth curveto 平滑三次贝塞尔曲线
- A = elliptical Arc 弧形
- Z = closepath 从结束点到开始点画一条直线,形成一个闭合的区域。
以上所有命令均允许小写字母:
- 大写表示绝对定位,绝对的参照点是svg最上角的那一点。
- 小写表示相对定位,相对的参照点是上一个位置。