SVG学习(二)

24 阅读6分钟

在实际生产中,制作svg更常用的方法是利用相关库。下载量比较高的就是svg.js了。它本身除了制作svg图形外,还已经封装好了动画,变形等函数。下面介绍它的使用方法。

官方文档地址:svgjs.dev/docs/3.2/

在工程化的项目中可以使用

npm install @svgdotjs/svg.js
import { SVG, extend as SVGextend, Element as SVGElement } from '@svgdotjs/svg.js'

其他时候可以用script标签来引入。需要注意的是使用时要在dom加载完成后使用

SVG.on(document, 'DOMContentLoaded', function() {
  var draw = SVG().addTo('body')
})

最主要的函数就是SVG(),它的作用是创建一个虚拟的svg容器。该函数会返回对应的SVG.Container。

SVG().addTo(),可以将svg容器挂载到页面上,参数既可以是‘#id’,‘.classNmae’这样的字符串,也可以是document.querySelector等方式获取到的具体元素。

如果想嵌套svg元素,则可以使用nested(),他会在一个svg容器内再创建出一个svg容器

var draw = SVG().addTo('#drawing')
var nested = draw.nested()
var rect = nested.rect(200, 200)

要创建group的话,可以使用group()

var group = draw.group()
group.path('M10,20L30,40')
group.add(rect)

这样,这些图形在表现形式上就都会在标签内了

symbol函数可以创建symbol标签,并且通过symbol来克隆图形

var symbol = draw.symbol()
symbol.rect(100, 100).fill('#f09')
var use  = draw.use(symbol).move(200, 200)

use函数会创建出use标签

defs函数可以创建defs标签

var defs = draw.defs()

link函数会创建出a标签,并且为这个a标签嵌入各种图形和链接地址

var link = draw.link('http://svgdotjs.github.io/')
var rect = link.rect(100, 100)

这样会让一个矩形成为a标签,点击后可以跳转。link.to可以更新链接地址,link.target('_blank')可以改变标签页打开方式。

除此之外还有两种方式创建链接

rect.linkTo('http://svgdotjs.github.io/')

rect.linkTo(function(link) {
  link.to('http://svgdotjs.github.io/').target('_blank')
})

在svg.js中创建元素的基本函数是element(),通过传入关键字来创建对应的元素,例如

var element = draw.element('title').words('This is a title.')

这样在页面中的svg标签内就会有一个title标签。也还是可以rect等元素

var element = draw.element('rect')element.attr({ x: 10, y: 10, width: 200, height: 50, fill: 'none', stroke: 'blue', 'stroke-width': 1 }) 

并且用attr函数来添加属性

在element函数基础上,svg.js拓展了更方便的创建图形元素的函数

rect函数用来创建矩形,两个参数分别是它的长和宽

circle函数用来创建圆形,参数是 直径

ellipse函数用来创建椭圆,参数是 x轴直径和y轴直径

line函数用来创建线段,参数是点阵集合,可以是多种形式

var line = draw.line(0, 0, 100, 150)
var line = draw.line().plot(0, 0, 100, 150)var line = draw.line([[0,0],[100,150]])
var line = draw.line().plot([[0, 0], [100, 150]])
import { PointArray } from '@svgdotjs/svg.js'var array = new PointArray([[0, 0], [100, 150]])var line = draw.line().plot(array).stroke({ width: 1 })

polyline可以用来创建折现,参数和line一样也是点阵集合,

polygon可以用来创建多边形,

path用来创建轨迹,参数就是画笔移动命令,还可以用来创建文字轨迹

var path = draw.path('M0 0 H50 A20 20 0 1 0 100 50 v25 C50 125 0 85 0 85 z').fill('none').stroke({ width: 1 })var textpath = path.text('SVG.js rocks!')

text函数用来创建文字,参数是字符串,支持用\n 换行,也可以传一个函数来创建

var text = draw.text(function(add) {
  add.tspan('Lorem ipsum dolor sit amet ').newLine()
  add.tspan('consectetur').fill('#f06')
  add.tspan('.')
  add.tspan('Cras sodales imperdiet auctor.').newLine().dx(20)
  add.tspan('Nunc ultrices lectus at erat').newLine()
  add.tspan('dictum pharetra elementum ante').newLine()
})

