svg动画类库Snap.svg简介
2019-07-05 本文已影响0人
belllee
SVG元素是一种特殊的DOM元素,可以使用CSS以及一般的JS类库来实现动画控制。但是这些方法都没提供SVG动画样式属性的完整控制,现在介绍一个专门的SVG动画类库Snap.svg,其github地址为:https://github.com/adobe-webplatform/Snap.svg
安装
Snap.svg提供多种安装方式。
HTML直接加载JS方式
<script src="snap.svg-min.js"></script>
// Manual Minified - https://github.com/adobe-webplatform/Snap.svg/raw/master/dist/snap.svg-min.js
// Manual Unminified - https://raw.githubusercontent.com/adobe-webplatform/Snap.svg/master/dist/snap.svg.js
//注意:上面url直接添加到src无法正常下载
//错误信息:Refused to execute script from 'https://.../snap.svg-min.js' because its MIME type ('text/plain') is not executable.
//是服务端返回类型错误,浏览器无法解析。可以手工下载到本地使用。
webpack加载方式
// 支持npm或者bower下载
bower install snap.svg
npm install snapsvg
// webpack配置
module: {
rules: [
{
test: require.resolve('snapsvg/dist/snap.svg.js'),
use: 'imports-loader?this=>window,fix=>module.exports=0',
},
],
},
resolve: {
alias: {
snapsvg: 'snapsvg/dist/snap.svg.js',
},
},
// 引用
import Snap from 'snapsvg';
Snap.svg动画基本实现步骤
// 1、在HTML中添加SVG
<svg id="demo1" width="300" height="300"></svg>
// 2、SVG中图形元素初始化
let svg = Snap('#demo1');
let circle = svg.select('.circle'); //如果SVG中已有实际图形元素,直接选择器初始化
let circle = svg.circle(150, 150, 10);//如果SVG中没有实际图形元素,调用方法创建化
// 3、修改属性和时间参数,实现动画设置。例如一秒钟内,圆半径变为100px
circle.animate({ r: 100 }, 1000, mina.easeout(), () => {
//动画结束,doSomething
});
Snap.svg常用API介绍
Snap(...)
功能描述: 创建或加载已有的SVG元素。
参数说明:
参数形式 | 参数类型 | 参数说明 | 备注 |
---|---|---|---|
(width, height) | 数字 | 创建新SVG的宽和高 | |
(DOM) | 对象 | 根据DOM对象加载SVG | |
(arry) | 数组 | 根据元素数组返回SVG元素数组 | |
(query) | 字符串 | 根据JS选择器加载SVG |
返回值: SVG元素
Element.select(query)
功能描述: 根据JS选择器加载SVG元素内已有的图形元素。
参数说明:
参数形式 | 参数类型 | 参数说明 | 备注 |
---|---|---|---|
query | 字符串 | 图形元素JS选择器定义 |
返回值: 选择器命中的元素Element,当存在多个命中的元素时,只返回第一个元素
Paper.circle(x, y, r)
功能描述: 在SVG元素内绘制一个圆。
参数说明:
参数形式 | 参数类型 | 参数说明 | 备注 |
---|---|---|---|
x | 数字 | 圆心X轴坐标 | |
y | 数字 | 圆心X轴坐标 | |
r | 数字 | 半径 |
返回值: 新建的circle元素Element
Paper.path([pathString])
功能描述: 在SVG元素内绘制一条Path。
参数说明:
参数形式 | 参数类型 | 参数说明 | 备注 |
---|---|---|---|
pathString | 字符串 | path的d属性值 |
返回值: 新建的path元素Element
Paper.rect(x, y, width, height, [rx], [ry])
功能描述: 在SVG元素内绘制一个矩形。
参数说明:
参数形式 | 参数类型 | 参数说明 | 备注 |
---|---|---|---|
x | 数字 | 矩形左上角X轴坐标 | |
y | 数字 | 矩形左上角Y轴坐标 | |
width | 数字 | 矩形宽度 | |
height | 数字 | 矩形高度 | |
rx | 数字 | 圆角的水平半径 | |
ry | 数字 | 圆角的垂直半径 |
返回值: 新建的rect元素Element
Snap.animation(attr, duration, [easing], [callback])
功能描述: 在一段时间内匀速变更相关属性到目标值。
参数说明:
参数名称 | 参数类型 | 参数说明 | 备注 |
---|---|---|---|
attr | 对象 | 属性目标值 | |
duration | 数字 | 动画持续总时长,单位MS | |
easing | 函数 | 自定义或者mina定义的缓动函数 | 控制移动速度是匀速还是加减速 |
callback | 函数 | 动画结束时回调函数 |
返回值: 动画对象
Snap.animate(from, to, setter, duration, [easing], [callback])
功能描述: 根据设置的参数,执行动画操作。
参数说明:
参数名称 | 参数类型 | 参数说明 | 备注 |
---|---|---|---|
from | 数字/数组 | 动画的启始帧数 | |
to | 数字/数组 | 动画的结束帧数 | |
setter | 函数 | 动画帧设置参数,该函数可传入当前帧数 | |
duration | 数字 | 动画持续总时长,单位MS | |
easing | 函数 | 自定义或者mina定义的缓动函数 | |
callback | 函数 | 动画结束时回调函数 |
返回值: mina格式的动画对象
Matrix.translate(x, y)
功能描述: 执行位移操作。
参数说明:
参数名称 | 参数类型 | 参数说明 | 备注 |
---|---|---|---|
x | 数字 | 水平移动距离,单位是像素 | |
y | 数字 | 垂直移动距离,单位是像素 |
Matrix.rotate(a, x, y)
功能描述: 使推行围绕指定的圆心,旋转一定角度。
参数说明:
参数名称 | 参数类型 | 参数说明 | 备注 |
---|---|---|---|
a | 数字 | 旋转角度,单位是度 | |
x | 数字 | 旋转圆心的水平位置,单位是像素 | |
y | 数字 | 旋转圆心的垂直位置,单位是像素 |
常见动画效果的示例
尺寸缩放
初始化参考上面“基本实现步骤”中的相关描述,后续只描述动画控制部分。
// 圆形半径缩放,在1S内半径从10,放大到100,动画效果是缓出
let circle = svg.circle(150, 150, 10);
circle.animate({ r: 100 }, 1000, mina.easeout(), () => {
//动画结束,doSomething
});
// 矩形长宽缩放,在2S内宽度100缩小到10,长度200缩小到20,动画效果是缓入
let rect = svg.circle(0, 0, 100, 200);
rect.animate({ width: 10, height:20 }, 2000, mina.easein(), () => {
//动画结束,doSomething
});
颜色渐变
// 圆形填充色渐变,3S内从绿色变成蓝色,动画效果是缓出
let circle = svg.circle(150, 150, 100).attr({
fill: "#bada55",
stroke: "#000",
strokeWidth: 5
});
circle.animate({ fill: "#0059b3", }, 3000, mina.easeout(), () => {
//动画结束,doSomething
});
线条渐变
// 1S内线条从起始态变换到终止态,动画效果是缓出
// 起始态:任意形状
let path = svg.paper.path({d: 'M0.500,65.500 C18.680,33.758 45.141,-6.797 72.500,2.500 C99.859,11.797 72.148,59.027 79.500,98.500 C86.852,137.973 117.668,128.914 138.500,59.500 C159.332,-9.914 246.500,59.500 246.500,59.500 C273.181,117.750 137.350,184.417 225.500,173.500 C351.137,157.940 155.369,160.617 162.500,86.500 C165.180,58.645 237.169,-2.418 283.500,2.500 C357.654,10.371 363.758,80.355 364.500,109.500',stroke:'#f00', fill: 'rgba(0,0,0,0)'});
// 终止态:心形
path.animate({d: 'M114.500,58.500 C106.230,58.751 23.907,-37.262 5.500,21.500 C-26.759,124.483 111.761,221.360 119.500,219.500 C154.464,211.096 201.234,149.580 220.500,104.500 C250.260,34.864 220.892,7.159 194.500,1.500 C160.455,-5.800 122.344,58.262 114.500,58.500 Z'}, 1000, mina.easeout(), () => {
//动画结束,doSomething
});
位置移动
// 1S内矩形移动100次,从(0,0)移动到(100,200),动画效果是缓出
let rect = svg.paper.rect({x: 0, y: 0, width: 50, height: 30, fill: '#f00'});
Snap.animate(0, 100, (val) => {
let m = new Snap.Matrix();
m.translate(val, val * 2); // translate位移API
rect.transform(m); // 在rect节点应用matrix
}, 1000, mina.easeout(), () => {
//动画结束,doSomething
});
位置移动
// 1S内矩形围绕矩形的中心旋转100次,完成旋转一周,动画效果是缓出
let rect = svg.paper.rect({x: 10, y: 10, width: 50, height: 30, fill: '#f00'});
Snap.animate(0, 100, (val) => {
let m = new Snap.Matrix();
m.rotate((val/100)*360, 35, 25); // 注意,旋转中心是矩形的中心
rect.transform(m); // 在rect节点应用matrix
}, 1000, mina.easeout(), () => {
//动画结束,doSomething
});