更多文章可關注我的個人博客:https://seven777777.github.io/myblog/
本文主要回顧整理一下之前(大概一年前,😂,這一年實在比較忙 )寫的一個頁面動畫。
之前其實寫了兩種方案,最終使用的如下的方案:
不過本篇文章會將兩種方案都整理出來,方便日後有同樣的需求時可以快速複用,同時也可以給正在實現這個需求的同學們一些參考!
話不多說,開整!
一、滾動式變化
這一種的呈現方式也是我在項目中最終應用的方式,個人覺得更好看一點 😄
1.關於實現原理
其實想要實現這種滾動式數值變化原理非常簡單,就是利用元素的位移,通常如果用css來實現元素的位移動畫的話,我們很容易就會想到animation
屬性。那我們基本上思路就有了:
- 將數值拆分
- 拆分後的每一塊都是單獨的一個模塊,包含數字0~9,只展示當前位應該展示的值,其他的值隱藏
- 變化數值時,根據每一位的變化,通過js再去動態移動數字,從而實現數字滾動變化的效果
大體思路如上,但實際操作過程中,還會有很多細節需要考慮到,比如小數點的顯示,是否顯示千分位符號,數字累計增長計算細節等,接下來就具體來看看如何實現。
2.具體實現
首先,我們html部分只需要一個box來承載顯示結果即可,細節部分我們下面通過JS來添加
// html 部分
<div id="valScrollAmt" class="valScrollAmt-box"></div>
這裏的 id 用於js中的標識,而 class 則用於樣式的編輯。我們這裏命名一個id:valScrollAmt
,下面會使用到。
接下來,我們假設初始值爲 0,首先將其轉換成數組。
說明:文中的代碼主要是方便分解步驟講解的寫法,實際應用中,爲了代碼優雅性,可進行封裝。不想看分解的同學也可以直接
戳這裏 看完整示例代碼
戳這裏 也可以去到我的github查看源碼
戳這裏 直接看效果頁面
const startNum = 0
//將number轉換成string,從而計算長度,如果需要展示千分位符號的,也可以轉換後(轉換後即爲字符串)直接計算長度
const numStr = (startNum + '').length;
let numArr = []
for(var i = 0;i<numStr.length;i++){
numArr.push(numStr.charAt(i));
}
轉換成數組後,接下來就是生成dom,並將其插入最外層的容器中
<!--封裝一個將數組轉換成dom的函數-->
function amtDom(arr){
var str = '';
for(var i = 0;i<arr.length;i++){
if(parseInt(arr[i])>=0){
// 這裏的`scrollItem`是每一位的dom標識,後面也會用到
// `digit-container`就是用來增加樣式的
str += '<div class="scrollItem digit-container" data-show='+arr[i]+'>\
<span>0</span>\
<span>1</span>\
<span>2</span>\
<span>3</span>\
<span>4</span>\
<span>5</span>\
<span>6</span>\
<span>7</span>\
<span>8</span>\
<span>9</span>\
</div>';
}else{
str += '<div class="sign-box"><span>'+arr[i]+'</span></div>';
}
}
return str;
}
// 爲了簡化操作,本文示例使用了jquery語法,使用的時候記得引入jquery
// 這裏的id就是前面定義的唯一標識,注意對應
$("#valScrollAmt").html(amtDom(numArr));
不過此時因爲我們還沒有增加樣式,出來的界面還看不出效果,且有一丟丟醜
下面我們就增加一些樣式,這一步不僅僅是美化,而是必要的,這種實現方式對dom的排版是有固定要求的
//css
.valScrollAmt-box{
display: flex;
height: 28px;
overflow: hidden;
font-size: 20px;
font-weight: bold;
}
.digit-container{
display: flex;
flex-direction: column;
line-height: 28px;
}
以上是滿足需求的一些基本樣式屬性
首先要保證數字的每一位是橫向排列,另外每一位上的0~9必須縱向展示,並且只需展示當前的數值,其餘的數值隱藏顯示。
這裏的高度也很重要,最外層盒子的高度最好要跟內部每一位數字的盒子的高度保持一致,另外這邊的高度也是js裏計算滾動長度的依據。
增加完樣式的樣子就是下面這樣啦
最後就是讓他動起來了
//首先要定好差值爲1的位移高度
let height = $("#valScrollAmt").height();
// 這裏需要注意的是,如果你是需要累計持續增長 那麼就需要將每次的變化前的數值數組緩存下來
// 每次滾動的時候就在舊數值的基礎上計算滾動高度
// 可以定義一個變量如下
let savePositionArr = []
// 然後遍歷所有的位數的dom
$(".scrollItem").each(function(i){
let scrollTopOld,scrollTopNew;
let num = parseInt($(this).data("show"));
scrollTopNew = height * num;
if(!.savePositionArr[i]){
.savePositionArr[i] = 0
}
scrollTopOld = .savePositionArr[i]
$(this).css("margin-top",-scrollTopOld);
if(scrollTopOld != scrollTopNew){
$(this).animate({marginTop: -scrollTopNew},1500);
}
savePositionArr[i] = scrollTopNew // 變化後及時將值替換存起來
});
最終應用的時候可以定義一個定時函數,控制變化的頻率,每次變化的數值也可以根據實際情況設置
最終效果就是這樣啦:
還有一個帶小數點和千分位的效果:
是不是很簡單!😄
二、動態變化
這種方法比較簡單,就不做詳細分解了
,直接上代碼:
// 將數字轉換爲逗號隔開的千分位格式
function num2qfw(num){
num += '';
if (!num.includes('.')) num += '.';
return num.replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) {
return $1 + ',';
}).replace(/\.$/, '');
}
// 數值改變動畫函數
function magic_number(value) {
var num = $("#valChangeAmt");
num.animate({count: value}, {
duration: 500,
step: function() {
num.text(num2qfw(parseInt(this.count)));
},
complete: function () {
num.text(num2qfw(parseInt(value)));
}
});
};
let oldVal = 9374401
function update() {
magic_number(oldVal);
oldVal += Math.random()*100
}
update()
setInterval(update, 3000); //3秒鐘執行一次 update();
效果如下: