css-文字充電效果
開啟掘金成長之旅!這是我參與「掘金日新計劃 · 12 月更文挑戰」的第31天,點選檢視活動詳情
前言
今年Apple推出了搭載M2晶片的新款MacBook Pro和MacBook Air,得到訊息第一時間也是去Apple官網看看介紹,看看他們的產品網頁,這次沒有什麼特別的,但是有個電池續航20小時的文字有一個充電的效果
今天就來實現這個充電的效果,並且使用到了CSS的新函式clamp()
實現充電效果
在HTML部分使用亂數假文自動生成隨機文字
```html
Lorem ipsum dolor sit amet consectetur adipisicing elit.
```
然後加入body選擇器,用Flexbox的方法將內容上下左右居中,設定背景顏色為黑色
css
body{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #000;
}
然後加入h1選擇器,文字先設為白色,寬度設為50%,將字距收窄一點,使用letter-spacing設為-3px
css
h1{
color: #fff;
width: 50%
margin: 0 auto;
font-family: Helvetica;
font-size: 60px;
letter-spacing: -3px;
}
要做到充電的效果關乎到兩個顏色,白色和綠色,這裡使用linear-gradient()去達到
h1選擇器加入background-image(漸層顏色是套用background-image而不是background-color),使用linear-gradient(),先設定白色50%,然後綠色50%
css
h1{
background-image: linear-gradient(#fff 50%,#4cd265 50%);
}
然後加上background-clip: text
,以文字作為遮罩,再將文字設為透明色color: transparent
h1選擇器定義一個CSS變數 --progress:0,在0的時候文字是全白色,1的時候是全綠色,然後將兩個50%的值替換成calc()計算,將--progress改為0.5看看效果
```css --progress:0.5;
background-image: linear-gradient(#fff calc(100% - calc(var(--progress) * 100%)),#4cd265 calc(100% - calc(var(--progress) * 100%))); ```
但是就這樣效果就有點寡,在充滿電的時候將文字放大一些,放大使用transform:scale(1.3)
,充電的完成度完全由--progress控制,當--progress小於1的時候scale()設為1,等於1的時候scale()設為1.3,但是css沒有if判斷式可以用
這裡使用一個新的css函式clamp(),這個函式接收三個值,第一個值最小值,我們填1,第三個值最大值,我們填3,而第二個值,如果少於1的話結果就是1,如果大於1.3結果就是1.3,如果在1和1.3之間的話,結果就是第二個值設定值
假設每次充電都加0.01,即100充滿電,通過calc(),var(--progress)-0.99再乘一個比較大的值,--progress在0.99或以下的時候scale()為1,--progress為1時scale()為1.3,再加入一個動畫的過渡
css
transform: scale(clamp(1,calc((var(--progress)-0.99) * 200),1.3));
transition: .3s transform ease-out;
最後,就是處理觸發動畫的部分了,定義一個變數progress,然後定義一個run函式,裡面判斷如果progress少於1的話progress加0.01,為了確保計算的精度準確,先用toFixed(2)轉換為兩個小數位再用parseFloat()轉換為數字,然後通過setProperty()將progress設定到css變數中,再加一個setTimeout(),每隔20毫秒就執行一次run函式
js
let progress=0
function run(){
if(progress<1){
progress=parseFloat((progress + 0.01).toFixed(2))
document.querySelector('h1').style.setProperty('--progress',progress)
console.log(progress);
setTimeout(run, 20);
}
}
run()
看看最終效果