老闆的網頁實驗室 #1 — 實作CSS拆字動畫

案例解析

https://rogue.studio/

這次的老闆網頁實驗室,要來分析一個國外的工作室網站,在這個網站中,有標題一個一個字跑入的效果,這樣的效果怎麼達到的呢?其實這樣的效果並不複雜,程式上也不會特別難達到,老闆特別喜歡他遮罩切入的感覺,要怎麼樣重現這個標題動畫套到網頁上呢?

https://rogue.studio/
https://rogue.studio/

在分析這個案例的時候很有趣的點是,如果一個一個自己手動去指定字最後擺放的位置會很麻煩,所以我們應該盡可能的利用 html 本身layout的功能,讓每個字母產生在我們希望他正常排列在文字裡面的位置之後,再把他拆成不同的元素做動畫。


第一個步驟 — 將文字拆成兩層span

首先,我們第一個目標是將整段文字,拆成分別的元素,才能去控制動畫。

內外框的拆字
內外框的拆字

在看原本的網頁時,你會發現切進來的效果彷彿原本字母的框框位置並沒有移動,超出框框的部分被切掉,所以在這種情況下,應該要分成內外兩個框框,外部的框框負責才切多出來的部分,內部的利用tranform移動,在不影響排版的情況下移動到框框裡面來。

我們希望html中內容可以越簡單越好,不用去管動畫,只要加上一個class — slideLetterIn,動畫就會自動處理跟套上去。

<h1 class=”slideLetterIn”> MONOAME STUDIO </h1>

在抓到所有有slideLetterIn的class後,我們可以利用span標籤,與inline-block屬性,把原本在同一個元素裡面的字母拆成一個一個的span,再整包放會去,讓他們當下仍參與整個字母的排列,所以乍看之下會跟還沒有拆開之前相同,但實際上已經變成內外兩層的方塊文字了!

這邊用到的是js的陣列操作方法 -map轉換跟join結合,中間的過程使用split(“”)把字串拆成一個一個文字,放入雙層的span,join成新的整坨html之後放回原本的元素裡面去。

var titleEls = document.querySelectorAll(".slideLetterIn")
titleEls.forEach(el=>{
  el.innerHTML = el.innerText
    .split("")
    .map(l=> `<span class='outer'>
                <span class='inner'>${l}</span>
              </span>`)
    .join("")
})

第二個步驟 — 製作 CSS 動畫跟控制

接下來,我們要製作一個組keyframe動畫,讓他套在每個字母上,並讓他們之間有時間差。

我們在看動畫控制的時候,可以先找出重複動作的部分,每個字母切進來的轉的角度跟移動相同,但是一個一個字會循序漸進進來。對於每一個字母我們可以套用相同的動畫,透過display: inline-block 讓他參與排列在同一行,同時有block屬性做transform。

.slideLetterIn 
  .outer
    overflow: hidden
    display: inline-block
  .inner
    display: inline-block
    transform: translate(70%) rotate(30deg)
  &.active /* 當字母進來時加上這個class */
    inner
      transform: translateX(0px)

然後字母根據他們是在整段文字裡面的第幾個元素來指定delay的時間,用scss(或sass)程式化的方式產生 nth-child(i),依序指定他們的transition-delay即可。

.slideLetterIn 
  span
    //使用loop指定第1-100個元素每個都會慢0.05秒開始動畫
    @for $i from 1 through 100
      &:nth-child(#{$i}) .inner
        transition-delay: #{$i*0.05s}
進出的delay效果

速度控制曲線參考: https://easings.net/#easeInOutSine

靈活的應用速度曲線,能比用預設的緩進緩出(ease-in-out) 帶來更生動的感覺,這次使用的easeOutQuint,是用四次方倍的動畫速度播放,因此動作開始時會比較快,創造俐落但是有彈性的感受,使用上只要把cubic-bezier指定進來到css的transition屬性即可。

速度曲線

第三個步驟 — 製作景深hover

第三個步驟是最後的點綴,網頁上滑鼠滑到字母上的時候,會有種往後移動失焦的感覺,滑鼠離開後慢慢的回復,在原始的網站中,一個字母變糊後會影響到周圍的幾個字也跟著糊,這邊製作簡易版的滑鼠上去會讓字糊化,離開時會需要一段時間恢復狀態製造連續的感覺。

Hover時模糊

直接套用預設的動畫速度看起來會很死板,因此我這邊技巧上讓他hover前後的變換時間不同,一但滑鼠移動到上面開始動畫後,就改變成快速進入的速度曲線到達最糊的狀態,滑鼠移出時,則是套用原本的緩入曲線,讓他慢慢回覆到原始的狀態,quadIn緩出的動畫速度套上去,然後變回來時再使用緩進的動畫速度。

span
  &.outer
    transition: 1s cubic-bezier(0.55, 0.055, 0.675, 0.19) //進出有不同的速度曲線
    cursor: pointer
    &:hover
      filter: blur(5px)
      transition: 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) //進出有不同的速度曲線
      opacity: 0.9
      transform: scale(0.97)

測試控制的部分我,我們加上一個checkbox,讓他改變時會去toggle最外層的class,加上了active是文字進入,會把單獨文字的transform設為0,文字就會進來,移除active就會套用原本文字的旋轉跟位移,讓文字跑出框框。

<div class="control">
  <label>Toggle
    <input id="toggle" type="checkbox" onchange="toggle()"/>
  </label>
</div>
function toggle(){
  document.querySelector(".slideLetterIn").classList.toggle("active")
}
setTimeout(function(){ 
  toggle()
},1000)

登愣,老闆上菜啦!

最後做出來的效果是這樣:

See the Pen SliceInTexts by Majer @Monoame Design (@frank890417) on CodePen.

其實這個範例的效果也可以用其他方式達到,比如canvas或是WebGL,就能夠達成更酷的像是文字扭曲、粒子特效、色散的效果。

如果大家有興趣看更多類似的分享的話,留言回覆你想要看什麼網站的拆解,老闆會帶著雞尾酒跟檸檬來拆解各式各樣有趣的網站,這篇如果超過15個留言的話,就來教大家怎麼去做區塊的模糊效果,以及能用哪些其他的方式去玩速度曲線,變化應用在不同的使用情境!

參考資料:

課程推薦

老闆在Hahow好學校開了兩門課,其中,動畫互動網頁程式入門(HTML/CSS/JS)以簡單例子帶你入門網站的基礎架構及開發,用素材刻出簡單有趣又美觀的網頁和動畫,享受做出獨一無二的網頁所帶來的成就感,在職場上與設計師和工程師合作無間。

打好基本的互動網頁基礎之後,可以進階動畫互動網頁特效入門(JS/CANVAS),紮實掌握JavaScript 程式與動畫基礎以及進階互動,整合應用掌控資料與顯示的Vue.js前端框架,完成具有設計感的互動網站。期待在課程裡見到你!

墨雨設計banner

訂閱 Creative Coding Taiwan 電子報:

PHP Code Snippets Powered By : XYZScripts.com