舉重若輕流水行雲,前端純CSS3實現質感非凡的圖片Logo滑鼠懸停(hover)光澤一閃而過的光影特效

劉悅的技術部落格發表於2021-12-04

原文轉載自「劉悅的技術部落格」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

相關文章