ribbon image search rewind fast-forward speech-bubble pie-graph star

新博客的动画效果实现

最近重新写了 Ghost-theme 的主题。其中主要是取消了Icon-font,改为了SVG Sprite 。其次非常重要的板块首屏的Slide 和导航重新设计了。先看下具体的效果吧:

视频无法播放,可以查看 gif 图片

Slide 切换

切换动画

slide 的切换主要是利用了transformanimation 两个重要的属性。而切换的时间函数则需要用到 cubic-bezier(关于贝塞尔曲线的效果可以参考这里)。然后利用少量的JS和手势库就可以完成了。

基本结构

<div id="slideshow" class="slideshow">  
  <!-- slide -->       
  <div class="slide">
      <div class="bg-overlay" style="background-image:url(/content/images/2017/04/rocket-in-dark-1.jpg)"></div>
      <blockquote>
          <p>破立</p>
          <a class="view-details noSwipe" href="/fan-fu/">
            阅读详情 <svg style="margin-top:2px;" class="icon icon-fast-forward"><use xlink:href="#icon-fast-forward"></use></svg>
          </a>
      </blockquote>
  </div>
  <!-- end slide -->

  <!-- repeat -->

</div>

其中我们可以看到容器 slideshow 里面 包含你需要存放的 slide 单元。每个 slide 由一张背景图片,和标题以及导航链接组成。下来我们添加一些样式,整个slide都是用的绝对定位,占满首屏:

.slideshow,
.slide,
.slide::after {
    width: 100%;
    height: 100%
}

.slideshow {
    margin: 0;
    padding: 0;
    overflow: hidden;
    position: relative;
    transition: margin .6s;
    -webkit-transition: margin .6s;
    transition-timing-function: cubic-bezier(0.7,0,0.3,1);
    -webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
    background-color: #2c3e50
}

关于这使用的transition后文的导航会涉及到。

接下来,我们添加slide里面的样式,

.slide {
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0;
    pointer-events: none;
    background: #fff;
    -webkit-transform-origin: 50% 120%;
    transform-origin: 50% 120%
}

.slide::after {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 1000;
    background: #fff;
    content: '';
    opacity: 0;
    -webkit-transition: opacity 4s;
    transition: opacity 4s;
    -webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
    transition-timing-function: cubic-bezier(0.7,0,0.3,1)
}

.slideshow blockquote p {
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 0 .25rem
}


.slideshow blockquote {
    z-index: 1001;
    position: absolute;
    bottom: 3rem;
    left: 3rem;
    right: 3rem;
    padding: 0;
    padding-bottom: 1rem;
    border-left: none;
    color: #fff;
    text-align: left
}

.slideshow .bg-overlay {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    box-shadow: 0 -2rem 3rem -2rem rgba(0,0,0,0.45) inset,0 -3rem 3rem -2rem rgba(0,0,0,0.45) inset,0 -4rem 5rem -4rem rgba(0,0,0,0.35) inset,0 -10rem 3rem -3rem rgba(0,0,0,0.35) inset,0 -15rem 3rem -3rem rgba(0,0,0,0.35) inset,0 -20rem 5rem -3rem rgba(0,0,0,0.35) inset;
    transition: opacity 0.6s;
    -webkit-transition: opacity 0.6s;
    -webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
    transition-timing-function: cubic-bezier(0.7,0,0.3,1)
}

.open .slideshow .bg-overlay {
    opacity: 0
}

.slideshow blockquote p {
    margin: 0;
    margin-bottom: 2.5rem;
    padding: 0;
    font-size: 4.8rem;
    font-style: normal;
    line-height: 1.2em
}

.slideshow blockquote .date {
    font-size: 1.1rem;
    color: #ccc
}

.slideshow blockquote .view-details {
    display: inline-block;
    padding: .5rem 1rem;
    border: 1px solid rgba(255,255,255,0.55);
    border-radius: .2rem;
    color: #fff;
    font-size: 1.4rem;
    line-height: 1.2em;
    box-shadow: 0 2px 4px -2px rgba(0,0,0,0.25)
}

其中 .slide 是使用的绝对定位,其中关键的是设置它的旋转中心,从上面的动图也可以看到是在中心旋转。而blockquote则设置的用于显示一些基本的标题和链接挑战的样式设置。

接下来我们来实现具体的动画效果:

