【问题标题】:Animate lines in a donut chart using a canvas使用画布为圆环图中的线条制作动画
【发布时间】:2017-11-22 17:11:42
【问题描述】:

基本上,我尝试为圆环图中的线条制作动画(请参阅example),以便它们中的每一个都与 document.ready 一起计数。我尝试采用herehere的解决方案

如您所见,countUp 解决方案已经运行良好,但需要连接到图表,以便在页面加载时绘制。

我对画布的了解并不惊人。如果有人可以提供帮助,我会很高兴。这是代码:https://jsfiddle.net/9oyoh67x/10/

$(document).ready(function () {        
var canvas = document.getElementById('canvas');
            var ctx = canvas.getContext('2d');
            console.log(ctx);
            ctx.lineWidth = 19;
            ctx.lineCap = 'round';
            ctx.shadowBlur = 10;
            donutChart(); 
            function degtoRad(degree) {
                var factor = Math.PI / 180; // = 1 deg = 0.01745 rad
                return degree * factor; // for 360 = 6.28 = 360°
            }

            /*function move() {
                var elem = document.getElementById("canvas");
                var width = 0;
                var id = setInterval(countUp, 1000); }
            */

            $(function () {
                var countUp = setInterval(function () { donutChart }, 40);
                function count($this) {
                    var current = parseInt($this.html(), 10);
                    $this.html(++current);
                    if (current !== $this.data('count')) {
                        setTimeout(function () { count($this) }, 50);
                    }
                }
                $(".testspan1").each(function () {
                    $(this).data('count', parseInt($(this).html(), 10));
                    $(this).html('0');
                    count($(this));
                });   
                 $(".testspan2").each(function () {
                    $(this).data('count', parseInt($(this).html(), 10));
                    $(this).html('0');
                    count($(this));
                });   
                 $(".testspan3").each(function () {
                    $(this).data('count', parseInt($(this).html(), 10));
                    $(this).html('0');
                    count($(this));
                });   
                 $(".testspan4").each(function () {
                    $(this).data('count', parseInt($(this).html(), 10));
                    $(this).html('0');
                    count($(this));
                });   
            });            

            function donutChart() {
                var factor_calc = Math.PI / 180;
                var record = $('.testspan1').text(); // equal to 100% or 360°
                var average = $('.testspan2').text();
                var income = $('.testspan2').text();
                var target = $('.testspan3').text();


                // Record
                ctx.strokeStyle = 'rgba(115, 100, 164, 1)';
                ctx.beginPath();
                ctx.arc(250, 250, 200, degtoRad(270), degtoRad(270 + (record / record) * 360));
                ctx.stroke();

                // Average
                ctx.strokeStyle = 'rgba(125, 131, 164, 1)';
                ctx.beginPath();
                ctx.arc(250, 250, 170, degtoRad(270), degtoRad(270 + (average / record) * 360));
                ctx.stroke();

                //Income
                ctx.strokeStyle = 'rgba(75, 181, 164, 1)';
                ctx.beginPath();
                ctx.arc(250, 250, 140, degtoRad(270), degtoRad(270 + (income / record) * 360));
                ctx.stroke();

                // Target
                ctx.strokeStyle = 'rgba(26, 221, 164, 1)';
                ctx.beginPath();
                ctx.arc(250, 250, 110, degtoRad(270), degtoRad(270 + (target / record) * 360));
                ctx.stroke();

                // Record
                ctx.font = "25px Philosopher";
                ctx.fillStyle = 'rgba(115, 100, 164, 1)';
                ctx.fillText(record, 220, 200);

                //Average
                ctx.font = "25px Philosopher";
                ctx.fillStyle = 'rgba(125, 131, 164, 1)';
                ctx.fillText(average, 220, 230);

                //Income
                ctx.font = "30px Philosopher";
                ctx.fillStyle = 'rgba(75, 181, 164, 1)';
                ctx.fillText(income, 220, 260);

                // Target
                ctx.font = "35px Philosopher";
                ctx.fillStyle = 'rgba(26, 221, 164, 1)';
                ctx.fillText(target, 220, 290);

                // Euro
                ctx.font = "60px Philosopher";
                ctx.fillStyle = 'rgba(26, 221, 164, 1)';
                ctx.fillText('€', 280, 255);
            }

            var options = {
                useEasing: true,
                useGrouping: true,
                separator: ',',
                decimal: '',
                prefix: '',
                suffix: '€'

            };
        });

HTML:

        <div class="canvasdiv">
        <canvas id="canvas" width="500" height="500"></canvas>
        <img id="myImage" />
        <span class='testspan1'>1250</span>
        <span class='testspan2'>250</span>
        <span class='testspan3'>450</span>
        <span class='testspan4'>130</span>
    </div>

对于有类似问题的人,这里有一些进一步的相关链接(不使用画布):

