會有這麼一種狀況,H5頁面須要進行數字統計展現,以此來強調產品or工做的成果。若是隻是靜態顯示一個數字,老是感受生硬。對好比下:
是否是瞬間高大上了呢?
這個效果我是在開源中國上找到的
https://www.oschina.net/code/snippet_2380148_52928
感謝饅頭同窗。css
一、如上圖可知,代碼將每一個數字生成了一豎0-9和小數點的隊列。若是須要滾動999,那麼就會生成3豎
二、因爲有height的限制,因此經過overflow: hidden;
隱藏了其餘已經滾動過的元素。
三、經過transition、transform實現了從0滑動至設置數字動畫效果,其中translateY的值是根據高度計算出來的html
transform: translateY(-120px); transition: 4s;
css樣式,數字的大小,高度,都須要手動設置git
/*數字滾動插件的CSS可調整樣式*/ .mt-number-animate { font-family: '微軟雅黑'; line-height: 40px; height: 40px; /*設置數字顯示高度*/ font-size: 25px; /*設置數字大小*/ overflow: hidden; display: inline-block; position: relative; } .mt-number-animate .mt-number-animate-dot { width: 15px; /*設置分割符寬度*/ line-height: 40px; float: left; text-align: center; } .mt-number-animate .mt-number-animate-dom { width: 20px; /*設置單個數字寬度*/ text-align: center; float: left; position: relative; top: 0; } .mt-number-animate .mt-number-animate-dom .mt-number-animate-span { width: 100%; float: left; } .number-area { position: relative; top: 30%; line-height: 20px; color: white; width: 300px; margin: auto } @media max-width: .number-area .number { position: relative; width: 100%; /*height: 45px*/ } .number-area .number div { float: left; margin-top: 5px; } .number-area .number p { float: left; line-height: 40px; }
JSgithub
/** * by Mantou qq:676015863 * 數字滾動插件 v1.0 */ ; (function($) { $.fn.numberAnimate = function(setting) { var defaults = { speed: 1000, //動畫速度 num: "", //初始化值 iniAnimate: true, //是否要初始化動畫效果 symbol: '', //默認的分割符號,千,萬,千萬 dot: 0 //保留幾位小數點 } //若是setting爲空,就取default的值 var setting = $.extend(defaults, setting); //若是對象有多個,提示出錯 if ($(this).length > 1) { alert("just only one obj!"); return; } //若是未設置初始化值。提示出錯 if (setting.num == "") { alert("must set a num!"); return; } var nHtml = '<div class="mt-number-animate-dom" data-num="{{num}}">\ <span class="mt-number-animate-span">0</span>\ <span class="mt-number-animate-span">1</span>\ <span class="mt-number-animate-span">2</span>\ <span class="mt-number-animate-span">3</span>\ <span class="mt-number-animate-span">4</span>\ <span class="mt-number-animate-span">5</span>\ <span class="mt-number-animate-span">6</span>\ <span class="mt-number-animate-span">7</span>\ <span class="mt-number-animate-span">8</span>\ <span class="mt-number-animate-span">9</span>\ <span class="mt-number-animate-span">.</span>\ </div>'; //數字處理 var numToArr = function(num) { num = parseFloat(num).toFixed(setting.dot); if (typeof(num) == 'number') { var arrStr = num.toString().split(""); } else { var arrStr = num.split(""); } //console.log(arrStr); return arrStr; } //設置DOM symbol:分割符號 var setNumDom = function(arrStr) { var shtml = '<div class="mt-number-animate">'; for (var i = 0, len = arrStr.length; i < len; i++) { if (i != 0 && (len - i) % 3 == 0 && setting.symbol != "" && arrStr[i] != ".") { shtml += '<div class="mt-number-animate-dot">' + setting.symbol + '</div>' + nHtml.replace("{{num}}", arrStr[i]); } else { shtml += nHtml.replace("{{num}}", arrStr[i]); } } shtml += '</div>'; return shtml; } //執行動畫 var runAnimate = function($parent) { $parent.find(".mt-number-animate-dom").each(function() { var num = $(this).attr("data-num"); num = (num == "." ? 10 : num); var spanHei = $(this).height() / 11; //11爲元素個數 var thisTop = -num * spanHei + "px"; if (thisTop != $(this).css("top")) { if (setting.iniAnimate) { //HTML5不支持 if (!window.applicationCache) { $(this).animate({ top: thisTop }, setting.speed); } else { $(this).css({ 'transform': 'translateY(' + thisTop + ')', '-ms-transform': 'translateY(' + thisTop + ')', /* IE 9 */ '-moz-transform': 'translateY(' + thisTop + ')', /* Firefox */ '-webkit-transform': 'translateY(' + thisTop + ')', /* Safari 和 Chrome */ '-o-transform': 'translateY(' + thisTop + ')', '-ms-transition': setting.speed / 1000 + 's', '-moz-transition': setting.speed / 1000 + 's', '-webkit-transition': setting.speed / 1000 + 's', '-o-transition': setting.speed / 1000 + 's', 'transition': setting.speed / 1000 + 's' }); } } else { setting.iniAnimate = true; $(this).css({ top: thisTop }); } } }); } //初始化 var init = function($parent) { //初始化 $parent.html(setNumDom(numToArr(setting.num))); runAnimate($parent); }; //重置參數 this.resetData = function(num) { var newArr = numToArr(num); var $dom = $(this).find(".mt-number-animate-dom"); if ($dom.length < newArr.length) { $(this).html(setNumDom(numToArr(num))); } else { $dom.each(function(index, el) { $(this).attr("data-num", newArr[index]); }); } runAnimate($(this)); } //init init($(this)); return this; } })(jQuery);
例如div的樣式設爲numberRun1web
$(".numberRun1").numberAnimate({ num: '118368', speed: 2000, symbol: "," });
此方案只能定長的每一個數字從0滑動到指定的數字,而不能直接從0滾動,若是這樣動畫就無法播了(除非播放完以後又從頭開始,這樣效率極低)。那麼有沒有方案實現從0滾動的滾動呢?
見http://inorganik.github.io/countUp.js/
源碼也只有200行
https://github.com/inorganik/countUp.js/blob/master/countUp.js
簡單講述一下原理
一、經過遞歸requestAnimationFrame來計算增值
二、經過toFixed精確小數點
三、經過算法實現緩動效果
四、經過正則/[0-9]/g
實現了數字替換(能夠改爲別的字)算法
demo:
https://leestar54.github.io/h5-demo/number_roll.htmlapp