前端必备神器 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 相关文章推荐
js解析xml字符串和xml文档实现原理及代码(针对ie与火狐)
Feb 02 Javascript
extjs4 treepanel动态改变行高度示例
Dec 17 Javascript
JS cookie中文乱码解决方法
Jan 28 Javascript
js实现鼠标经过表格行变色的方法
May 12 Javascript
Angular.js实现多个checkbox只能选择一个的方法示例
Feb 24 Javascript
JS中showModalDialog关闭子窗口刷新主窗口用法详解
Mar 25 Javascript
详解在Angularjs中ui-sref和$state.go如何传递参数
Apr 24 Javascript
jQuery AJAX与jQuery事件的分析讲解
Feb 18 jQuery
electron-vue利用webpack打包实现多页面的入口文件问题
May 12 Javascript
layui table设置某一行的字体颜色方法
Sep 05 Javascript
JS图片懒加载的优点及实现原理
Jan 10 Javascript
jQuery实现开关灯效果
Aug 02 jQuery
浅谈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
德生PL330测评
2021/03/02 无线电
php+redis消息队列实现抢购功能
2018/02/08 PHP
PHP设计模式之状态模式定义与用法详解
2018/04/02 PHP
360搜索引擎自动收录php改写方案
2018/04/28 PHP
jquery 多级下拉菜单核心代码
2010/05/21 Javascript
一些经常会用到的Javascript检测函数
2010/05/31 Javascript
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
2011/03/30 Javascript
判断javascript的数据类型(示例代码)
2013/12/11 Javascript
js过滤特殊字符输入适合输入、粘贴、拖拽多种情况
2014/03/22 Javascript
NodeJS学习笔记之Connect中间件模块(二)
2015/01/27 NodeJs
DIV随滚动条滚动而滚动的实现代码【推荐】
2016/04/12 Javascript
js和jQuery设置Opacity半透明 兼容IE6
2016/05/24 Javascript
Bootstrap对话框使用实例讲解
2016/09/24 Javascript
xcode中获取js文件的路径方法(推荐)
2016/11/05 Javascript
React组件的三种写法总结
2017/01/12 Javascript
JavaScript DOM节点操作实例小结(新建,删除HTML元素)
2017/01/19 Javascript
AngularJS读取JSON及XML文件的方法示例
2017/05/25 Javascript
NodeJS链接MySql数据库的操作方法
2017/06/27 NodeJs
基于js中的存储键值对以及注意事项介绍
2018/03/30 Javascript
[03:04]2018年国际邀请赛典藏宝瓶&莱恩声望物品展示 片尾有彩蛋
2018/06/04 DOTA
Python计算两个日期相差天数的方法示例
2017/05/23 Python
python merge、concat合并数据集的实例讲解
2018/04/12 Python
Python爬虫框架scrapy实现的文件下载功能示例
2018/08/04 Python
Python第三方Window模块文件的几种安装方法
2018/11/22 Python
Python 旋转打印各种矩形的方法
2019/07/09 Python
Python实现滑动平均(Moving Average)的例子
2019/08/24 Python
Pytorch修改ResNet模型全连接层进行直接训练实例
2019/09/10 Python
Numpy将二维数组添加到空数组的实现
2019/12/05 Python
python实现随机加减法生成器
2020/02/24 Python
医校毕业生自我鉴定
2014/01/25 职场文书
总经理助理职责
2014/02/04 职场文书
高级编程求职信模板
2014/02/16 职场文书
《大江保卫战》教学反思
2014/04/11 职场文书
单位工作证明
2014/10/07 职场文书
领导欢迎词致辞
2015/01/23 职场文书
win10下go mod配置方式
2021/04/25 Golang