前端必备神器 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 相关文章推荐
javascript与CSS复习(《精通javascript》)
Jun 29 Javascript
IE8下String的Trim()方法失效的解决方法
Nov 08 Javascript
倒记时60刷新网页的js代码
Feb 18 Javascript
什么是 AngularJS?AngularJS简介
Dec 06 Javascript
JS日期对象简单操作(获取当前年份、星期、时间)
Oct 26 Javascript
深入掌握 react的 setState的工作机制
Sep 27 Javascript
微信小程序下拉刷新PullDownRefresh的使用方法
Nov 29 Javascript
vue全局自定义指令-元素拖拽的实现代码
Apr 14 Javascript
js canvas实现5张图片合成一张图片
Jul 15 Javascript
IE11下CKEditor在Bootstrap Modal中下拉问题的解决
Sep 25 Javascript
vue 获取及修改store.js里的公共变量实例
Nov 06 Javascript
js在HTML的三种引用方式详解
Aug 29 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
PHP隐形一句话后门,和ThinkPHP框架加密码程序(base64_decode)
2011/11/02 PHP
PHP __autoload()方法真的影响性能吗?
2012/03/30 PHP
浅谈PHP与C#的值类型指向区别的详解
2013/05/21 PHP
PHP实现自动登入google play下载app report的方法
2014/09/23 PHP
php计算到指定日期还有多少天的方法
2015/04/14 PHP
PHP将Excel导入数据库及数据库数据导出至Excel的方法
2015/06/24 PHP
Linux下安装Memcached服务器和客户端与PHP使用示例
2019/04/15 PHP
How to Auto Include a Javascript File
2007/02/02 Javascript
HTA版JSMin(省略修饰语若干)基于javascript语言编写
2009/12/24 Javascript
js实现日期级联效果
2014/01/23 Javascript
JS实现IE状态栏文字缩放效果代码
2015/10/24 Javascript
Javascript实现图片加载从模糊到清晰显示的方法
2016/06/21 Javascript
把普通对象转换成json格式的对象的简单实例
2016/07/04 Javascript
Vue.js组件使用开发实例教程
2016/11/01 Javascript
canvas实现钟表效果
2017/02/13 Javascript
详解ng-alain动态表单SF表单项设置必填和正则校验
2019/06/11 Javascript
关于vue项目中搜索节流的实现代码
2019/09/17 Javascript
Vue封装Axios请求和拦截器的步骤
2020/09/16 Javascript
VUE中鼠标滚轮使div左右滚动的方法详解
2020/12/14 Vue.js
Python 获得13位unix时间戳的方法
2017/10/20 Python
利用python实现简单的邮件发送客户端示例
2017/12/23 Python
Python实现k-means算法
2018/02/23 Python
python使用正则表达式来获取文件名的前缀方法
2018/10/21 Python
Python rabbitMQ如何实现生产消费者模式
2020/08/24 Python
Scrapy爬虫文件批量运行的实现
2020/09/30 Python
Expedia泰国:预订机票、酒店和旅游包(航班+酒店)
2016/09/27 全球购物
Puritan’s Pride(普丽普莱)官方网站:美国最大最全的保健品公司之一
2016/10/23 全球购物
酒店员工检讨书
2014/02/18 职场文书
办公室岗位职责
2015/02/04 职场文书
昆虫记读书笔记
2015/06/26 职场文书
运动会宣传语
2015/07/13 职场文书
公务员岗前培训心得体会
2016/01/08 职场文书
技术转让协议书
2016/03/19 职场文书
诗词赏析-(浣溪沙)
2019/08/13 职场文书
Go语言-为什么返回值为接口类型,却返回结构体
2021/04/24 Golang
Python内置类型集合set和frozenset的使用详解
2022/04/26 Python