使用 Snap.svg 制作动画

2017/02/22 · HTML5 ·
SVG

原文出处: 凹凸实验室   

bet36365注册送奖金 1

前端必备神器 Snap.svg 弹动效果,前端snap.svg

有人说不会 SVG 的前端开发者不叫开发者,而叫爱好者。前端不光是 Angularjs
了,这时候再不学 SVG 就晚了!(如果你只会 jQuery
就当我没说。。。)这里我就给大家分享一个前几天在别处看到的一个高大上的
SVG 效果,左边菜单弹出来会动动弹的说,链接点这里。

当时我就震惊了,今天抽空搞清了源码,然后下面是我潜心研究后做出来的
Demo,虽然比较粗糙,但还是很洋气的感觉呢。下面我就这个 DEMO
跟大家分享一下。

http://jsfiddle.net/windwhinny/n6w1ur5k/3/

本案例需要有些 PS 或者 AI
中路径的知识,下面是本例中运涉及到的知识点和工具:

snap.svg
svg path data
Adobe Illustrator
animation timing

先给出原理:根据时间变换坐标。如下图所示,本例其实就是 A、B、C
三条线之间的转换,A 是初始状态,点击后经过 B 最后形成
C。其中有两次动画,分别是 A-B 和 B-C,而这两次动画的 timing function
和时间都是不同的。

bet36365注册送奖金 2

第一步:画草稿

做动画前第一步就是画草稿(如上图),我一般用 AI 来画,因为 AI
可以精确的控制元素尺寸和位置,而且其原理和 SVG 是一样的。

然后有的同学就会说,“老湿,是不是要保存为 SVG 格式的,然后做修改啊?”

画草稿图的目的只是为了方便的确定每个点的坐标,自己算太麻烦了,而且还容易出错。除此之外
AI 没有任何作用。AI 生成的 SVG
文件在此例中根本不能拿来用,因为其中的路劲点太混乱了,下面会详说。

什么?你不会用 AI ?

如果你还想在前端这条路上走下去的话,那现在就去学吧。(在这里我想吐槽一下,PS
是用来处理点阵图片的,根本不适合拿来做设计图。相比之下 AI
才是做这个的,google 给出的 metrial design 布局模板全都是 AI
格式的。但国内不管是什么企业,用 PS 都好像很开心的样子,不知道为什么。)

第二步:计算路径

这一步就比较复杂了,上面说过了,这个动画其实就是坐标之间转换。而从四边形到圆弧之间的转换不光是坐标位移而已,还有曲线弧度的转换。上面的设计图直接保存为
SVG 后代码如下:

复制代码 代码如下:

<?xml version=”1.0″ encoding=”utf-8″?>
<!– Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG
Version: 6.00 Build 0)  –>
<svg version=”1.1″ id=”图层_1″ xmlns=”http://www.w3.org/2000/svg
xmlns:xlink=”http://www.w3.org/1999/xlink” x=”0px” y=”0px”
     viewBox=”0 0 175 175″ enable-background=”new 0 0 175 175″
xml:space=”preserve”>
<!– 路径 A –>
<path fill=”none” stroke=”#BF3A41″ stroke-miterlimit=”10″ d=”
    M12.5,12.5
    h75
    h75
    v75
    v75
    h-75
    h-75
    v-35
    V12.5z”/>
<!– 路径 B –>
<path fill=”none” stroke=”#0000FF” stroke-miterlimit=”10″ d=”
    M37.5,37.5
    c0,0,10-25,50-25
    s50,25,50,25
    s25,10,25,50
    s-25,50-25,50
    s-10,25-50,25
    s-50-25-50-25
    s-25.1-10-25.1-50
    S37.5,37.5,37.5,37.5z”/>
<!– 路径 C –>
<path fill=”none” stroke=”#000000″ stroke-miterlimit=”10″ d=”
    M37.5,37.5
    h50
    h50
    v50
    v50
    h-50
    h-50
    v-50
    V37.5z”/>
</svg>

