我的部落格:[譯] CSS 變數實現炫酷滑鼠懸浮效果
我最近從Grover網站上的有趣的懸停動畫中獲得靈感。將滑鼠移動到訂閱按鈕上可以顯示游標移動後的彩色漸變。這個想法很簡單,但結果是一個按鈕從復位和等待點選中脫穎而出。
那怎樣實現類似的效果使我們的網站同樣出色呢?很好,它並沒有你想象的那麼困難!
跟蹤位置
我們需要做的第一件事便是跟蹤滑鼠游標的位置。
document.querySelector('.button').onmousemove = (e) => {
const x = e.pageX - e.target.offsetLeft
const y = e.pageY - e.target.offsetTop
e.target.style.setProperty('--x', `${ x }px`)
e.target.style.setProperty('--y', `${ y }px`)
}
複製程式碼
- 選中目標元素並監聽使用者滑鼠劃過的事件
- 計算滑鼠相對於該元素的座標
- 將座標儲存到 CSS 的變數中
是的,只需要 6 行程式碼就可以讓你的 CSS 知道使用者滑鼠的位置。通過這些資訊你可以實現更多更龐大的效果。但是讓我們先實現 CSS 部分……
為漸變設定動畫效果
我們已經將滑鼠座標儲存在 CSS 變數中,所以可以在 CSS 中的任何地方使用它們。(以下為 SCSS 程式碼)
.button {
position: relative;
appearance: none;
background: #f72359;
padding: 1em 2em;
border: none;
color: white;
font-size: 1.2em;
cursor: pointer;
outline: none;
overflow: hidden;
border-radius: 100px;
span {
position: relative;
}
&::before {
--size: 0;
content: '';
position: absolute;
left: var(--x);
top: var(--y);
width: var(--size);
height: var(--size);
background: radial-gradient(circle closest-side, #4405f7, transparent);
transform: translate(-50%, -50%);
transition: width .2s ease, height .2s ease;
}
&:hover::before {
--size: 400px;
}
}
複製程式碼
- 將文字包裹在一個
span
中,防止漸變層覆蓋到文字上方 - 初始
width
和height
為0px
並且當滑鼠懸浮在按鈕上時將它們增加到400px
。不要忘記設定transition
讓它有個漸入的效果 - 使用 JS 中設定座標跟隨滑鼠
- 應用一個
radial-gradient
到background
上並使用closest-side circle
。closest-side
使得background
充滿整個before
但又沒有超出它。
效果
就這樣,新增缺少的 HTML 就可以了:
<button class="button">
<span>Hover me I'm awesome</span>
</button>
複製程式碼
See the Pen Mouse movement button with border-radius by Tobias Reich (@electerious) on CodePen.
擴充
只需對滑鼠的位置作出反應,即可建立如此多的效果。它非常華麗並且使得?互動如此有趣。
以下是我在basicScroll的網站上使用的類似動畫:
May the hover be with you https://t.co/2jrmVorLRW
或者看中並建立一個 3D 視差按鈕:
3D parallax button with JS controlled CSS variables @CodePen ? https://t.co/qE0woiNip8 https://t.co/Wyi0xjRzPq
可能性是無止境的。你可以在下方評論區分享你使用它建立的效果?。
Q&A
Q: 為什麼使用 width
和 height
而不是使用 transform: scale()
實現動畫呢?
A: 對於動畫的效能, width
和 height
是不好的,你可能會盡量地嘗試使用 transform
。你為什麼我不這樣做呢?問題在於瀏覽器在加速圖層中呈現元素(正在轉換)。當按鈕具有非矩形邊緣時,此圖層可能會導致問題。
Q: 為什麼改變 top
和 left
而不是 transform: translate()
呢?
A: 參照上條。
Q: 我可以在 Twitter 關注你嗎?
A: 當然。(原作者推特 @electerious)