SVG元素是一種特殊的DOM元素,可以使用CSS以及一般的JS類(lèi)庫(kù)來(lái)實(shí)現(xiàn)動(dòng)畫(huà)控制。但是這些方法都沒(méi)提供SVG動(dòng)畫(huà)樣式屬性的完整控制,現(xiàn)在介紹一個(gè)專(zhuān)門(mén)的SVG動(dòng)畫(huà)類(lèi)庫(kù)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無(wú)法正常下載
//錯(cuò)誤信息:Refused to execute script from 'https://.../snap.svg-min.js' because its MIME type ('text/plain') is not executable.
//是服務(wù)端返回類(lèi)型錯(cuò)誤,瀏覽器無(wú)法解析??梢允止は螺d到本地使用。
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動(dòng)畫(huà)基本實(shí)現(xiàn)步驟
// 1、在HTML中添加SVG
<svg id="demo1" width="300" height="300"></svg>
// 2、SVG中圖形元素初始化
let svg = Snap('#demo1');
let circle = svg.select('.circle'); //如果SVG中已有實(shí)際圖形元素,直接選擇器初始化
let circle = svg.circle(150, 150, 10);//如果SVG中沒(méi)有實(shí)際圖形元素,調(diào)用方法創(chuàng)建化
// 3、修改屬性和時(shí)間參數(shù),實(shí)現(xiàn)動(dòng)畫(huà)設(shè)置。例如一秒鐘內(nèi),圓半徑變?yōu)?00px
circle.animate({ r: 100 }, 1000, mina.easeout(), () => {
//動(dòng)畫(huà)結(jié)束,doSomething
});
Snap.svg常用API介紹
Snap(...)
功能描述: 創(chuàng)建或加載已有的SVG元素。
參數(shù)說(shuō)明:
| 參數(shù)形式 | 參數(shù)類(lèi)型 | 參數(shù)說(shuō)明 | 備注 |
|---|---|---|---|
| (width, height) | 數(shù)字 | 創(chuàng)建新SVG的寬和高 | |
| (DOM) | 對(duì)象 | 根據(jù)DOM對(duì)象加載SVG | |
| (arry) | 數(shù)組 | 根據(jù)元素?cái)?shù)組返回SVG元素?cái)?shù)組 | |
| (query) | 字符串 | 根據(jù)JS選擇器加載SVG |
返回值: SVG元素
Element.select(query)
功能描述: 根據(jù)JS選擇器加載SVG元素內(nèi)已有的圖形元素。
參數(shù)說(shuō)明:
| 參數(shù)形式 | 參數(shù)類(lèi)型 | 參數(shù)說(shuō)明 | 備注 |
|---|---|---|---|
| query | 字符串 | 圖形元素JS選擇器定義 |
返回值: 選擇器命中的元素Element,當(dāng)存在多個(gè)命中的元素時(shí),只返回第一個(gè)元素
Paper.circle(x, y, r)
功能描述: 在SVG元素內(nèi)繪制一個(gè)圓。
參數(shù)說(shuō)明:
| 參數(shù)形式 | 參數(shù)類(lèi)型 | 參數(shù)說(shuō)明 | 備注 |
|---|---|---|---|
| x | 數(shù)字 | 圓心X軸坐標(biāo) | |
| y | 數(shù)字 | 圓心X軸坐標(biāo) | |
| r | 數(shù)字 | 半徑 |
返回值: 新建的circle元素Element
Paper.path([pathString])
功能描述: 在SVG元素內(nèi)繪制一條Path。
參數(shù)說(shuō)明:
| 參數(shù)形式 | 參數(shù)類(lèi)型 | 參數(shù)說(shuō)明 | 備注 |
|---|---|---|---|
| pathString | 字符串 | path的d屬性值 |
返回值: 新建的path元素Element
Paper.rect(x, y, width, height, [rx], [ry])
功能描述: 在SVG元素內(nèi)繪制一個(gè)矩形。
參數(shù)說(shuō)明:
| 參數(shù)形式 | 參數(shù)類(lèi)型 | 參數(shù)說(shuō)明 | 備注 |
|---|---|---|---|
| x | 數(shù)字 | 矩形左上角X軸坐標(biāo) | |
| y | 數(shù)字 | 矩形左上角Y軸坐標(biāo) | |
| width | 數(shù)字 | 矩形寬度 | |
| height | 數(shù)字 | 矩形高度 | |
| rx | 數(shù)字 | 圓角的水平半徑 | |
| ry | 數(shù)字 | 圓角的垂直半徑 |
返回值: 新建的rect元素Element
Snap.animation(attr, duration, [easing], [callback])
功能描述: 在一段時(shí)間內(nèi)勻速變更相關(guān)屬性到目標(biāo)值。
參數(shù)說(shuō)明:
| 參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 參數(shù)說(shuō)明 | 備注 |
|---|---|---|---|
| attr | 對(duì)象 | 屬性目標(biāo)值 | |
| duration | 數(shù)字 | 動(dòng)畫(huà)持續(xù)總時(shí)長(zhǎng),單位MS | |
| easing | 函數(shù) | 自定義或者mina定義的緩動(dòng)函數(shù) | 控制移動(dòng)速度是勻速還是加減速 |
| callback | 函數(shù) | 動(dòng)畫(huà)結(jié)束時(shí)回調(diào)函數(shù) |
返回值: 動(dòng)畫(huà)對(duì)象
Snap.animate(from, to, setter, duration, [easing], [callback])
功能描述: 根據(jù)設(shè)置的參數(shù),執(zhí)行動(dòng)畫(huà)操作。
參數(shù)說(shuō)明:
| 參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 參數(shù)說(shuō)明 | 備注 |
|---|---|---|---|
| from | 數(shù)字/數(shù)組 | 動(dòng)畫(huà)的啟始幀數(shù) | |
| to | 數(shù)字/數(shù)組 | 動(dòng)畫(huà)的結(jié)束幀數(shù) | |
| setter | 函數(shù) | 動(dòng)畫(huà)幀設(shè)置參數(shù),該函數(shù)可傳入當(dāng)前幀數(shù) | |
| duration | 數(shù)字 | 動(dòng)畫(huà)持續(xù)總時(shí)長(zhǎng),單位MS | |
| easing | 函數(shù) | 自定義或者mina定義的緩動(dòng)函數(shù) | |
| callback | 函數(shù) | 動(dòng)畫(huà)結(jié)束時(shí)回調(diào)函數(shù) |
返回值: mina格式的動(dòng)畫(huà)對(duì)象
Matrix.translate(x, y)
功能描述: 執(zhí)行位移操作。
參數(shù)說(shuō)明:
| 參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 參數(shù)說(shuō)明 | 備注 |
|---|---|---|---|
| x | 數(shù)字 | 水平移動(dòng)距離,單位是像素 | |
| y | 數(shù)字 | 垂直移動(dòng)距離,單位是像素 |
Matrix.rotate(a, x, y)
功能描述: 使推行圍繞指定的圓心,旋轉(zhuǎn)一定角度。
參數(shù)說(shuō)明:
| 參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 參數(shù)說(shuō)明 | 備注 |
|---|---|---|---|
| a | 數(shù)字 | 旋轉(zhuǎn)角度,單位是度 | |
| x | 數(shù)字 | 旋轉(zhuǎn)圓心的水平位置,單位是像素 | |
| y | 數(shù)字 | 旋轉(zhuǎn)圓心的垂直位置,單位是像素 |
常見(jiàn)動(dòng)畫(huà)效果的示例
尺寸縮放
初始化參考上面“基本實(shí)現(xiàn)步驟”中的相關(guān)描述,后續(xù)只描述動(dòng)畫(huà)控制部分。
// 圓形半徑縮放,在1S內(nèi)半徑從10,放大到100,動(dòng)畫(huà)效果是緩出
let circle = svg.circle(150, 150, 10);
circle.animate({ r: 100 }, 1000, mina.easeout(), () => {
//動(dòng)畫(huà)結(jié)束,doSomething
});
// 矩形長(zhǎng)寬縮放,在2S內(nèi)寬度100縮小到10,長(zhǎng)度200縮小到20,動(dòng)畫(huà)效果是緩入
let rect = svg.circle(0, 0, 100, 200);
rect.animate({ width: 10, height:20 }, 2000, mina.easein(), () => {
//動(dòng)畫(huà)結(jié)束,doSomething
});
顏色漸變
// 圓形填充色漸變,3S內(nèi)從綠色變成藍(lán)色,動(dòng)畫(huà)效果是緩出
let circle = svg.circle(150, 150, 100).attr({
fill: "#bada55",
stroke: "#000",
strokeWidth: 5
});
circle.animate({ fill: "#0059b3", }, 3000, mina.easeout(), () => {
//動(dòng)畫(huà)結(jié)束,doSomething
});
線條漸變
// 1S內(nèi)線條從起始態(tài)變換到終止態(tài),動(dòng)畫(huà)效果是緩出
// 起始態(tài):任意形狀
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)'});
// 終止態(tài):心形
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(), () => {
//動(dòng)畫(huà)結(jié)束,doSomething
});
位置移動(dòng)
// 1S內(nèi)矩形移動(dòng)100次,從(0,0)移動(dòng)到(100,200),動(dòng)畫(huà)效果是緩出
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節(jié)點(diǎn)應(yīng)用matrix
}, 1000, mina.easeout(), () => {
//動(dòng)畫(huà)結(jié)束,doSomething
});
位置移動(dòng)
// 1S內(nèi)矩形圍繞矩形的中心旋轉(zhuǎn)100次,完成旋轉(zhuǎn)一周,動(dòng)畫(huà)效果是緩出
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); // 注意,旋轉(zhuǎn)中心是矩形的中心
rect.transform(m); // 在rect節(jié)點(diǎn)應(yīng)用matrix
}, 1000, mina.easeout(), () => {
//動(dòng)畫(huà)結(jié)束,doSomething
});