我们动画分为四种,即逆时针淡入与淡出,顺时针淡入与淡出。

首先我们先添加整体的动画函时间函数控制。这里主要是使用的 cubic-bezier(0.7,0,0.3,1)

.slider--animInRight,
.slider--animInLeft,
.slider--animOutRight,
.slider--animOutLeft {
    -webkit-animation-timing-function: cubic-bezier(0.7,0,0.3,1);
    animation-timing-function: cubic-bezier(0.7,0,0.3,1);
    -webkit-animation-duration: .9s;
    animation-duration: .9s;
    -webkit-animation-fill-mode: forwards;
    animation-fill-mode: forwards
}

我们添加图片逆时针旋转进入的动画效果,slide上面的一张会向左旋转一定角度,然后显示在最上层。

.slider--animInLeft {
    -webkit-animation-name: animInLeft;
    animation-name: animInLeft
}

.slider--animInLeft {
    z-index: 101;
    opacity: 1
}

@-webkit-keyframes animInLeft {
    from {
        -webkit-transform: rotate3d(0,0,1,-20deg) translate3d(-100%,0,0);
        opacity: 0
    }

    to {
        -webkit-transform: rotate3d(0,0,1,0deg) translate3d(0,0,0);
        transform: rotate3d(0,0,1,0deg) translate3d(0,0,0)
    }
}

@keyframes animInLeft {
    from {
        -webkit-transform: rotate3d(0,0,1,-20deg) translate3d(-100%,0,0);
        transform: rotate3d(0,0,1,-20deg) translate3d(-100%,0,0);
        opacity: 0
    }

    to {
        -webkit-transform: rotate3d(0,0,1,0deg) translate3d(0,0,0);
        transform: rotate3d(0,0,1,0deg) translate3d(0,0,0)
    }
}

同理,我们添加从右进入的动画效果:

.slider--animInRight {
    z-index: 101;
    opacity: 1
}
.slider--animInRight {
    -webkit-animation-name: animInRight;
    animation-name: animInRight
}

@-webkit-keyframes animInRight {
    from {
        -webkit-transform: rotate3d(0,0,1,20deg) translate3d(100%,0,0);
        transform: rotate3d(0,0,1,20deg) translate3d(100%,0,0);
        opacity: 0
    }

    to {
        -webkit-transform: rotate3d(0,0,1,0deg) translate3d(0,0,0);
        transform: rotate3d(0,0,1,0deg) translate3d(0,0,0)
    }
}

@keyframes animInRight {
    from {
        -webkit-transform: rotate3d(0,0,1,20deg) translate3d(100%,0,0);
        transform: rotate3d(0,0,1,20deg) translate3d(100%,0,0);
        opacity: 0
    }

    to {
        -webkit-transform: rotate3d(0,0,1,0deg) translate3d(0,0,0);
        transform: rotate3d(0,0,1,0deg) translate3d(0,0,0)
    }
}

其中我们还需要给进入的样式中设置:after伪类的效果,让它的的透明度变为1。

.slider--animOutRight::after,
.slider--animOutLeft::after {
    opacity: 1
}

同理,我们可以添加淡出的动画,分为左右两个方向。

.slider--animOutRight {
    -webkit-animation-name: animOutRight;
    animation-name: animOutRight
}

.slider--animOutLeft {
    -webkit-animation-name: animOutLeft;
    animation-name: animOutLeft
}

@-webkit-keyframes animOutLeft {
    to {
        -webkit-transform: rotate3d(0,0,1,-20deg) translate3d(-100%,0,0);
        transform: rotate3d(0,0,1,-20deg) translate3d(-100%,0,0);
        opacity: 0
    }
}

@keyframes animOutLeft {
    to {
        -webkit-transform: rotate3d(0,0,1,-20deg) translate3d(-100%,0,0);
        transform: rotate3d(0,0,1,-20deg) translate3d(-100%,0,0);
        opacity: 0
    }
}
@-webkit-keyframes animOutRight {
    to {
        -webkit-transform: rotate3d(0,0,1,20deg) translate3d(100%,0,0);
        transform: rotate3d(0,0,1,20deg) translate3d(100%,0,0);
        opacity: 0
    }
}

@keyframes animOutRight {
    to {
        -webkit-transform: rotate3d(0,0,1,20deg) translate3d(100%,0,0);
        transform: rotate3d(0,0,1,20deg) translate3d(100%,0,0);
        opacity: 0
    }
}

