svg动画实现弹性侧栏菜单

来源:互联网 发布:算法的乐趣 下载 编辑:程序博客网 时间:2024/05/20 06:22
p{text-indent:2em;}前端开发whqet,csdn,王海庆,whqet,前端开发专家

效果预览

众所周知,flash动画类型可以分为补间动画和逐帧动画,补间动画又可以分为属性改变(大小、位置、颜色等)和形状改变(直线变弧线等)。网页动画里,我们可以使用css3、javascript(jquery)等实现属性改变,却对形状改变无能为力,那么如何实现网页动画里的形状改变呢?今天提供一种解决方案——通过snap.svg动态改变svg形状实现,案例效果如下图所示,案例灵感来自codrops。


----------------

----------------------------------------

在线研究点击这里,下载收藏点击这里。

----------------------------------------

---------------

关键技术

制作这个案例,你需要

1. snap.svg的基本使用

2. classie.js的基本使用

3. snap.svg操作改变svg的内容

4. 冲动与激情

实现步骤

ok,我们html内容如下,.menu为整个容器,.menu__handle为单击按钮,.menu__inner为弹出菜单内容,.morph-shape为形状改变的线条。我们把需要改变的线条的path数据实现放到data-morph-open和data-morph-close两个属性里。

<div class="container"><nav id="menu" class="menu"><button class="menu__handle"><span>Menu</span></button><div class="menu__inner"><ul><li><a href="#">Home</a></li><li><a href="#">Favs</a></li><li><a href="#">Files</a></li><li><a href="#">Stats</li></ul></div><div class="morph-shape" data-morph-open="M300-10c0,0,295,164,295,410c0,232-295,410-295,410" data-morph-close="M300-10C300-10,5,154,5,400c0,232,295,410,295,410"><svg width="100%" height="100%" viewBox="0 0 600 800" preserveAspectRatio="none"><path fill="none" d="M300-10c0,0,0,164,0,410c0,232,0,410,0,410"/></svg></div></nav></div>

然后是css,css里面我们实现基本布局与css3动画。css里面我们使用了Normalize和prefixfree。按钮(三条线变成x)由.menu__handle的before、after两个伪对象和span实现。

/*统一化设置*/*, *:after, *:before { box-sizing: border-box; }.clearfix:before, .clearfix:after { content: ''; display: table; }.clearfix:after { clear: both; }body {color: #fff;background: #FF7F50;font-weight: 400;font-size: 1em;}a {color: #fff;text-decoration: none;}a:hover,a:focus {color: #393;outline: none;}.container {text-align: center;padding: 5.25em 0.5em 0;}/*菜单设置*/.menu {position: fixed;width: 240px;   top: 2px;bottom: 2px;left: 0;z-index: 100;overflow: hidden;transform: translate3d(-150px, 0, 0);transition: transform 0.6s;}.menu.menu--open {transform: translate3d(0, 0, 0);}.menu__inner {width: calc(100% + 15px);padding: 0 100px 2em 0;overflow-y: auto;height: 100%;position: relative;z-index: 100;}.menu ul {list-style: none;padding: 0;margin: 0;}.menu ul li {transform: translate3d(-150px, 50px, 0);transition: transform 0.6s;   height:24px;   line-height:24px;}.menu.menu--anim ul li {transform: translate3d(0, 0, 0);}.menu ul li:first-child {transition-delay: 0.3s;}.menu ul li:nth-child(2) {transition-delay: 0.2s;}.menu ul li:nth-child(3) {transition-delay: 0.1s;}.menu ul li a {display: block;outline: none;}/*按钮及单击之后变换*/.menu__handle {background: #FF7F50;border: none;width: 30px;height: 24px;padding: 0;outline: none;position: absolute;top: 3px;right: 45px;z-index: 2000;}.menu__handle::before,.menu__handle::after,.menu__handle span {background: #fff;}.menu__handle::before,.menu__handle::after {content: '';position: absolute;height: 2px;width: 100%;left: 0;top: 50%;transform-origin: 50% 50%;transition: transform 0.25s;}.menu__handle span {position: absolute;width: 100%;height: 2px;left: 0;overflow: hidden;text-indent: 200%;transition: opacity 0.25s;}.menu__handle::before {transform: translate3d(0, -10px, 0);}.menu__handle::after {transform: translate3d(0, 10px, 0);}.menu--open .menu__handle span {opacity: 0;}.menu--open .menu__handle::before {transform: rotate3d(0, 0, 1, 45deg);}.menu--open .menu__handle::after {transform: rotate3d(0, 0, 1, -45deg);}/* 线条及改变 */.morph-shape {position: absolute;width: 160px;height: 100%;top: 0;right: 0px;}.morph-shape svg path {stroke: #fff;stroke-width: 2px;}.menu--open .morph-shape svg path {stroke: #fff;stroke-width: 4px;}

然后是javascript,也是我们的核心。这里用到了classie.js和snap.svg(可以参考张鑫旭大侠翻译的snap.svg中文版)。

function SVGMenu( el, options ) {this.el = el;this.init();}SVGMenu.prototype.init = function() {this.trigger = this.el.querySelector( 'button.menu__handle' );this.shapeEl = this.el.querySelector( 'div.morph-shape' );var s = Snap( this.shapeEl.querySelector( 'svg' ) );this.pathEl = s.select( 'path' );this.paths = {reset : this.pathEl.attr( 'd' ),open : this.shapeEl.getAttribute( 'data-morph-open' ),close : this.shapeEl.getAttribute( 'data-morph-close' )};this.isOpen = false;this.trigger.addEventListener( 'click', this.toggle.bind(this) );};SVGMenu.prototype.toggle = function() {var self = this;if( this.isOpen ) {classie.remove( self.el, 'menu--anim' );setTimeout( function() { classie.remove( self.el, 'menu--open' );}, 250 );}else {classie.add( self.el, 'menu--anim' );setTimeout( function() { classie.add( self.el, 'menu--open' );}, 250 );}self.pathEl.stop().animate( { 'path' : self.isOpen ? self.paths.close : this.paths.open }, 350, mina.easeout, function() {self.pathEl.stop().animate( { 'path' : self.paths.reset }, 800, mina.elastic );} );self.isOpen = !self.isOpen;};new SVGMenu( document.getElementById( 'menu' ) );

ok,请大家仔细揣摩。当然,这个方面也出了一些插件可以使用例如,SVG Morpheus,也可看看《SVG-Morpheus实现SVG图标图形间的补形动画》这篇教程。

----------------------------------------------------------

前端开发whqet,关注web前端开发,分享相关资源,欢迎点赞,欢迎拍砖。
---------------------------------------------------------------------------------------------------------

10 0
原创粉丝点击