transform,transition,animation的混合使用——高手之路

源自世界發表於2017-05-20

每個製作出來的css3動畫都凝結了設計者和創作者智慧的結晶,以此,我們要向前輩致敬;動畫的出現給單調的網頁平添了活性,是單純的展示頁面變得不再那麼枯燥,所以,作為一個web前端的開發者能夠創作出屬於自己的特有的動畫,我感到很高興。

今天,我向大家介紹實現css下拉選單的動畫製作的不同方法,希望能給大家有所幫助和啟示。首先,先來個效果圖給大家看一看:

transform,transition,animation的混合使用——高手之路
滑鼠滑過--下拉選單動畫

transform,transition,animation的混合使用——高手之路
單擊--下拉選單動畫

那麼接下來我就給大家介紹一下這個動畫的組成,它主要包括三個小動畫組成。第一部分就是滑鼠的滑過的漸變動畫;第二部分,就是右邊的三角小箭頭的動畫,這個說起來也很簡單,這個三角形是使用css樣式寫的控制元素的四條邊的顏色和各邊的顯隱來形成;第三部分,就是展開的下拉框。

根據我之前寫過的一篇文章《transform,transition,animation的混合使用——進階》中對動畫的組合形式的分類,將動畫的實現分類有transform和transition組合,transform和animation組合,再結合動畫的觸發形式,pc端常見的滑鼠滑過、滑鼠單擊,wap端的觸控形式,該動畫的最終的呈現形式將以下四種常見形式:
第一種,實現方案用transition(滑鼠滑過)
第二種,實現方案用animation(滑鼠滑過)
第三種,實現方案用transition(滑鼠單擊或觸控)
第四種,實現方案用animation(滑鼠單擊或觸控)

我將詳細講解前兩種的實現,後兩種的實現(略講),由於是觸發方式的改變,所以對於javascript有一定使用經驗的同學將會根據自己的使用習慣很容易的形成自己所需要的程式碼,進而形成自己的css動畫下拉選單的解決方案。

滑鼠滑過--下拉選單動畫

transition和transform組合
html程式碼:

<div class="l-drop-menu l-menu-1">
        <span>下拉選單</span>
        <ul class="l-list">
            <li class="l-list-item"><a href="http://www.baidu.com">百度一下</a></li>
            <li class="l-list-item"><a href="http://www.bing.com">bing搜尋</a></li>
            <li class="l-list-item"><a href="http://www.iconfont.cn/">iconfont</a></li>
        </ul>
    </div>複製程式碼

css程式碼:

.l-list {
    position: absolute;
    top: 100%;
    z-index: -1;
    width: 100%;
    padding: 4px 0;
    background-color: #fff;
    border: 1px solid #cecece;
    box-sizing: border-box;
    opacity: 0;
}

.l-list-item {
    list-style: none;
    padding: 4px 8px;
}

.l-list-item a {
    display: block;
    padding: 4px 0;
    font-size: 16px;
    color: #000;
    text-align: center;
    text-decoration: none;
    transition: all 0.2s linear;
}

.l-list-item a:hover {
    color: #fff;
    background-color: #cecece;
}

.l-drop-menu {
    position: relative;
    width: 142px;
    height: auto;
    margin: 0 auto;
}

.l-drop-menu>span {
    position: relative;
    display: block;
    padding: 8px 20px;
    text-align: center;
    color: #58a;
    background-color: #fff;
    cursor: pointer;
}

.l-drop-menu>span::after {
    position: absolute;
    top: 8px;
    right: 16px;
    content: '';
    width: 0;
    height: 0;
    overflow: hidden;
    border-width: 8px;
    border-style: dashed dashed solid;
    border-color: transparent transparent #c2c2c2;
    transition: all 0.3s linear;
}

.l-drop-menu>span:hover {
    color: #fff;
    background-color: #cecece;
}

.l-drop-menu>span:hover::after {
    top: 16px;
    border-style: solid dashed dashed;
    border-color: #ffffff transparent transparent;
}複製程式碼

以上是animation和transition兩種不同實現形式的公用程式碼。

