css3元素出現動畫實例

css3中實現動畫通常有兩種方式,一個是transition過渡,一個是animation動畫。最主要區別就是transition須要條件觸發,一般會用hover來觸發,而animation則更靈活,能夠自動播放,也能夠經過條件觸發。css

那麼,如何實現一個元素出現動畫呢?css3

若是是transition,能夠很輕鬆的實現這一效果,例如瀏覽器

.box{
  visibility:hidden;
  opacity:0;
  transform:translateY(100px);
  transition:.3s;
}
.show{
  visibility:visible;
  opacity:1;
  transform:translateY(0);
}

這樣就實現了一個「從下至上,透明度從0至1」的出現動畫,很經常使用不是嗎。app

https://codepen.io/xboxyan/pe...框架

固然,咱們也能夠用animation來實現,dom

.box{
  visibility:hidden;
  opacity:0;
  transform:translateY(100px);
  transition:.3s;
}
.show{
  animation:show .5s forwards;
}

.hide{
  visibility:visible;
  opacity: 1;
  transform: translateY(0);
  animation:hide .5s forwards;
}
@keyframes show{
  to {
    visibility:visible;
    opacity: 1;
    transform: translateY(0)
  }
}
@keyframes hide{
  to {
    visibility:hidden;
    opacity: 0;
    transform: translateY(100px)
  }
}

個人天,竟然要寫這麼多,才能實現和上面同樣的效果,沒辦法,出現和消失是兩組不一樣的動畫,因此須要定義兩個動畫。ide

https://codepen.io/xboxyan/pe...性能

元素出現動畫

上面簡單的介紹了動畫的兩種實現方法。嚴格來說,transition只是過渡,只是切換樣式過程當中有動畫的效果,而animation纔是真正作動畫的。固然也須要根據本身的實際需求來選擇。測試

下面來看這樣一個需求:動畫

一般頁面上要全局顯示一個消息提示,相似於toast效果。這是我一般的作法

function showMessage(txt){
    this.timer && clearTimeout(this.timer);
    var oDiv = document.getElementById('messageInfo');
    if(!oDiv){
      oDiv = document.createElement('div');
      oDiv.className = 'messageInfo';
      oDiv.id = 'messageInfo';
      document.body.appendChild(oDiv);
    }
    oDiv.innerHTML = '<span>'+txt+'</span>';
    oDiv.classList.add('show');
    this.timer = setTimeout(function(){
      oDiv.classList.remove('show');
    },2000)
}

原理就是,向頁面添加一個div#messageInfo容器,而後添加類名.show讓元素出現,2s後自動移除.show實現隱藏,效果以下

https://codepen.io/xboxyan/pe...

能夠很明顯的看到一個效果就是,第一次出現的時候是沒有動畫的,之後就正常了。可能平時項目中,這一點小瑕疵也沒什麼影響,畢竟很大一部分人連動畫都不給啊,直接就是display:nonedisplay:block,能夠說是提不上體驗了。

那麼,爲何會出現這種現象呢?

首先明白一點,transition是不會自動觸發的,上面是經過添加和移除類名來實現過渡效果的。可是在第一次元素剛剛建立的時候,此時在頁面上該元素還未加載完成,這個時候當即添加類名,實際上是能夠等同因而一塊兒建立的,沒有造成過渡效果。解決這個問題很簡單,就是稍微延時一下

//...
setTimeout(function(){
   oDiv.classList.add('show');
},50)
//...

這樣就基本上解決了這個問題,以下

https://codepen.io/xboxyan/pe...

可是,理論上這裏的延遲越小越好,我測試了一下,大概和瀏覽器的性能有關吧,用定時器的目的也僅僅是等待元素加載完成,而dom也沒有原生監聽加載完成事件,因此只能用定時器估一個大概的值。

可是,這仍然是一個瑕疵,從代碼結構上來說,這也是沒法忍受的。那麼,還有沒有更好的方法呢?答案就是animation

Animation

雖然從開頭的例子來看,animation的寫法又臭又長,可是也正體現出它的功能強大,其中之一就是自動播放動畫

那麼,把上面的toast改造一下,用animation實現

.messageInfo{ 
    /**...**/
    animation:show .5s forwards;
}
.hide{
  visibility:visible;
  opacity: 1;
  transform: translateY(0);
  animation:hide .5s forwards;
}
@keyframes show{
  to {
    visibility:visible;
    opacity: 1;
    transform: translateY(0)
  }
}
@keyframes hide{
  to {
    visibility:hidden;
    opacity: 0;
    transform: translateY(-100%)
  }
}

js基本和以前一致

function showMessage(txt){
    this.timer && clearTimeout(this.timer);
    var oDiv = document.getElementById('messageInfo');
    if(!oDiv){
      oDiv = document.createElement('div');
      oDiv.className = 'messageInfo';
      oDiv.id = 'messageInfo';
      document.body.appendChild(oDiv);
    }
    oDiv.innerHTML = '<span>'+txt+'</span>';
    oDiv.classList.remove('hide');//默認是顯示
    this.timer = 
      setTimeout(function(){
      oDiv.classList.add('hide');//2s後隱藏
    },2000)
}

效果以下

https://codepen.io/xboxyan/pe...

能夠說是至關完美了

其餘應用場景

元素添加動畫

一般在添加表單或者上傳圖片時,若是須要讓新添加的元素產生一個動畫效果,那麼能夠用到animation

https://codepen.io/xboxyan/pe...

固然,還能夠作到分頁加載動畫,須要給每一個元素添加一個延時animation-delay便可

/*animation-delay*/
.list li:not(.hide):nth-child(5n + 1) {
    animation-delay: .3s;
}
.list li:not(.hide):nth-child(5n + 2) {
    animation-delay: .6s;
}
.list li:not(.hide):nth-child(5n + 3) {
    animation-delay: .9s;
}
.list li:not(.hide):nth-child(5n + 4) {
    animation-delay: 1.2s;
}
.list li:not(.hide):nth-child(5n + 5) {
    animation-delay: 1.5s;
}

效果以下,元素會依次登場,預覽窗口比較小,建議在原連接查看

https://codepen.io/xboxyan/pe...

而後,還能夠實現九宮格動畫,讓元素在出現的時候從左上方依次向右下方擴散,一樣是用到了animation-delay

https://codepen.io/xboxyan/pe...

很酷炫不是嗎,無需用到js,也無需用到其它框架,純自然,支持的瀏覽器體驗更上一層樓,不支持的瀏覽器也無傷大雅

小節

整體來講,animation遠比transition要強大的多,固然在實際使用中也要分場景(好比文章開頭的那個例子很明顯就是transition更好),若是有交互,如鼠標移入,首先看transition可否實現,其次纔是animation,若是像這一類元素出現(生成)動畫,那麼就須要使用到animation了。

相關文章
相關標籤/搜索