案例解析
這次的老闆網頁實驗室,要來分析一個國外的工作室網站,在這個網站中,有標題一個一個字跑入的效果,這樣的效果怎麼達到的呢?其實這樣的效果並不複雜,程式上也不會特別難達到,老闆特別喜歡他遮罩切入的感覺,要怎麼樣重現這個標題動畫套到網頁上呢?
在分析這個案例的時候很有趣的點是,如果一個一個自己手動去指定字最後擺放的位置會很麻煩,所以我們應該盡可能的利用 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}
速度控制曲線參考: https://easings.net/#easeInOutSine
靈活的應用速度曲線,能比用預設的緩進緩出(ease-in-out) 帶來更生動的感覺,這次使用的easeOutQuint,是用四次方倍的動畫速度播放,因此動作開始時會比較快,創造俐落但是有彈性的感受,使用上只要把cubic-bezier指定進來到css的transition屬性即可。
第三個步驟 — 製作景深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個留言的話,就來教大家怎麼去做區塊的模糊效果,以及能用哪些其他的方式去玩速度曲線,變化應用在不同的使用情境!
參考資料:
- 這次的拆解來源:https://rogue.studio/
- 範例連結:https://codepen.io/frank890417/pen/dyPbgWW?editors=0011
- CSS Display inline-block: https://www.w3schools.com/css/css_inline-block.asp
- CSS transition curve 曲線網站:https://easings.net/#
- JS Array Methods: https://www.w3schools.com/js/js_array_methods.asp
- CSS Filter Blur: https://developer.mozilla.org/en-US/docs/Web/CSS/filter
課程推薦
老闆在Hahow好學校開了兩門課,其中,動畫互動網頁程式入門(HTML/CSS/JS)以簡單例子帶你入門網站的基礎架構及開發,用素材刻出簡單有趣又美觀的網頁和動畫,享受做出獨一無二的網頁所帶來的成就感,在職場上與設計師和工程師合作無間。
打好基本的互動網頁基礎之後,可以進階動畫互動網頁特效入門(JS/CANVAS),紮實掌握JavaScript 程式與動畫基礎以及進階互動,整合應用掌控資料與顯示的Vue.js前端框架,完成具有設計感的互動網站。期待在課程裡見到你!