我们只需要关注路径的 d 属性就行了,可以看出,AB
两个路径之间还是可以互相转换的,但他们和 C
路径(有弧线的路径)之间就不能转换了。他们所用到的绘图命令都不同,AB
两个都是矩形,绘图时用到的都是
h、v,也就是横纵之间的位移,画出来的都是横竖线。而 C 路劲用到的都是
s、c这些命令,画出来的都是曲线。所以 AI 给出来的图我们不能用,要自己根据
svg path data 重新绘制一遍。

下面我参照 AI 设计图重新绘制的三条路径:

复制代码 代码如下:

<!– 路径 A –>
<path d=”
    M37.5,37.5
    S87.5,37.5,87.5,37.5
    S137.5,37.5,137.5,37.5
    S137.5,87.5,137.5,87.5
    S137.5,137.5,137.5,137.5
    S87.5,137.5,87.5,137.5
    S37.5,137.5,37.5,137.5
    S37.5,87.5,37.5,87.5
    S37.5,37.5,37.5,37.5z”>
<!– 路径 B –>
<path d=”
    M 37.5,37.5
    S47.5,12.5,87.5,12.5
    S127.5,25,137.5,37.5
    S162.5,47.5,162.5,87.5
    S150,127.5,137.5,137.5
    S127.5,162.5,87.5,162.5
    S47.5,150,37.5,137.5
    S12.5,127.5,12.5,87.5
    S25,47.5,37.5,37.5z”>
<!– 路径 C –>
<path d=”
    M12.5,12.5
    S87.5,12.5,87.5,12.5
    S162.5,12.5,162.5,12.5
    S162.5,87.5,162.5,87.5
    S162.5,162.5,162.5,162.5
    S87.5,162.5,87.5,162.5
    S12.5,162.5,12.5,162.5
    S12.5,127.5,12.5,127.5
    S12.5,12.5,12.5,12.5z”>

有过设计基础的同学应该明白上面代码的含义,就是将所有锚点转换成平滑,然后再更改手柄的位置。形状没变,虽然代码多了不少,但是把绘制命令都变成了
S ,这样三条路径就只有数值之间的不同了。而动画的过程就是数值之间的转换。

第三步:Timing

这一步就是设定动画的时间点和 timing function 。时间点比较好说,A-B 和
B-C 我设置的分别是300毫秒和400毫秒。

timing function 就是我们在做 CSS 动画中运用到的
animation-timing-function 属性,比较常见的有
ease、linear、easein,我们也可以用贝塞尔曲线自己定制。但是CSS的 timing
function 比较简单,只能定义一条均匀的曲线,A-B 转换用到的 ease-out,但是
B-C 为了体现弹动的效果,所用到的 timing-function
就不是一条均匀曲线这么简单了。

bet36365注册送奖金 3

上面列出了一些比较常用的 timing-function ,其中大概分为
ease、bounce、elastic 三类。ease
一般用作减速或者加速动效。bounce如同他的曲线图一样,一般用作小球落地那种动效。而
elastic
一般用在如琴弦一样的动效上,这种动效一个特点就是有部分偏移到负坐标上了,而
B-C 用到的就是这个,如下图。

bet36365注册送奖金 4

根据上面已经画出来的路径,结合动画,代码就出来了:

复制代码 代码如下:

var svg=Snap(“#svg”);
var pathes=[
   
“M37.5,37.5S87.5,37.5,87.5,37.5S137.5,37.5,137.5,37.5S137.5,87.5,137.5,87.5
S137.5,137.5,137.5,137.5S87.5,137.5,87.5,137.5S37.5,137.5,37.5,137.5S37.5,87.5,37.5,87.5S37.5,37.5,37.5,37.5z”,
    “M 37.5,37.5 S47.5,12.5,87.5,12.5 S127.5,25,137.5,37.5
S162.5,47.5,162.5,87.5 S150,127.5,137.5,137.5 S127.5,162.5,87.5,162.5
S47.5,150,37.5,137.5 S12.5,127.5,12.5,87.5 S25,47.5,37.5,37.5z”,
bet36365注册送奖金,   
“M12.5,12.5S87.5,12.5,87.5,12.5S162.5,12.5,162.5,12.5S162.5,87.5,162.5,87.5S162.5,162.5,162.5,162.5S87.5,162.5,87.5,162.5S12.5,162.5,12.5,162.5S12.5,127.5,12.5,127.5S12.5,12.5,12.5,12.5z”
];

var path=svg.path(pathes[0]);

path.attr({
    fill:”#2E70FF”
});

function animateIn(callback){
    path.animate({
        d:pathes[1]
    },300,mina.easeout,function(){
        path.animate({
            d:pathes[0]
        },400,mina.elastic,callback)
    });
};

function animateOut(callback){
    path.animate({
        d:pathes[1]
    },300,mina.easeout,function(){
        path.animate({
            d:pathes[2]
        },400,mina.elastic,callback)
    });
};

Snap 是 Adobe 出品处理 SVG 的库,mina是 Snap
自带的一个动画工具集,其中有很多预设的动画。

结语

用 Snap 制作的动画可以兼容 IE9
,而且速度也不错,自定义功能很强大。相信不久的将来还会有更多狂拽酷炫屌炸天的动效会用
Snap 制作出来。

如果想学习动效的话,可以先看一下 TED 一集关于动效的视频

http://www.bkjia.com/Javascript/908665.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javascript/908665.htmlTechArticle前端必备神器 Snap.svg 弹动效果,前端snap.svg
有人说不会 SVG 的前端开发者不叫开发者,而叫爱好者。前端不光是 Angularjs
了,这时候再不学…

一、Snap.svg是什么

从主要功能上说,Snap.svg.js 是一个操纵 SVG 节点/制作 SVG
动画的框架,简单点理解可以看下面文字:

Snap.svg 是一个可以使你操纵 SVG 资源和 jQuery 操作 DOM 一样简单的类库

——译自官网

拿 Snap.svg (下文简称 Snap ) 和 jQuery (下文简称 JQ )
来做对比最合适不过,很可能作者也是参考了 JQ 的 API
设计,那么它们的相似程度有多高呢?请看下面的对比表:

/ context(上下文) 选择器 事件绑定 节点操作 属性操作 链式写法
Snap svg Snap.select(‘circle’) el.click(…)/el.touchend(…) after()/remove()/append() attr() svg.paper.circle(50,50,40).attr({fill:”#f00”});
JQ document jQuery(‘div’) el.click(…) after()/remove()/append() attr() elem.addClass(‘hide’).remove();

在 JQ 中,可操作的最外层 DOM 边界是 document 。而在 Snap
的概念里,可操作的最外层的节点是 svg ,svg
节点的选择、事件绑定都需要在这个上下文里完成。

在上面的对比图可以看出很多 JQ
的影子,无论是选择器、事件绑定、节点操作等等,都是非常的类似 JQ ,有 JQ
基础的同学基本可以半天掌握 Snap 的全部 API。

二、Snap 的代码结构

bet36365注册送奖金 5

笔者根据 Snap 的 API
制作了上面的图表,并且简单标注了注释方便大家理解,可以重点关注一下
Element 和 Paper 这两个类。

1. Element

这个部分是节点操作相关的方法集,也是该类库最基础的部分。

JavaScript

// 选择节点 var svg = Snap(‘#svg’); svg.select(‘circle’); // 选择
svg.select(‘.rect_01’); // 选择

1
2
3
4
// 选择节点
var svg = Snap(‘#svg’);
svg.select(‘circle’); // 选择
svg.select(‘.rect_01’); // 选择

JavaScript

// 事件绑定 var svg = Snap(‘#svg’);
svg.select(‘circle’).click(function() { // do something });

1
2
3
4
5
// 事件绑定
var svg = Snap(‘#svg’);
svg.select(‘circle’).click(function() {
// do something
});

更多方法请参考文后 API 资料。

2. Paper

这部分是画图相关的方法集,这是几乎每个动画框架都有的部分,类似于createjsGraphics

SVG
有6种基本图形:矩形、圆形
、椭圆、线条、折线、多边形。还有另外一种:路径(path),path
是最复杂的一种绘图方式,它可以绘制复杂的图形——当然6种基本图形也不在话下。而关于基本图像与
path 之间的转换,可以参考本站的另外一篇文章:聊聊 SVG
基本形状转换那些事

bet36365注册送奖金 6

Paper
方法集主要可以绘制6种基本图形(节点),以及文本(节点)、图片(节点)、渐变等。

JavaScript

// 画一个圆 var svg = Snap(‘#svg’); svg.paper.circle({ cx: 100, cy:
100, r: 50, fill: ‘#f00’ });   // 创建一张图片
svg.paper.image(‘url.jpg’, 0, 400, 300, 300);

1
2
3
4
5
6
7
8
9
10
11
// 画一个圆
var svg = Snap(‘#svg’);
svg.paper.circle({
cx: 100,
cy: 100,
r: 50,
fill: ‘#f00’
});
 
// 创建一张图片
svg.paper.image(‘url.jpg’, 0, 400, 300, 300);

3. Snap 工具方法

Snap下有不少实用工具,比如
Snap.ajax、Snap.format模板、颜色格式转换和插件方法等。

JavaScript

// 扩展Snap,为其添加插件方法 Snap.plugin(function (Snap, Element,
Paper, global, Fragment) { Snap.newmethod = function () {};
Element.prototype.newmethod = function () {}; Paper.prototype.newmethod
= function () {}; });

1
2
3
4
5
6
// 扩展Snap,为其添加插件方法
Snap.plugin(function (Snap, Element, Paper, global, Fragment) {
Snap.newmethod = function () {};
Element.prototype.newmethod = function () {};
Paper.prototype.newmethod = function () {};
});

三、用 Snap 制作动画

1. 制作动画的方法

Snap 的做动画主要有两种方式:

  • 使用 Element 里的 animate 方法,Element.animate(attrs, duration,
    [easing], [callback])
  • 使用 Snap 的静态方法,Snap.animate(from, to, setter, duration,
    [easing],
    [callback]),这种方法更通用也更强大,指定开始结束值,setter里面可以放置多个节点的动画。

样例:演示Element.animate方法的使用。预览地址点此

JavaScript

// 动画样例1 var svg = Snap(‘#svg’); svg.select(‘circle’).animate({r:
100}, 1000, mina.easeout(), function() { console.log(‘animation end’);
});   // 动画样例2 var svg = Snap(‘#svg’); var circle =
svg.select(‘circle’); var rect = svg.select(‘rect’); Snap.animate(0,
100, function(val) { circle.attr({r: val}); rect.attr({x: val}); },
1000, mina.easeout(), function() { console.log(‘animation end’); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 动画样例1
var svg = Snap(‘#svg’);
svg.select(‘circle’).animate({r: 100}, 1000, mina.easeout(), function() {
console.log(‘animation end’);
});
 
// 动画样例2
var svg = Snap(‘#svg’);
var circle = svg.select(‘circle’);
var rect = svg.select(‘rect’);
Snap.animate(0, 100, function(val) {
circle.attr({r: val});
rect.attr({x: val});
}, 1000, mina.easeout(), function() {
console.log(‘animation end’);
});

bet36365注册送奖金 7

2. 动画的属性

在 Snap 中,可作为动画的属性有哪些呢?笔者大致分为了几类:

  • 简单数值类,如坐标、宽高、opacity、大部分 Paper API
    可配置的属性值,甚至滤镜相关的属性。如{x:100} -> {x:200},
    {width:0} -> {width:100}
  • path 相关动画,如d属性(变形动画)、描边动画、路径跟随动画
  • matrix 类,放大缩小、位移、旋转等,和 CSS 的 transform 类似
  • 颜色类,颜色变换动画,如 fill、stroke 属性,如{fill:’#f00’} ->
    {fill:’#f0f’}

样例:颜色变换动画,预览地址点此

JavaScript

// 动画样例,颜色变化动画 var svg = Snap(‘#svg’); var circle =
svg.paper.circle({cx: 100, cy: 100, r: 50, fill: ‘#f00’});
circle.animate({fill: ‘#00f’}, 1000, mina.easeout(), function() {
console.log(‘animation end’); });

1
2
3
4
5
6
// 动画样例,颜色变化动画
var svg = Snap(‘#svg’);
var circle = svg.paper.circle({cx: 100, cy: 100, r: 50, fill: ‘#f00’});
circle.animate({fill: ‘#00f’}, 1000, mina.easeout(), function() {
console.log(‘animation end’);
});

bet36365注册送奖金 8

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图