transiton實現形式的程式碼

.l-menu-1 .l-list {
     transform: translate3d(0, 10px, 0);
    backface-visibility: hidden;
    transition: all 0.3s linear;
}

.l-menu-1:hover .l-list {
    z-index: 2;
    overflow: auto;
    opacity: 1;
    transform: translate3d(0, 0, 0);
}複製程式碼

animation實現形式的css程式碼

.l-menu-2 .l-list{
    animation: l-animation-up 0.5s;
}

.l-menu-2:hover .l-list{
    z-index: 2;
    opacity: 1;
    animation: l-animation-down 0.5s;
}

@-webkit-keyframes l-animation-down {
    from {
        -webkit-transform: translate3d(0, 10px, 0);
        opacity: .1
    }
    to {
        -webkit-transform: translate3d(0, 0, 0);
        opacity: 1
    }
}

@keyframes l-animation-down {
    from {
        transform: translate3d(0, 10px, 0);
        opacity: .1
    }
    to {
        transform: translate3d(0, 0, 0);
        opacity: 1
    }
}

@-webkit-keyframes l-animation-up {
    from {
        -webkit-transform: translate3d(0, 0, 0);
        opacity: 1
    }
    to {
        -webkit-transform: translate3d(0, 10px, 0);
        opacity: .1
    }
}

@keyframes l-animation-up {
    from {
        transform: translate3d(0, 0, 0);
        opacity: 1
    }
    to {
        transform: translate3d(0, 10px, 0);
        opacity: .1
    }
}複製程式碼

程式碼曬完了,我們就來說一說做這個動畫的注意點吧!

1.第一種用transition和transform的形式,下拉框我們通常的實現形式通過定位來實現,本案例的實現形式和傳統的實現形式並無二樣;
2.第一種用transition和transform的形式,我們傳統的控制顯隱我們使用的是display:none,display:block;但明顯這種方案用在這裡不合適,使用這種解決方案的結果就是沒用過渡效果,也即是沒有了動畫效果,我採用了opacity和z-index來解決這種問題(詳情檢視和分析程式碼);
3.第二種用animation和transform的形式,這種實現形式我相信大家在學習和工作中都看過,但這種形式要實現的動畫效果和第一種之間,我覺得地址用實現形式更好,因為這個第二種,只有展開時的過渡效果,而沒有閉合時的過渡效果,對於要求並不高的同學來說,或許這樣的效果還不錯,但是對於我這種追求極客的來說,我還是不滿足,所以,我就試著有加入了一個移開時的動畫,實現了跟第一種一樣的動畫效果(有一個重新整理頁面的問題),但我要接著說的是在第二點中我有提過有opacity和z-index解決transition形式動畫沒有過渡的情況,在第二種形式,display:none,display:block這種控制顯隱的方式也可用。

transform,transition,animation的混合使用——高手之路
animation和transition對比以及animation的重新整理問題效果圖

綜上,下拉選單動畫最優選擇第一種,其次,選擇第二種。

演示地址:lvzhenbang.github.io/css3-animat…

單擊--下拉選單動畫

單擊的動畫和滑鼠滑過的動畫效果區別就是觸發形式的不同,從而造成了css程式碼的相應差異,transition通過單擊實現就是通過改變在元素中新增.l-menu-active來實現;animation通過單擊實現就是通過在元素中新增.l-menu-in, .l-menu-out來實現的。

html程式碼同上

css程式碼 公用和上面兩個例子重合的程式碼如下:

.l-list {
    position: absolute;
    top: 100%;
    display: none;
    width: 100%;
    background-color: #fff;
    box-sizing: border-box;
}

.l-list-item {
    list-style: none;
    padding: 4px 8px;
    border-top: 1px solid #cecece;
}

.l-list-item a {
    display: block;
    padding: 4px 0;
    font-size: 16px;
    color: #000;
    text-align: center;
    text-decoration: none;
    -webkit-transition: all 0.2s linear;
}

.l-list-item a:hover {
    color: #fff;
    background-color: #cecece;
}