这样我们的样式基本就到位了,我们需要设置当前显示slider的样式。

.slider--current {
    position: absolute;
    z-index: 100;
    opacity: 1;
    pointer-events: auto
}

这样我们的基本效果就呈现了。

接着我们添加一些边角料的样式,比如用于控制的左右切换的按钮以及slide的缩略图。

.slideshow .ctrl {
    z-index: 101;
    position: absolute;
    bottom: 3rem;
    right: 3rem
}

.slideshow .ctrl a {
    color: rgba(255,255,255,0.75);
    margin: .5rem
}

.slideshow .ctrl a:hover,.slideshow .ctrl a.active {
    color: #fff
}

.slideshow .thumb {
    z-index: 101;
    position: absolute;
    bottom: 3rem;
    left: 3.25rem
}

.slideshow .thumb a {
    display: inline-block;
    width: .5rem;
    height: .5rem;
    margin: .25rem;
    border-radius: .5rem;
    background-color: rgba(255,255,255,0.45)
}

.slideshow .thumb a.active {
    background-color: rgba(255,255,255,0.85)
}

这些都是动态通过JS添加的,接下来我们添加JS来控制逻辑。首先我们需要引入 jQuery的库。

/* globals jQuery, document */
(function ($) {
    "use strict";
    var $document = $(document),
        containers = [].slice.call($('.slide')),
        containersCount = containers.length,
        current = 0,
        isAnimating = false,
        pageTriggers = [];

    var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

    $document.ready(function () {
        initSlider();
    });
    function initSlider() {
        var thumbString = '';
        containers.forEach(function (item, index) {
            thumbString += '<a href="javascript:;" ' + (index === 0 ? 'class="active" ' : '') + '></a>';
        });
        if (containers.length > 1) {
            var ctrlString = '';
            if (!isMobile) {
                 ctrlString = '<div class="ctrl"><a href="javascript:;" class="js-ctrl-left" ><svg class="icon icon-rewind"><use xlink:href="#icon-rewind"></use></svg></a><a href="javascript:;" class="js-ctrl-right icon-angle-right" ><svg class="icon icon-fast-forward"><use xlink:href="#icon-fast-forward"></use></svg></a></div>';
            }
            $('#slideshow').append([ctrlString, '<div class="thumb">', thumbString, '</div>'].join(''));
            bindEvent();
        }
        pageTriggers = [].slice.call($('.thumb a'));
        $(containers[current]).addClass('slider--current');
    }

    function bindEvent() {
        $('.js-ctrl-left').on('click', function () {
            if (current > 0) {
                navigate(pageTriggers[current - 1]);
            }
        });
        $('.js-ctrl-right').on('click', function () {
            if (current < containersCount - 1) {
                navigate(pageTriggers[current + 1]);
            }
        });

    function navigate(pageTrigger) {
        var oldcurrent = current,
            newcurrent = pageTriggers.indexOf(pageTrigger);
        if (isAnimating || oldcurrent === newcurrent) return;
        isAnimating = true;

        var currentPageTrigger = pageTriggers[current],
            nextContainer = containers[newcurrent],
            currentContainer = containers[current],
            dir = newcurrent > oldcurrent ? 'left' : 'right';

        $(currentPageTrigger).removeClass('active');
        $(pageTrigger).addClass('active');
        // update current
        current = newcurrent;
        $(nextContainer).addClass(dir === 'left' ? 'slider--animInRight' : 'slider--animInLeft');
        $(currentContainer).addClass(dir === 'left' ? 'slider--animOutLeft' : 'slider--animOutRight');
        onEndAnimation(currentContainer, function () {
            $(currentContainer).removeClass(dir === 'left' ? 'slider--animOutLeft' : 'slider--animOutRight');
            $(nextContainer).removeClass(dir === 'left' ? 'slider--animInRight' : 'slider--animInLeft');
            $(currentContainer).removeClass('slider--current');
            $(nextContainer).addClass('slider--current');
            isAnimating = false;
        });
    }


})(jQuery);

这样我们就可以就可以看到基本的效果了,其中 navigate 为最为核心的函数。主要是依据当前的slide然后去进行方向的选择,也就是添加不同的 class

我们看到其中有用到一些svg图标,所以我们还必须先在body里添加svg图标:

<!--svg -->

<svg style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg">  
<defs>  
<symbol id="icon-ribbon" viewBox="0 0 24 24">  
<title>ribbon</title>  
<path d="M7 1h10q1.242 0 2.121 0.879t0.879 2.121v19l-8-6-8 6v-19q0-1.242 0.879-2.121t2.121-0.879zM17 3h-10q-0.414 0-0.707 0.293t-0.293 0.707v15l6-4.5 6 4.5v-15q0-0.414-0.293-0.707t-0.707-0.293z"></path>  
</symbol>  
<symbol id="icon-image" viewBox="0 0 24 24">  
<title>image</title>  
<path d="M4 1h16q1.242 0 2.121 0.879t0.879 2.121v16q0 1.242-0.879 2.121t-2.121 0.879h-16q-1.242 0-2.121-0.879t-0.879-2.121v-16q0-1.242 0.879-2.121t2.121-0.879zM21 17.414l-5-5-8.586 8.586h12.586q0.414 0 0.707-0.293t0.293-0.707v-2.586zM20 3h-16q-0.414 0-0.707 0.293t-0.293 0.707v16q0 0.414 0.293 0.707t0.707 0.293h0.586l11.414-11.414 5 5v-10.586q0-0.414-0.293-0.707t-0.707-0.293zM8 5q1.242 0 2.121 0.879t0.879 2.121-0.879 2.121-2.121 0.879-2.121-0.879-0.879-2.121 0.879-2.121 2.121-0.879zM8 7q-0.414 0-0.707 0.293t-0.293 0.707 0.293 0.707 0.707 0.293 0.707-0.293 0.293-0.707-0.293-0.707-0.707-0.293z"></path>  
</symbol>  
<symbol id="icon-search" viewBox="0 0 24 24">  
<title>search</title>  
<path d="M10 1q1.828 0 3.496 0.715t2.871 1.918 1.918 2.871 0.715 3.496q0 1.57-0.512 3.008t-1.457 2.609l5.68 5.672q0.289 0.289 0.289 0.711 0 0.43-0.285 0.715t-0.715 0.285q-0.422 0-0.711-0.289l-5.672-5.68q-1.172 0.945-2.609 1.457t-3.008 0.512q-1.828 0-3.496-0.715t-2.871-1.918-1.918-2.871-0.715-3.496 0.715-3.496 1.918-2.871 2.871-1.918 3.496-0.715zM10 3q-1.422 0-2.719 0.555t-2.234 1.492-1.492 2.234-0.555 2.719 0.555 2.719 1.492 2.234 2.234 1.492 2.719 0.555 2.719-0.555 2.234-1.492 1.492-2.234 0.555-2.719-0.555-2.719-1.492-2.234-2.234-1.492-2.719-0.555z"></path>  
</symbol>  
<symbol id="icon-rewind" viewBox="0 0 24 24">  
<title>rewind</title>  
<path d="M18 4q0.414 0 0.707 0.293t0.293 0.707-0.297 0.711l-6.289 6.289 6.289 6.289q0.297 0.297 0.297 0.711t-0.293 0.707-0.707 0.293q-0.422 0-0.711-0.289l-7-7q-0.289-0.289-0.289-0.711t0.289-0.711l7-7q0.289-0.289 0.711-0.289zM12 4q0.414 0 0.707 0.293t0.293 0.707-0.297 0.711l-6.289 6.289 6.289 6.289q0.297 0.297 0.297 0.711t-0.293 0.707-0.707 0.293q-0.422 0-0.711-0.289l-7-7q-0.289-0.289-0.289-0.711t0.289-0.711l7-7q0.289-0.289 0.711-0.289z"></path>  
</symbol>  
<symbol id="icon-fast-forward" viewBox="0 0 24 24">  
<title>fast-forward</title>  
<path d="M11 4q0.414 0 0.703 0.289l7 7q0.297 0.297 0.297 0.711t-0.297 0.711l-7 7q-0.289 0.289-0.703 0.289t-0.707-0.293-0.293-0.707q0-0.422 0.289-0.711l6.289-6.289-6.289-6.289q-0.289-0.289-0.289-0.711 0-0.43 0.285-0.715t0.715-0.285zM5 4q0.414 0 0.703 0.289l7 7q0.297 0.297 0.297 0.711t-0.297 0.711l-7 7q-0.289 0.289-0.703 0.289t-0.707-0.293-0.293-0.707q0-0.422 0.289-0.711l6.289-6.289-6.289-6.289q-0.289-0.289-0.289-0.711 0-0.43 0.285-0.715t0.715-0.285z"></path>  
</symbol>  
<symbol id="icon-speech-bubble" viewBox="0 0 24 24">  
<title>speech-bubble</title>  
<path d="M4 1h16q1.242 0 2.121 0.879t0.879 2.121v11q0 1.242-0.879 2.121t-2.121 0.879h-8l-7 5v-5h-1q-1.242 0-2.121-0.879t-0.879-2.121v-11q0-1.242 0.879-2.121t2.121-0.879zM20 3h-16q-0.414 0-0.707 0.293t-0.293 0.707v11q0 0.414 0.293 0.707t0.707 0.293h3v3.117l4.359-3.117h8.641q0.414 0 0.707-0.293t0.293-0.707v-11q0-0.414-0.293-0.707t-0.707-0.293z"></path>  
</symbol>  
<symbol id="icon-pie-graph" viewBox="0 0 24 24">  
<title>pie-graph</title>  
<path d="M12 1q2.242 0 4.277 0.871t3.508 2.344 2.344 3.508 0.871 4.277-0.871 4.277-2.344 3.508-3.508 2.344-4.277 0.871-4.277-0.871-3.508-2.344-2.344-3.508-0.871-4.277 0.871-4.277 2.344-3.508 3.508-2.344 4.277-0.871zM11 13v-9.945q-1.664 0.188-3.145 0.965t-2.547 1.957-1.688 2.75-0.621 3.273q0 1.828 0.715 3.496t1.918 2.871 2.871 1.918 3.496 0.715q1.703 0 3.273-0.621t2.75-1.688 1.957-2.547 0.965-3.145h-9.945zM13 3.055v7.945h7.945q-0.172-1.547-0.852-2.934t-1.727-2.434-2.434-1.727-2.934-0.852z"></path>  
</symbol>  
<symbol id="icon-star" viewBox="0 0 24 24">  
<title>star</title>  
<path d="M9.297 9l2.703-8.32 2.703 8.32h8.75l-7.078 4.914 2.703 8.172-7.078-5.18-7.078 5.141 2.703-8.133-7.078-4.914h8.75zM13.25 11l-1.25-3.977-1.25 3.977h-3.883l3.125 2.070-1.227 3.695 3.242-2.344 3.227 2.367-1.227-3.695 3.117-2.094h-3.875z"></path>  
</symbol>  
</defs>  
</svg>  
<!--svg end-->  

添加图标样式

.icon {
    display: inline-block;
    width: 1em;
    height: 1em;
    stroke-width: 0;
    stroke: currentColor;
    fill: currentColor;
    vertical-align: middle
}

导航的动画

从动画中,我们还看到了向下滑的时候,会看到导航的链接出现,也就是点击右上角的 图标按钮 后出现的效果。接下来我们再添加这样的效果。

<div class="nav">  
    <div class="container">

        <div class="nav-list">
            <div class="avatar">
              <img src="http://img1.vued.vanthink.cn/vuedf926d9e80d3eb33c504228105f872e3c.png" />
            </div>
            <div class="quote">
              Jack Pu&#x27;s Blog (蒲小花的博客-ポーのブログ)  
            </div>
                <a href="http://www.jackpu.com/">Home</a>
                <a href="https://www.behance.net/codeui">Design</a>
                <a href="http://www.jackpu.com/tag/web/">Web</a>
                <a href="http://me.jackpu.com/">About Me</a>
        </div>
        <a href="javascript:;" class="menu-icon open">
          <svg width="100%" height="100%" viewBox="0 0 60 60" preserveAspectRatio="none">
            <g id="icon-grid">
              <rect x="32.5" y="5.5" width="22" height="22"></rect>
              <rect x="4.5" y="5.5" width="22" height="22"></rect>
              <rect x="32.5" y="33.5" width="22" height="22"></rect>
              <rect x="4.5" y="33.5" width="22" height="22"></rect>
            </g>
            <g id="icon-cross">
              <line x1="4.5" y1="55.5" x2="54.953" y2="5.046"></line>
              <line x1="54.953" y1="55.5" x2="4.5" y2="5.047"></line>
            </g>
          </svg> 
        </a>
    </div>
</div>  

基本的结构,就是简单的导航链接和控制的svg按钮。

接下来我们添加它的基本样式,它默认是只会出现一个 如下图的按钮菜单。

.nav {
    overflow: hidden;
    z-index: 1000;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 7rem;
    margin-bottom: 0;
    text-align: center;
    font-size: 1.5rem;
    opacity: 1;
    transition: height .6s;
    transition-timing-function: cubic-bezier(0.7,0,0.3,1)
}

.nav .container {
    position: relative;
    width: 1170px;
    height: 100%;
    line-height: 7rem;
    margin: 0 auto
}

.open .nav {
    height: 100%;
    background-color: #fff
}

.open .nav .nav-list {
    opacity: 1;
    transform: translateY(0)
}

.nav-list {
    opacity: 0;
    padding-top: 5rem;
    margin: 0 4rem;
    text-align: center;
    font-size: 2rem;
    line-height: 4rem;
    transition: all .65s;
    transform: translateY(-520px);
    transition-timing-function: cubic-bezier(0.7,0,0.3,1)
}

.nav-list .avatar {
    display: inline-block;
    width: 12rem;
    height: 12rem;
    border-radius: 6rem;
    border: 0.3rem solid #111;
    text-align: center;
    overflow: hidden
}

.nav-list .avatar img {
    width: 100%;
    height: 100%
}

.nav-list .quote {
    font-size: 1.8rem;
    color: #777
}

.nav-list a {
    overflow: hidden;
    display: block;
    width: 20rem;
    height: 4rem;
    margin: 0 auto;
    border-radius: 2rem;
    white-space: nowrap;
    text-overflow: ellipsis;
    transition: all .25s ease;
    text-decoration: underline;
    color: #333;
    transition: all .2s ease
}

.nav-list a:active {
    background: linear-gradient(to left,#ee8326,#ef1d27);
    color: #fff;
    text-decoration: none
}

.nav-list a:hover {
    color: #000
}

.menu-icon {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 2.4rem
}

.menu-icon #icon-grid,.menu-icon #icon-cross {
    opacity: 0;
    stroke: #f1f1f1;
    stroke-width: 2px;
    fill: none;
    transition: all 0.3s ease-in
}

.menu-icon #icon-cross {
    opacity: 1
}

