原文轉載自「劉悅的技術部落格」https://v3u.cn/a_id_197
喜歡看電影的朋友肯定會注意到一個有趣的細節,就是電影出品方一定會在片頭的Logo環節做一個小特效:暗影流動之間光澤一閃而過,這樣做不僅可以提高Logo的辨識度,還可以提升質感,一舉兩得。參照華納兄弟影業(Warner Bros. Pictures)的例子:
那麼,在前端領域,如果使用純CSS技術,能不能實現類似的特效呢?答案當然是可以的,這次我們以本站的Logo為例子,以一持萬、提綱挈領地講解一下如何使用純CSS技術實現圖片Logo滑鼠懸停光澤一閃而過的光影特效。
一般情況下,大多數前端開發會選擇 linear-gradient() ,這個方法建立一個表示兩種或多種顏色線性漸變的圖片。其結果屬於<gradient>資料型別,是一種特別的<image>資料型別。
簡單用法:
/* 漸變軸為45度,從藍色漸變到紅色 */
linear-gradient(45deg, blue, red);
/* 從右下到左上、從藍色漸變到紅色 */
linear-gradient(to left top, blue, red);
/* 從下到上,從藍色開始漸變、到高度40%位置是綠色漸變開始、最後以紅色結束 */
linear-gradient(0deg, blue, green 40%, red);
那麼它怎麼和logo圖片結合使用呢?首先建立一個物件,因為是logo,所以我使用a標籤,也就是超級連結,隨後宣告偽類mylogo:
<a href="/" class="mylogo" title="劉悅的技術部落格"></a>
之後,定義logo的樣式:
.mylogo{
display:block;
margin: 0 auto;
width:255px;
height:200px;
background-image:/logo.png;
background-repeat: no-repeat;
}
接著就是linear-gradient()出場,原理並不複雜,利用linear-gradient繪製一個白色半透明漸變層,利用背景的負座標隱藏起來,同時配合transition屬性,在滑鼠懸停(hover)的時候,設定1秒鐘的延時動畫,逐漸將光斑的座標進行位移,產生一種光澤掠過的效果:
.mylogo{
width: 255px;
height: 200px;
background: -webkit-linear-gradient(left, rgba(255,255,255,0)0, rgba(255,255,255,0.5)50%, rgba(255,255,255,0)100%) no-repeat -270px 0, url(/logo.png) no-repeat;
transition: 1s ease;
}
.mylogo:hover {
background-position: 200px 0, 0 0;
}
這裡需要注意的是,預設負座標一定要超過logo本體的寬度,否則位移就不夠充分,效果是下面這樣的:
看起來還不錯,這裡transition的屬性設定在logo本體的偽類上面,此時如果logo本體失去滑鼠的焦點,光斑位置又會回到原來的負座標,此時光影又會在回閃一次,也就是一次懸停發生兩次位移,閃爍兩次,如果只想閃一次,可以將transition載入hover偽類中,這樣離開後不會二次位移,因為動畫效果只會出現在滑鼠懸停上,滑鼠離開後,就沒有動畫回閃了:
.mylogo{
width: 255px;
height: 200px;
/*直接使用background縮放版本*/
/*每個漸變點的位置不能太小,不然會出現殘缺光斑*/
/*no-repeat -270px 0:將光斑定位隱藏起來*/
background: -webkit-linear-gradient(left, rgba(255,255,255,0)0, rgba(255,255,255,0.5)50%, rgba(255,255,255,0)100%) no-repeat -270px 0, url(/logo.png) no-repeat;
/* transition: 1s ease; */
}
.mylogo:hover{
/*滑鼠滑過實現光斑滑動,但是在多背景情況下,需要多個background-position屬性值,否則會影響其他背景*/
background-position: 200px 0, 0 0;
transition: 1s ease;
}
效果是這樣的:
但是這就結束了嗎?還沒有,因為這看起來似乎。。。有點一律千篇?
如果所有人都用linear-gradient,就難免有點無趣了,那麼有沒有別的不落窠臼的玩兒法呢?
既然曉得了原理,無非就是位移產生的小把戲,那麼我們完全脫離linear-gradient,使用一張帶光澤質感的背景圖片shine.png:
由於使用了背景圖,所以我們需要對程式碼進行修改,為實體的背景圖新增一個容器,span標籤:
<a href="/" class="mylogo" title="劉悅的技術部落格"><span></span></a>
樣式和linear-gradient差不多,也是利用負座標將span標籤內的背景圖隱藏起來:
.mylogo span {
display: block;
background: url("/shine.png") -360px -380px no-repeat;
transition-property: all;
transition-duration: .7s;
height: 200px;
width: 255px;
}
接下來要比linear-gradient要簡單地多,直接設定懸停屬性,讓背景圖片發生位移:
.mylogo:hover span {
background-position: 100px 300px;
}
效果是這樣的:
如果仔細觀察,會發現背景圖更加契合光影掠過的效果,因為linear-gradient每個漸變點在不同解析度的螢幕下並不統一,也就是說在高分辨下會出現殘缺光斑。
暗黑模式下的效果是這樣的:
看起來似乎更加有質感一點,除此之外,也許你還想利用transition玩一些更加刺激的效果:
.mylogo:hover {
-webkit-transform: rotate(666turn);
transform: rotate(666turn);
transition-delay: 1s;
transition-property: all;
transition-duration: 59s;
transition-timing-function: cubic-bezier(.34, 0, .84, 1)
}
讓我們旋轉、跳躍、閉著眼:
結語:兩套方案都可以很好的實現光影特效,區別在於linear-gradient並不會消耗網站的頻寬,但會消耗電腦的CPU和記憶體,而與背景漸變相比,背景影像效果會更好一點,但是將會更多地使用網路頻寬,而webp技術又可以幫助我們對圖片進行極致的壓縮(參見:https://v3u.cn/a\_id\_190),所以我們可以理解這是一種權衡,畢竟,書本上寫的是道理,但是現實中講究的是取捨,不是嗎?
原文轉載自「劉悅的技術部落格」 https://v3u.cn/a_id_197