码迷,mamicode.com
首页 > 其他好文 > 详细

snap.svg实现弹性侧栏菜单

时间:2014-12-31 01:05:11      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:snap.svg   svg   网页动画   弹性菜单   

前端开发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.jssnap.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前端开发,分享相关资源,欢迎点赞,欢迎拍砖。
---------------------------------------------------------------------------------------------------------

snap.svg实现弹性侧栏菜单

标签:snap.svg   svg   网页动画   弹性菜单   

原文地址:http://blog.csdn.net/whqet/article/details/42276641

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!