CSS3 實現
用 CSS3 實現動畫,顯然,我們想到的是用 animation 。
首先看下 animation 合併寫法,具體含義就不解釋了,如果需要可以自行了解。
animation: name duration timing-function delay iteration-count direction fill-mode play-state;
我們開始來一步一步實現。
Step 1: 固定區域,設置基本樣式
首先,我們先準備 1 張點贊動畫圖片:
看一下 HTML 結構。外層一個結構固定整個顯示動畫區域的位置。這裏在一個寬 100px ,高 200px 的 div 區域。
Step 2: 運動起來
使用 animation 的幀動畫,定義一個 bubble_y 的幀序列。
.bl1{
animation:bubble_y 4s linear 1 forwards ;
}
@keyframes bubble_y {
0% {
margin-bottom:0;
}
100% {
margin-bottom:200px;
}
}
這裏設置運行時間 4s ;
採用線性運動 linear,如果有需求當然也可以使用其他曲線,比如 ease;
每個點贊動畫只運行 1 次;
動畫是隻需要向前 forwards。
Step 3: 增加漸隱
漸隱效果,使用 opacity 即可。這裏我們固定在最後 1/4 開始漸隱。修改 bubble_y:
@keyframes bubble_y {
0% {
margin-bottom:0;
}
75%{
opacity:1;
}
100% {
margin-bottom:200px;
opacity:0;
}
}
Step 4: 增加動畫放大效果
在最開始一小段時間,圖片由小變大。
於是我們新增一個動畫:bubble_big_1。
這裏從 0.3 倍原圖放大到 1 倍。這裏注意運行時間,比如上面設置,從動畫開始到結束總共是 4s,那麼這個放大時間就可以按需設置了,比如 0.5s。
.bl1{
animation:bubble_big 0.5s linear 1 forwards;
}
@keyframes bubble_big_1 {
0% {
transform: scale(.3);
}
100% {
transform: scale(1);
}
}
Step 5: 設置偏移
我們先定義幀動畫:bubble_1 來執行偏移。圖片開始放大階段,這裏沒有設置偏移,保持中間原點不變。
在運行到 25% * 4 = 1s,即 1s之後,是向左偏移 -8px, 2s 的時候,向右偏移 8px,3s 的時候,向做偏移 15px ,最終向右偏移 15px。
大家可以想到了,這是定義的一個經典的左右擺動軌跡,“向左向右向左向右” 曲線擺動效果。
@keyframes bubble_1 {
0% {
}
25% {
margin-left:-8px;
}
50% {
margin-left:8px
}
75% {
margin-left:-15px
}
100% {
margin-left:15px
}
}
Step 6: 補齊動畫樣式
這裏預設了一種運行曲線軌跡,左右擺動的樣式,我們在再預設更多種曲線,達到隨機軌跡的目的。
比如 bubble_1 的左右偏移動畫軌跡,我們可以修改偏移值,來達到不同的曲線軌跡。
Step 7: JS 操作隨機增加節點樣式
提供增加點讚的方法,隨機將點讚的樣式組合,然後渲染到節點上。
let praiseBubble = document.getElementById(“praise_bubble”);
let last = 0;
function addPraise() {
const b =Math.floor(Math.random() * 6) + 1;
const bl =Math.floor(Math.random() * 11) + 1; // bl1~bl11
let d = document.createElement(“div”);
d.className = bubble b${b} bl${bl}
;
d.dataset.t = String(Date.now());
praiseBubble.appendChild(d);
}
setInterval(() => {
addPraise();
},300)
在使用 CSS 來實現點讚的時候,通常還需要注意設置 bubble 的隨機延時,比如:
.bl2{
animation:bubble_2 $bubble_time linear .4s 1 forwards,bubble_big_2 $bubble_scale linear .4s 1 forwards,bubble_y $bubble_time linear .4s 1 forwards;
}
這裏如果是隨機到 bl2,那麼延時 0.4s 再運行,bl3 延時 0.6s ……
如果是批量更新到節點上,不設置延時的話,那就會扎堆出現。隨機“ bl ”樣式,就隨機了延時,然後批量出現,都會自動錯峯顯示。我們還需要增加當前用戶手動點讚的動畫,這個不需要延時。
另外,有可能同時別人下發了點贊 40 個,業務需求通常是希望這 40 個點贊氣泡都能依次出現,製造持續的點贊氛圍,否則下發量大又會扎堆顯示了。
那麼我們還需要分批打散點贊數量,比如一次點讚的時間($bubble_time)是 4s, 那麼 4s 內,希望同時出現多少個點贊呢?比如是 10個,那麼 40 個點贊,需要分批 4 次渲染。
window.requestAnimationFrame(() => {
// 繼續循環處理批次
render();
});
另外還需要手動清除節點。以防節點過多帶來的性能問題。如下是完整的效果圖。
源碼:源碼