这是一款效果非常炫酷的jQuery和CSS3全屏推拉式滑动菜单特效插件。这个插件的效果是当点击了主菜单按钮时,全屏菜单从屏幕左侧滑出,主菜单按钮动态旋转更换图标。当再次点击主菜单按钮时,全屏菜单又从右向左滑会去。
下面是一张描述这个过程的动态gif图片:
HTML结构
该全屏滑动菜单的HTML结构分为三个部分:包含可见内容的<main>
元素,一个用于包含全屏导航菜单的div.cd-nav
和一个用于触发事件的按钮.cd-nav-trigger
。
.cd-nav
中包含两个div.cd-half-block
元素:第一个是包含菜单导航项的.cd-primary-nav
,第二个是联系方式的内容.cd-contact-info
。
<div id="cd-nav" class="cd-nav"> <div class="cd-navigation-wrapper"> <div class="cd-half-block"> <h2>Navigation</h2> <nav> <ul class="cd-primary-nav"> <li><a href="#0" class="selected">The team</a></li> <!-- list items here --> </ul> </nav> </div><!-- .cd-half-block --> <div class="cd-half-block"> <address> <ul class="cd-contact-info"> <li><a href="mailto:info@myemail.co">info@myemail.co</a></li> <!-- other contact info here --> </ul> </address> </div> <!-- .cd-half-block --> </div> <!-- .cd-navigation-wrapper --> </div> <!-- .cd-nav -->
在.cd-nav-trigger
中包含一个span.cd-nav-icon
,它用于创建按钮的汉堡包图标,它本身是汉堡包中间的那条线,而它的::before
和::after
伪元素分别用于创建上面和下面的线。还包含一个SVG元素,它用于创建图标的动画。
CSS样式
当用户点击.cd-nav-trigger
主菜单按钮时,会在<body>
元素上添加.navigation-is-open
class。这个class会触发主菜单按钮动画和全屏菜单的滑动动画。
对于主菜单按钮的动画可以分为三个部分:
- 汉堡包图标被转换为箭头图标:
.cd-nav-icon::after
和.cd-nav-icon::before
伪元素分别旋转45度和-45度,并使它们的宽度增加50%。 - 将
.cd-nav-icon
旋转180度。 - 图标上的圆形进度条效果:开始的时候,图标的边框属性值为
stroke-dasharray="157 157"
和stroke-dashoffset="157"
,157是圆周的值。动画开始后,stroke-dashoffset
的值被设置为0。
主按钮图标的每一步动画都使用CSS3 Transitions来使动画效果平滑过渡。
下面是这个动画过程的gif动态示意图:
.cd-nav-trigger { transition: transform 0.5s; } .navigation-is-open .cd-nav-trigger { /* rotate trigger when navigation becomes visible */ transform: rotate(180deg); } .cd-nav-trigger .cd-nav-icon::before, .cd-nav-trigger .cd-nav-icon:after { /* upper and lower lines of the menu icon */ width: 100%; height: 100%; transition: transform 0.5s, width 0.5s, top 0.3s; } .cd-nav-trigger .cd-nav-icon::before { transform-origin: right top; transform: translateY(-6px); } .cd-nav-trigger .cd-nav-icon::after { transform-origin: right bottom; transform: translateY(6px); } .navigation-is-open .cd-nav-trigger .cd-nav-icon::after, .navigation-is-open .cd-nav-trigger .cd-nav-icon::before { /* animate arrow --> from hamburger to arrow */ width: 50%; transition: transform 0.5s, width 0.5s; } .navigation-is-open .cd-nav-trigger .cd-nav-icon::before { transform: rotate(45deg); } .navigation-is-open .cd-nav-trigger .cd-nav-icon::after { transform: rotate(-45deg); } .cd-nav-trigger circle { /* circle border animation */ transition: stroke-dashoffset 0.4s 0s; } .navigation-is-open .cd-nav-trigger circle { stroke-dashoffset: 0; transition: stroke-dashoffset 0.4s 0.3s; }
对于全屏菜单的滑动进入屏幕的效果,<main>
元素和.cd-navigation-wrapper
元素都在X轴上translate
100%的距离。为了制作更为逼真的推拉效果,插件中的transition
时间函数使用的是cubic bezier curve
,这个函数曲线允许你设置4个参数(曲线两端分别有两个控制点),可以通过调整这些控制点来定制transition
时的动画效果。
下图中展示了你设置自定义cubic-bezier timing functions和线性(linear)动画的区别:
JAVASCRIPT
该全屏推拉式滑动菜单使用jQuery来监听主菜单按钮的点击事件,并为相应的元素添加或移除.navigation-is-open
class。
jQuery(document).ready(function($){ var isLateralNavAnimating = false; //open/close lateral navigation $('.cd-nav-trigger').on('click', function(event){ event.preventDefault(); //stop if nav animation is running if( !isLateralNavAnimating ) { if($(this).parents('.csstransitions').length > 0 ) isLateralNavAnimating = true; $('body').toggleClass('navigation-is-open'); $('.cd-navigation-wrapper').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){ //animation is over isLateralNavAnimating = false; }); } }); });