【问题讨论】:

    标签: javascript jquery canvas jquery-animate donut-chart


    【解决方案1】:

    我做到了。这是我的解决方案(https://jsfiddle.net/9oyoh67x/12/):

    // requestAnimationFrame Shim
    (function start() {
        var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
            window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
        window.requestAnimationFrame = requestAnimationFrame;
    })();
    
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    console.log(ctx);
    ctx.lineWidth = 19;
    ctx.lineCap = 'round';
    ctx.shadowBlur = 10;
    var record = 820; // equal to 100% or 360°
    var record_count = (record / record * 100)
    var average = (229 / record * 100);
    var income = (490 / record * 100);
    var target = (750 / record * 100);
    var counterClockwise = true;
    var circ = Math.PI * 2;
    var quart = Math.PI / 2;
    var startTime1 = null;
    var startTime2 = null;
    var startTime3 = null;
    var startTime4 = null;
    var duration = null;
    var duration1 = null;
    var duration2 = null;
    var duration3 = null;
    var duration4 = null;
    var options = {
        useEasing: true,
        useGrouping: true,
        separator: ',',
        decimal: '0',
        prefix: '',
        suffix: ''
    };
    
    
    function animate_rec(time) {
    
        if (!startTime1) {
            startTime1 = time;
        }
    
        var delta1 = Math.min(1, (time - startTime1) / duration1);
        var curPerc = ((2 * Math.PI) / 100) * (record_count * delta1);
        console.log(curPerc)
        var innerNumRec = (record * delta1);
        //console.log(innerNumRec);
    
        ctx.strokeStyle = 'rgba(115, 100, 164, 1)';
        ctx.beginPath();
        ctx.arc(250, 250, 200, -quart, curPerc - quart);
        ctx.stroke();
    
        if (delta1 < 1) {
            requestAnimationFrame(animate_rec);
            ctx.clearRect(215, 180, 50, 30);
        } else {
            startTime1 = null;
            ctx.clearRect(215, 180, 50, 30);
        }
    
    
    
        // Record
        ctx.font = "25px Philosopher";
        ctx.fillStyle = 'rgba(115, 100, 164, 1)';
        ctx.fillText(Math.round(innerNumRec), 220, 200);
    }
    
    var startAnim_rec = function () {
        duration1 = 3000;
        requestAnimationFrame(animate_rec);
    };
    
    function animate_avg(time) {
    
        if (!startTime2) {
            startTime2 = time;
        }
    
        var delta2 = Math.min(1, (time - startTime2) / duration2);
        var curPerc = ((2 * Math.PI) / 100) * (average * delta2);
        var innerNumAvg = ((average * record / 100) * delta2);
        console.log(innerNumAvg);
    
        ctx.strokeStyle = 'rgba(125, 131, 164, 1)';
        ctx.beginPath();
        ctx.arc(250, 250, 170, -quart, curPerc - quart);
        ctx.stroke();
    
        if (delta2 < 1) {
            requestAnimationFrame(animate_avg);
            ctx.clearRect(215, 210, 70, 50);
        } else {
            startTime2 = null;
            ctx.clearRect(215, 210, 70, 50);
        }
    
        // Average
        ctx.font = "30px Philosopher";
        ctx.fillStyle = 'rgba(125, 131, 164, 1)';
        ctx.fillText(Math.round(innerNumAvg), 220, 230);
    
    }
    
    var startAnim_avg = function () {
        duration2 = 3200;
        requestAnimationFrame(animate_avg);
    };
    
    function animate_inc(time) {
    
        if (!startTime3) {
            startTime3 = time;
        }
    
        var delta3 = Math.min(1, (time - startTime3) / duration3);
        var curPerc = ((2 * Math.PI) / 100) * (income * delta3);
        var innerNumInc = ((income * record / 100) * delta3);
        console.log(innerNumInc);
    
        ctx.strokeStyle = 'rgba(75, 181, 164, 1)';
        ctx.beginPath();
        ctx.arc(250, 250, 140, -quart, curPerc - quart);
        ctx.stroke();
    
        if (delta3 < 1) {
            requestAnimationFrame(animate_inc);
            ctx.clearRect(215, 230, 70, 50);
        } else {
            startTime3 = null;
            ctx.clearRect(215, 230, 70, 50);
        }
    
        // Income
        ctx.font = "35px Philosopher";
        ctx.fillStyle = 'rgba(75, 181, 164, 1)';
        ctx.fillText(Math.round(innerNumInc), 220, 260);
    }
    
    var startAnim_inc = function () {
        duration3 = 3400;
        requestAnimationFrame(animate_inc);
    };
    
    function animate_tar(time) {
        if (!startTime4) {
            startTime4 = time;
        }
    
        var delta4 = Math.min(1, (time - startTime4) / duration4);
        var curPerc = ((2 * Math.PI) / 100) * (target * delta4);
        var innerNumTar = ((target * record / 100) * delta4);
        console.log(innerNumTar);
    
        ctx.strokeStyle = 'rgba(26, 221, 164, 1)';
        ctx.beginPath();
        ctx.arc(250, 250, 110, -quart, curPerc - quart);
        ctx.stroke();
    
        if (delta4 < 1) {
            requestAnimationFrame(animate_tar);
            ctx.clearRect(220, 260, 70, 50);
        } else {
            startTime4 = null;
            ctx.clearRect(220, 260, 70, 50);
        }
    
        // Target
        ctx.font = "40px Philosopher";
        ctx.fillStyle = 'rgba(26, 221, 164, 1)';
        ctx.fillText(Math.round(innerNumTar), 220, 290);
    }
    
    var startAnim_tar = function () {
        duration4 = 3600;
        requestAnimationFrame(animate_tar);
    };
    
    startAnim_rec();
    startAnim_avg();
    startAnim_inc();
    startAnim_tar();
    
    // Euro
    ctx.font = "60px Philosopher";
    ctx.fillStyle = 'rgba(26, 221, 164, 1)';
    ctx.fillText('€', 280, 255);});
    

    【讨论】:

      猜你喜欢
      • 2013-12-21
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      • 2014-06-29
      相关资源
      最近更新 更多