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


Posted in Javascript onNovember 10, 2014

有人说不会 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 和时间都是不同的。

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

第一步:画草稿

做动画前第一步就是画草稿(如上图),我一般用 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 就不是一条均匀曲线这么简单了。

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

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

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

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

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",

    "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 一集关于动效的视频

Javascript 相关文章推荐
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
Mar 16 Javascript
基于vuejs+webpack的日期选择插件
May 21 Javascript
简单实现jQuery级联菜单
Jan 09 Javascript
Javascript中return的使用与闭包详解
Jan 11 Javascript
使用Bootstrap和Vue实现用户信息的编辑删除功能
Oct 25 Javascript
element-ui表格数据转换的示例代码
Aug 24 Javascript
Vue组件Draggable实现拖拽功能
Dec 01 Javascript
vue.js 2.0实现简单分页效果
Jul 29 Javascript
mpvue微信小程序开发之实现一个弹幕评论
Nov 24 Javascript
node.js中module模块的功能理解与用法实例分析
Feb 14 Javascript
js实现页面导航层级指示效果
Aug 25 Javascript
微信小程序实现单个或多个倒计时功能
Nov 01 Javascript
浅谈JavaScript 框架分类
Nov 10 #Javascript
使用script的src实现跨域和类似ajax效果
Nov 10 #Javascript
jquery插件推荐 jquery.cookie
Nov 09 #Javascript
jquery插件推荐浏览器嗅探userAgent
Nov 09 #Javascript
Javascript限制网页只能在微信内置浏览器中访问
Nov 09 #Javascript
js闭包的用途详解
Nov 09 #Javascript
js闭包实例汇总
Nov 09 #Javascript
You might like
thinkphp获取栏目和文章当前位置的方法
2014/10/29 PHP
php中curl使用指南
2015/02/05 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
OAuth认证协议中的HMACSHA1加密算法(实例)
2017/10/25 PHP
YII框架模块化处理操作示例
2019/04/26 PHP
COM中获取JavaScript数组大小的代码
2009/11/22 Javascript
Extjs学习笔记之八 继承和事件基础
2010/01/08 Javascript
jQuery getJSON()+.ashx 实现分页(改进版)
2013/03/28 Javascript
js中 关于undefined和null的区别介绍
2013/04/16 Javascript
JavaScript的内存释放问题详解
2015/01/21 Javascript
JS获取及设置TextArea或input文本框选择文本位置的方法
2015/03/24 Javascript
在Mac OS下使用Node.js的简单教程
2015/06/24 Javascript
全面了解JavaScript的数据类型转换
2016/07/01 Javascript
jquery移除了live()、die(),新版事件绑定on()、off()的方法
2016/10/26 Javascript
利用JS判断鼠标移入元素的方向
2016/12/11 Javascript
深入理解Javascript中的valueOf与toString
2017/01/04 Javascript
详解Vue2.X的路由管理记录之 钩子函数(切割流水线)
2017/05/02 Javascript
通过命令行生成vue项目框架的方法
2017/07/12 Javascript
Vue.js实现输入框绑定的实例代码
2017/08/24 Javascript
seajs中模块依赖的加载处理实例分析
2017/10/10 Javascript
详解Node.js中path模块的resolve()和join()方法的区别
2018/10/29 Javascript
atom-design(Vue.js移动端组件库)手势组件使用教程
2019/05/16 Javascript
vue实现移动端触屏拖拽功能
2020/08/21 Javascript
python实现根据ip地址反向查找主机名称的方法
2015/04/29 Python
在Python程序中操作文件之isatty()方法的使用教程
2015/05/24 Python
Selenium的使用详解
2018/10/19 Python
使用虚拟环境打包python为exe 文件的方法
2019/08/29 Python
Python如何使用OS模块调用cmd
2020/02/27 Python
Champs Sports加拿大:北美最大的以商场为基础的专业运动鞋和服装零售商之一
2018/05/01 全球购物
澳大利亚在线性感内衣商店:Fantasy Lingerie
2021/02/07 全球购物
数据库基础的一些面试题
2012/02/25 面试题
财务总经理岗位职责
2014/02/16 职场文书
党的群众路线教育实践活动宣传方案
2014/02/23 职场文书
cf战队收人广告词
2014/03/14 职场文书
Python实现的扫码工具居然这么好用!
2021/06/07 Python
解析目标检测之IoU
2021/06/26 Python