.menu-icon.open #icon-cross {
    opacity: 0
}

.menu-icon.open #icon-grid {
    opacity: 1
}

.open .nav .menu-icon #icon-cross {
    stroke: #333
}

其中,我们可以看到会有 .open 这个 class的存在,实际上它是作用于 body 上的。而添加 open 后,按钮的样式会有小方块变成关闭的按钮,这是用过 svg 的样式控制来实现的。而 nav 这个导航的样式也会有所变化 高度会变成 100%。同时,下面的 slideshow 也会配合动画效果,有下面的样式变化:

.open .slideshow {
    margin-top: 480px
}
.open .slideshow .bg-overlay {
    opacity: 0
}

其中距离顶部高度会变化,而且里面的图片也会变得透明,这样会有淡出的效果。

当然我们需要在 JS 中添加这些控制:

$('.menu-icon').on('click', function (e) {
    $('body').toggleClass('open');
    $(this).toggleClass('open');
});

添加手势

对于手势的支持,我们需要引入 jquery.swipe,这个时候我们添加对于手势的处理,

$("#slideshow").swipe({
  //Generic swipe handler for all directions
  swipe: function (event, direction, distance, duration, fingerCount, fingerData) {
      if (direction == 'left') {
          if (current < containersCount - 1) {
              navigate(pageTriggers[current + 1]);
          }
      } else if (direction == 'right') {
          if (current > 0) {
              navigate(pageTriggers[current - 1]);
          }
      } else if (direction == 'down') {
          var sT = $('html').scrollTop();
          if(sT == 0) {
              $('body').toggleClass('open');
              $('.menu-icon').toggleClass('open');
          } else {
             $('html').animate({'scrollTop': 0},500);  
          }

      } else if(direction == 'up'){
          return false;
      }
  },
  threshold: 0,
  allowPageScroll: 'vertical',
});    
}

完整代码

这样我们就实现了这次新的 slide 的效果, 你可以点击回到主页查看效果。主题项目 github 地址: https://github.com/JackPu/ghost-theme

参考

You Can Speak "Hi" to Me in Those Ways