使用JS實現數值動態變化動畫效果

更多文章可關注我的個人博客: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();

效果如下:

搴芳拾夢
歡迎關注的我的個人公衆號【搴芳拾夢】
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章