.l-drop-menu {
    position: relative;
    width: 142px;
    height: auto;
    margin: 0 auto;
}

.l-drop-menu>span {
    position: relative;
    display: block;
    padding: 10px 20px;
    text-align: center;
    color: #58a;
    background-color: #fff;
    cursor: pointer;
}

.l-drop-menu>span::after {
    position: absolute;
    top: 16px;
    right: 16px;
    content: '';
    width: 0;
    height: 0;
    overflow: hidden;
    border-width: 8px;
    border-style: solid dashed dashed;
    border-color: #58a transparent transparent;
    -webkit-transition: all 0.3s linear;
    transition: all 0.3s linear;
}複製程式碼

transition實現的程式碼:

.l-drop-menu.l-menu-active>span, .l-drop-menu.l-menu-in>span {
    color: #fff;
    background-color: #cecece;
}

.l-drop-menu.l-menu-active>span::after, .l-drop-menu.l-menu-in>span::after {
    top: 8px;
    border-style: dashed dashed solid;
    border-color: transparent transparent #58a;
}

.l-menu-1.l-menu-active .l-list {
    display: block;
    -webki-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
}

.l-menu-1 .l-list {
    -webkit-transform: translate3d(0, 10px, 0);
    transform: translate3d(0, 10px, 0);
    -webkit-transition: all 0.3s linear;
    transition: all 0.3s linear;
}複製程式碼

animation的程式碼:

.l-menu-2.l-menu-out .l-list {
    display: none;
    -webkit-animation: l-animation-up 0.5s;
    animation: l-animation-up 0.5s;
}

.l-menu-2.l-menu-in .l-list {
    display: block;
    -webkit-animation: l-animation-down 0.5s;
    animation: l-animation-down 0.5s;
}

@-webkit-keyframes l-animation-down {
    from {
        -webkit-transform: translate3d(0, 10px, 0);
    }
    to {
        -webkit-transform: translate3d(0, 0, 0);
    }
}

@keyframes l-animation-down {
    from {
        transform: translate3d(0, 10px, 0);
    }
    to {
        transform: translate3d(0, 0, 0);
    }
}

@-webkit-keyframes l-animation-up {
    from {
        -webkit-transform: translate3d(0, 0, 0);
    }
    to {
        -webkit-transform: translate3d(0, 10px, 0);
    }
}

@keyframes l-animation-up {
    from {
        transform: translate3d(0, 0, 0);
    }
    to {
        transform: translate3d(0, 10px, 0);
    }
}複製程式碼

綜上,你會發現transition實現的動畫,當你單擊時發現動畫用display:none,display:block;這種方式依然不能達到預期的效果,所以還是應該採用opacity和z-index的方案;但是使用animation測沒有任何問題,與此同時當你重新整理網頁時,不會出現問題。

所以,當單擊實現下拉選單這兩種方案都不錯,但是理解起來相對簡單的是animation的形式。

transform,transition,animation的混合使用——高手之路
單擊--下拉選單動畫(左邊是使用display:none,display:block)

關於如何改transition的單擊實現方案,各位同學可以當作一個小例子來實踐一下。

transition的js程式碼:

var menu1 = document.getElementsByClassName('l-menu-1')[0];

menu1.onclick = function() {
    var className = menu1.className;
    if (~className.indexOf('l-menu-active')) {
        menu1.className = className.replace(' l-menu-active', '');
    } else {
        menu1.className += ' l-menu-active';
    }
}複製程式碼

animation的js程式碼:

var menu2 = document.getElementsByClassName('l-menu-2')[0];
menu2.onclick = function() {
    var className = menu2.className;
    if (~className.indexOf('l-menu-in')) {
        menu2.className = className.replace('l-menu-in', 'l-menu-out');
    } else {
        menu2.className += ' l-menu-in';
    }
}複製程式碼

演示地址:lvzhenbang.github.io/css3-animat…

接下來的文章我會給大家帶來一些我自己的做css動畫的

原始碼下載地址:github地址:https://github.com/lvzhenbang/css3-animate/tree/gh-pages

相關文章