1. 程式人生 > 實用技巧 >CSS 計數器的妙用:數字遞增動效

CSS 計數器的妙用:數字遞增動效

CSS 計數器是由 CSS 維護的變數,這些變數可根據 CSS 規則增加從而跟蹤使用次數。我們可以利用這個特性,根據文件位置來調整內容表現,比如顯示列表編號。

最近在公司官網就用到了這個特性:

image.png

因為這裡的序號只是個裝飾,並不強調先後順序。比起使用真實 DOM 元素顯示序號,CSS 計數器更加簡潔靈活,萬一內容順序需要調整,序號也不受影響。

有時候我們會看到某些 Dashboard 介面有數字快速滾動的效果,比如招行 App 的賬戶餘額。這種效果怎麼實現呢?本文會介紹幾種方法。

JavaScript 方案

最簡單的莫過於用setInterval定時器了,定期修改 DOM 內容就行。不過為了實現更平順的動畫效果,更推薦使用requestAnimationFrame

:

functionanimateValue(obj,start,end,duration){
letstartTimestamp=null;
conststep=(timestamp)=>{
if(!startTimestamp)startTimestamp=timestamp;
constprogress=Math.min((timestamp-startTimestamp)/duration,1);
obj.innerHTML=Math.floor(progress*(end-start)+start);
if(progress<1){
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
}

constobj=document.getElementById("value");
animateValue(obj,100,0,5000);

js.gif

CSS @keyframes 結合 margin

這個思路比較有意思,原理是把數字排成一行,通過動畫移動元素位置來顯示不同位置的數字:

<divclass="counter">
<divclass="numbers">
<div>0</div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
</div>
.counter{
width:100px;
overflow:hidden;
}
.numbers{
width:auto;
display:flex;
animation:countNumber4sinfinitealternate;
animation-timing-function:steps(10);
}
.numbersdiv{
text-align:center;
flex:00100px;
}

@keyframescountNumber{
0%{
margin-left:0px;
}
100%{
margin-left:-1000px;
}
}

keyframe.gif

CSS 計數器入門版

CSS 計數器使用到以下幾個屬性:

  • counter-reset - 建立或者重置計數器

  • counter-increment - 遞增變數

  • content - 插入生成的內容

  • counter() 或 counters() 函式 - 將計數器的值新增到元素

要使用 CSS 計數器,得先用 counter-reset 建立。結合 CSS 動畫@keyframes,在動畫的不同階段設定不同的遞增值,就能實現這個效果:

<div></div>
div::after{
content:counter(count);
animation:counter3slinearinfinitealternate;
counter-reset:count0;
}

@keyframescounter{
0%{
counter-increment:count0;
}
10%{
counter-increment:count1;
}
20%{
counter-increment:count2;
}
30%{
counter-increment:count3;
}
40%{
counter-increment:count4;
}
50%{
counter-increment:count5;
}
60%{
counter-increment:count6;
}
70%{
counter-increment:count7;
}
80%{
counter-increment:count8;
}
90%{
counter-increment:count9;
}
100%{
counter-increment:count10;
}
}

CSS 計數器高配版

更進一步,如果敢用最新特性,其實有更秀的操作,那就是給 CSS 變數設定動畫。這個技巧的核心就是設定 CSS 自定義屬性為整數型別,這樣就能像其他擁有整數型別值的 CSS 屬性一樣,可用於transition中了。

@property--num{
syntax:'<integer>';
initial-value:0;
inherits:false;
}

div{
transition:--num1s;
counter-reset:numvar(--num);
}
div:hover{
--num:10000;
}
div::after{
content:counter(num);
}

不過需要注意的是,目前只有 Chrome (或者 Chromium 核心的瀏覽器比如 Edge 和 Opera)支援@property語法,因此相容性是個問題。如果你的頁面只針對 Chrome(比如 Electron 應用),那就可以放心使用。否則還是用前面的保守方案吧。

小數也能玩動畫

前面說的變數都要求是整數,那能不能讓小數也支援這種動畫呢?答案是可以的。

可以把小數轉成整數。步驟原理是:

  1. 註冊一個整型的 CSS 變數(即--number),指定初始值initial-value

  2. calc將值取整:--integer: calc(var(--number))

@property--integer{
syntax:"<integer>";
initial-value:0;
inherits:false;
}
--number:1234.5678;
--integer:calc(var(--number));/*1235*/

如果只需要提取整數部分,可以這樣:--integer: max(var(--number) - 0.5, 0),連calc()都不需要了。類似方法可以提取小數部分。

/*@property--integer*/
--number:1234.5678;
--integer:max(var(--number)-0.5,0);/*1234*/

完整程式碼:

<div></div>
@property--percent{
syntax:"<number>";
initial-value:0;
inherits:false;
}
@property--temp{
syntax:"<number>";
initial-value:0;
inherits:false;
}
@property--v1{
syntax:"<integer>";
initial-value:0;
inherits:false;
}
@property--v2{
syntax:"<integer>";
initial-value:0;
inherits:false;
}

div{
font:80040pxmonospace;
padding:2rem;
transition:--percent1s;
--temp:calc(var(--percent)*100);
--v1:max(var(--temp)-0.5,0);
--v2:max((var(--temp)-var(--v1))*100-0.5,0);
counter-reset:v1var(--v1)v2var(--v2);
}
div::before{
content:counter(v1)"."counter(v2,decimal-leading-zero)"%";
}
constgenNumber=()=>{
document.querySelector("div").style.setProperty("--percent",Math.random());
};

setInterval(genNumber,2000);
setTimeout(genNumber);

decimal.gif

順手點“在看”,每天早下班;轉發加關注,共奔小康路~

來源:迅聞網