而plain方法会创建出一个不含tspan的纯文字,text.tspan函数可以用来创建tspan标签

textPath函数可以用来创建文字轨迹,它有两个参数,第一个是文字,第二个是画笔移动命令

image函数用来引入图片,第一个参数是图片地址,第二个参数是回调函数,如果要在图片加载中执行任何操作的话可以使用

gradient可以创建渐变效果,第一个参数是linear和radial,是线性和径向渐变。第二个参数是用来设置颜色的分布情况

var gradient = draw.gradient('linear', function(add) {
  add.stop(0, '#333')
  add.stop(1, '#fff')
})

pattern可以用来创建重复的,类似于棋盘格似的图形,它有三个参数,第一个是这个图形的width,第二个是height,第三个是对这个区域进行填充。

var draw = SVG().addTo('body').size(500, 130)
var pattern = draw.pattern(20, 20, function(add) {
  add.rect(20,20).fill('#f06')
  add.rect(10,10).fill('#0f9')
  add.rect(10,10).move(10,10).fill('#fff')
})
draw.rect(100, 100).move(20, 20).radius(10).fill(pattern)

最后,把它当作一种颜色一样,填充给图形就行

mask可以用来创建遮罩,就是一部分显示,另一部分隐藏的效果,具体使用如下

var draw = SVG().addTo('body').size(300, 130)
var circle = draw.circle(50).fill('#fff')
var mask = draw.mask()
mask.add(circle.center(35, 35))
mask.add(circle.clone().center(70, 70).size(70).fill('#ccc'))
mask.add(circle.clone().center(90, 30).size(30).fill('#999'))
mask.add(circle.clone().center(105, 115).size(50).fill('#333'))
var rect = draw.rect(100, 100).move(20, 20).fill('#f06')
rect.maskWith(mask)
rect.on('mouseover', function() {
	this.animate(300, '<>').fill('#0f9')
})
rect.on('mouseout', function() {
	this.animate(300, '<>').fill('#f06')
})

只有这几个圆形是可以显示区域,其他地方都会被隐藏起来

clipPath于遮罩类似,也是一部分显示另一部分隐藏,但不同的是裁剪会有一种边界融合的效果,遮罩则是重叠的。

var draw = SVG().addTo('body').size(300, 130)
var circle = draw.circle(50).fill('#fff')
var clip = draw.clip()
clip.add(circle.center(35, 35))
clip.add(circle.clone().center(70, 70).size(70).fill('#ccc'))
clip.add(circle.clone().center(90, 30).size(30).fill('#999'))
clip.add(circle.clone().center(105, 115).size(50).fill('#333'))
var rect = draw.rect(100, 100).move(20, 20).fill('#f06')
rect.clipWith(clip)
rect.on('mouseover', function() {
	this.animate(300, '<>').fill('#0f9')
})
rect.on('mouseout', function() {
	this.animate(300, '<>').fill('#f06')
})

use函数是利用已有的元素克隆出一模一样的元素,任何对两个元素的操作都会同步展现出来

marker是将某一个图形挂载到某一处上面,首先要设置一个宽高来画一个图形,再设置一个点将图形挂载到这个点上。可以设置start,mid和end

var draw = SVG().addTo('body')
var path = draw.path('M0 0 A50 50 0 0 1 50 50 A50 50 0 0 0 100 100')
path.fill('none').move(20, 20).stroke({ width: 1, color: '#ccc' })
path.marker('start', 10, 10, function(add) {
  add.circle(10).fill('#f06')
})
path.marker('mid', 10, 10, function(add) {
  add.rect(5, 10).cx(5).fill('#ccc')
})
path.marker('end', 20, 20, function(add) {
  add.circle(6).center(4, 5)
  add.circle(6).center(4, 15)
  add.circle(6).center(12, 10)
  this.fill('#0f9')
})

style函数可以创建style标签,foreignObject用来引入外部元素,一般是html。

更多使用细节,可以查看svgjs.dev/docs/3.0/sh…