Count animation from number A to B

后端 未结 8 949
一个人的身影
一个人的身影 2020-11-30 22:18

I am updating a numeric value inside an element by doing intervalled ajax requests.

To make the whole thing a bit more alive,

相关标签:
8条回答
  • 2020-11-30 22:45

    I had a slightly different approach to this kind of animation. Based on these assumptions:

    1. there is a starting text (as fallback for non-JS browser or google indexing)
    2. this text can contains non-numeric chars
    3. the function take an element directly as first param (as opposed to an element Id)

    So, if you want to animate a simple text like "+300% gross margin", only the numeric part will be animated.

    Moreover, all params have now a default value for start, end and duration.

    https://codepen.io/lucamurante/pen/gZVymW

    function animateValue(obj, start = 0, end = null, duration = 3000) {
        if (obj) {
    
            // save starting text for later (and as a fallback text if JS not running and/or google)
            var textStarting = obj.innerHTML;
    
            // remove non-numeric from starting text if not specified
            end = end || parseInt(textStarting.replace(/\D/g, ""));
    
            var range = end - start;
    
            // no timer shorter than 50ms (not really visible any way)
            var minTimer = 50;
    
            // calc step time to show all interediate values
            var stepTime = Math.abs(Math.floor(duration / range));
    
            // never go below minTimer
            stepTime = Math.max(stepTime, minTimer);
    
            // get current time and calculate desired end time
            var startTime = new Date().getTime();
            var endTime = startTime + duration;
            var timer;
    
            function run() {
                var now = new Date().getTime();
                var remaining = Math.max((endTime - now) / duration, 0);
                var value = Math.round(end - (remaining * range));
                // replace numeric digits only in the original string
                obj.innerHTML = textStarting.replace(/([0-9]+)/g, value);
                if (value == end) {
                    clearInterval(timer);
                }
            }
    
            timer = setInterval(run, stepTime);
            run();
        }
    }
    
    animateValue(document.getElementById('value'));
    #value {
        font-size: 50px;
    }
    <div id="value">+300% gross margin</div>

    0 讨论(0)
  • 2020-11-30 22:45

    This is what i came up with:

    function animateVal(obj, start=0, end=100, steps=100, duration=500) {   
        start = parseFloat(start)
        end = parseFloat(end)
    
        let stepsize = (end - start) / steps
        let current = start
        var stepTime = Math.abs(Math.floor(duration / (end - start)));
        let stepspassed = 0
        let stepsneeded = (end - start) / stepsize
    
        let x = setInterval( () => {
                current += stepsize
                stepspassed++
                obj.innerHTML = Math.round(current * 1000) / 1000 
            if (stepspassed >= stepsneeded) {
                clearInterval(x)
            }
        }, stepTime)
    }   
    
    animateVal(document.getElementById("counter"), 0, 200, 300, 200)
    
    0 讨论(0)
提交回复
热议问题