zoukankan      html  css  js  c++  java
  • 那些H5用到的技术(6)——数字滚动特效

    前言

    会有这么一种情况,H5页面需要进行数字统计展示,以此来强调产品or工作的成果。如果只是静态显示一个数字,总是感觉生硬。对比如下:

    是不是瞬间高大上了呢?
    这个效果我是在开源中国上找到的
    https://www.oschina.net/code/snippet_2380148_52928
    感谢馒头同学。

    原理

    1、如上图可知,代码将每个数字生成了一竖0-9和小数点的队列。如果需要滚动999,那么就会生成3竖
    2、由于有height的限制,所以通过overflow: hidden;隐藏了其他已经滚动过的元素。
    3、通过transition、transform实现了从0滑动至设置数字动画效果,其中translateY的值是根据高度计算出来的

    transform: translateY(-120px);
    transition: 4s;

    源码

    css样式,数字的大小,高度,都需要手动设置

        /*数字滚动插件的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 {
             15px;
            /*设置分割符宽度*/
            line-height: 40px;
            float: left;
            text-align: center;
        }
    
        .mt-number-animate .mt-number-animate-dom {
             20px;
            /*设置单个数字宽度*/
            text-align: center;
            float: left;
            position: relative;
            top: 0;
        }
    
        .mt-number-animate .mt-number-animate-dom .mt-number-animate-span {
             100%;
            float: left;
        }
    
        .number-area {
            position: relative;
            top: 30%;
            line-height: 20px;
            color: white;
             300px;
            margin: auto
        }
    
        @media max- .number-area .number {
            position: relative;
             100%;
            /*height: 45px*/
        }
    
        .number-area .number div {
            float: left;
            margin-top: 5px;
        }
    
        .number-area .number p {
            float: left;
            line-height: 40px;
        }

    JS

        /**
        *  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的样式设为numberRun1

        $(".numberRun1").numberAnimate({
            num: '118368',
            speed: 2000,
            symbol: ","
        });

    补充

    CountUp.js

    此方案只能定长的每个数字从0滑动到指定的数字,而不能直接从0滚动,如果这样动画就没法播了(除非播放完之后又从头开始,这样效率极低)。那么有没有方案实现从0滚动的滚动呢?

    http://inorganik.github.io/countUp.js/
    源码也只有200行
    https://github.com/inorganik/countUp.js/blob/master/countUp.js
    简单讲述一下原理
    1、通过递归requestAnimationFrame来计算增值
    2、通过toFixed精确小数点
    3、通过算法实现缓动效果
    4、通过正则/[0-9]/g实现了数字替换(可以改成别的字)

    demo:
    https://leestar54.github.io/h5-demo/number_roll.html

  • 相关阅读:
    今日总结
    今日总结
    每日总结
    每日总结
    小程序之navigator跳转方式
    vue面试题(上)
    ES6 中的 set 用法
    维信小程序 如何 实现下拉刷新?
    微信小程序的相关文件类型有哪些??
    vue中v-if与v-show的区别以及使用场景
  • 原文地址:https://www.cnblogs.com/leestar54/p/7481934.html
Copyright © 2011-2022 走看看