前端必备神器 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下阻止表单重复提交、防刷新、防后退
Aug 17 Javascript
jquery ajax提交表单数据的两种方式
Nov 24 Javascript
javascript 二维数组的实现与应用
Mar 16 Javascript
关于html+ashx开发中几个问题的解决方法
Jul 18 Javascript
javascript插入样式实现代码
Feb 22 Javascript
jQuery带箭头提示框tooltips插件集锦
Nov 17 Javascript
js中for in语句的用法讲解
Apr 24 Javascript
JS实现网页顶部向下滑出的全国城市切换导航效果
Aug 22 Javascript
jQuery中的ready函数与window.onload谁先执行
Jun 21 Javascript
如何将HTML字符转换为DOM节点并动态添加到文档中详解
Aug 19 Javascript
webpack4打包vue前端多页面项目
Sep 17 Javascript
JavaScript中的垃圾回收与内存泄漏示例详解
May 02 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
4月1日重磅发布!《星际争霸II》6.0.0版本更新
2020/04/09 星际争霸
php中的实现trim函数代码
2007/03/19 PHP
献给php初学者(入门学习经验谈)
2010/10/12 PHP
深入for,while,foreach遍历时间比较的详解
2013/06/08 PHP
php文件上传的简单实例
2013/10/19 PHP
javascript 设计模式之单体模式 面向对象学习基础
2010/04/18 Javascript
JavaScript 继承机制的实现(待续)
2010/05/18 Javascript
SWFObject 2.1以上版本语法介绍
2010/07/10 Javascript
js 在定义的时候立即执行的函数表达式(function)写法
2013/01/16 Javascript
JS检测输入字符是否包含非法字符的示例代码
2014/02/11 Javascript
屏蔽相应键盘按钮操作
2014/03/10 Javascript
node.js中使用node-schedule实现定时任务实例
2014/06/03 Javascript
javascript十六进制及二进制转化的方法
2015/05/06 Javascript
js与jquery正则验证电子邮箱、手机号、邮政编码的方法
2016/07/04 Javascript
原生js仿jquery animate动画效果
2016/07/13 Javascript
js实现点击切换checkbox背景图片的简单实例
2017/05/08 Javascript
深入浅析JavaScript中的RegExp对象
2017/09/18 Javascript
vue动态改变背景图片demo分享
2018/09/13 Javascript
three.js搭建室内场景教程
2018/12/30 Javascript
微信小程序实现翻牌抽奖动画
2020/09/21 Javascript
PHP 502bad gateway原因及解决方案
2020/11/13 Javascript
Python中的类与对象之描述符详解
2015/03/27 Python
Python正确重载运算符的方法示例详解
2017/08/27 Python
python绘制条形图方法代码详解
2017/12/19 Python
Django中Model的使用方法教程
2018/03/07 Python
Python xlrd/xlwt 创建excel文件及常用操作
2020/09/24 Python
python matplotlib绘制三维图的示例
2020/09/24 Python
芬兰灯具网上商店:Nettilamppu.fi
2018/06/30 全球购物
澳大利亚第一旅行车和房车配件店:Caravan RV Camping
2020/12/26 全球购物
工作交流会欢迎词
2014/01/12 职场文书
教育科研先进个人材料
2014/01/26 职场文书
酒店开业策划方案
2014/06/02 职场文书
2014年扶贫工作总结
2014/11/18 职场文书
优秀教师先进材料
2014/12/16 职场文书
继承公证书格式
2015/01/26 职场文书
悬疑名作《朋友游戏》动画无字ED宣传片 新角色公开
2022/04/13 日漫