这是一款效果非常酷的jQueryCSS3 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来异步调用页面,处理页面加载前的事件或错误内容提示等等。