这是一款效果非常酷的jQuery和CSS3 3D页面切换导航菜单特效插件。该导航菜单插件是汉堡包隐藏菜单,每个菜单项的图标使用SVG来制作,鼠标滑过图标时有动画效果,点击某一个菜单项后,页面会在3D空间进行切换,效果非常炫酷。
插件中为了使页面加载时用户能更注意导航菜单的存在,将页面的内容沿Z轴往里面缩小,这里使用的是CSS transformations,而不是使用3D translations,但是得到的结果是一样的。
当你选择了某个菜单项,插件会切换页面的颜色为该菜单项的背景颜色。
制作方法
HTML结构
该导航菜单插件的HTML结构分为三个部分:.cd-nav-trigger
是用于触发隐藏菜单的汉堡包图标按钮。.cd-section
包含了页面中的主要内容。.cd-nav-container
是导航菜单。
<a href="#cd-nav" class="cd-nav-trigger"> Menu<span><!-- used to create the menu icon --></span> </a> <!-- .cd-nav-trigger --> <main> <section class="cd-section index cd-selected"> <header> <div class="cd-title"> <h2><!-- title here --></h2> <p><!-- brief description here --></p> </div> <!-- .cd-title --> </header> <div class="cd-content"> <!-- your content here --> </div> </section> <!-- .cd-section --> </main> <nav class="cd-nav-container" id="cd-nav"> <header> <h3>Navigation</h3> <a href="#0" class="cd-close-nav">Close</a> </header> <ul class="cd-nav"> <li class="cd-selected" data-menu="index"> <a href="index.html"> <span> <!-- svg icon here --> </span> <em><!-- title here --></em> </a> </li> <li data-menu="projects"> <!-- .... --> </li> <!-- other list items here --> </ul> <!-- .cd-3d-nav --> </nav>
代码最后额外的div.cd-overlay
元素是用来制作阴影层,它只有在导航菜单显示时才可见。
CSS样式
为了实现动画效果,插件在<main>
元素和<nav>
元素中分别使用了 CSS3 Transformations。默认情况下,导航菜单位置是固定的,并且并放置在页面的右边,在屏幕的可视区域之外(使用translateX(100%)
)。当用户点击了导航菜单按钮,<nav>
元素被添加class .is-visible
,这个class 会使用translateX(0)
将导航菜单移入屏幕中。同时,<main>
元素会被添加class .scale-down
,该class会将<main>
元素缩小一些(scale(.9)
)。以上这些动画都使用 CSS3 Transitions 来制作平滑的过渡效果。
.cd-nav-container { position: fixed; top: 0; right: 0; width: 80%; height: 100%; transform: translateX(100%); transition: transform 0.4s; } .cd-nav-container.is-visible { transform: translateX(0); } main { transition: transform 0.4s; } main.scale-down { transform: scale(0.9); }
当用户从导航菜单中选择一个菜单项时,会创建一个新的.cd-section
元素,并插入到DOM中。
接着,.cd-selected
class会被添加到.cd-section
元素上,这时,旧的.cd-section
元素会被移除。新的.cd-section
元素(它初始化时被移到右侧的屏幕之外)将被使用(translateX(0)
移回屏幕之内,并覆盖旧的内容(z-index: 2
)。
注意:你不会看见旧的section移动到右边的动画,因为插件中为.cd-section
为transformations设置了transition延时0.4秒。
.cd-section { position: absolute; z-index: 1; top: 0; left: 0; height: 100%; width: 100%; overflow-y: auto; transform: translateX(100%); transition: transform 0s 0.4s; } .cd-section.cd-selected { position: relative; z-index: 2; transform: translateX(0); transition: transform 0.4s 0s; }
JAVASCRIPT
index.html页面只包含了简介的内容,其它页面的HTML结构基本相同,但是.cd-section
的内容略有不同。
当用户从导航菜单中旋转了一个新的菜单项时,插件通过loadNewContent
方法创建一个新的<section>
元素并插入DOM中。
然后使用load()
方法来调用指定的内容(这里使用一个data-menu
属性来决定哪个页面的内容被调用)。
当一个HTML页面的内容被调用的时候,新的section会被添加class .cd-selected
,并且关闭导航菜单。
$('.cd-nav li').on('click', function(event){ event.preventDefault(); var target = $(this), //detect which section user has chosen sectionTarget = target.data('menu'); if( !target.hasClass('cd-selected') ) { //if user has selected a section different from the one alredy visible //update the navigation -> assign the .cd-selected class to the selected item target.addClass('cd-selected').siblings('.cd-selected').removeClass('cd-selected'); //load the new section loadNewContent(sectionTarget); } else { // otherwise close navigation toggleNav(false); } }); function loadNewContent(newSection) { //create a new section element and insert it into the DOM var section = $('').appendTo($('main')); //load the new content from the proper html file section.load(newSection+'.html .cd-section > *', function(event){ //add the .cd-selected to the new section element -> it will cover the old one section.addClass('cd-selected').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){ //close navigation toggleNav(false); }); section.prev('.cd-selected').removeClass('cd-selected'); }); $('main').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){ //once the navigation is closed, remove the old section from the DOM section.prev('.cd-section').remove(); }); if( $('.no-csstransitions').length > 0 ) { //detect if browser supports transitions toggleNav(false); section.prev('.cd-section').remove(); } }
提示:插件中只是使用load()函数来实现简单的页面加载功能,你可以通过$.ajax
来异步调用页面,处理页面加载前的事件或错误内容提示等等。