简体   繁体   English

画布条形图动画

[英]Canvas Bar Graph Animation

I'm trying to get up to speed on the canvas tag and I'm getting stuck when it comes to basic animations. 我正试图在画布标签上加快速度,在基本动画方面我遇到了困难。 I've searched around and I can get most of the tutorials I've found working, but I've had some trouble translating that into what I'm trying to do. 我已经四处搜索了,我可以得到大部分我发现的教程,但是我在将其转化为我想要做的事情时遇到了一些麻烦。

I have a bar graph that I'm building for my portfolio, and I would like to have the ability to animate the bars on the graph. 我有一个条形图,我正在为我的投资组合构建,我希望能够为图形上的条形图设置动画。 Basically when the page loads, the bars start from the bottom of the graph, and grow upwards to where they need to be. 基本上,当页面加载时,条形图从图形的底部开始,并向上增长到它们需要的位置。 I have a version I built in jquery found here to give an idea of what I'm after: http://jokedesigns.com/portfoliov6/ 我有一个我在jquery中构建的版本,可以在这里找到我想要的内容: http//jokedesigns.com/portfoliov6/

Could someone point me in the right direction on how to achieve the animations I'm looking for? 有人能指出我如何实现我正在寻找的动画的正确方向吗? Even if its a simple function I should be able to rework it into what I need. 即使它是一个简单的功能,我应该能够将它重新制作成我需要的东西。 Most of the tutorials I've found mainly deal with rotation, I did find one that was a linear animation, but I still wasn't able to quite rework that into what I need. 我发现的大多数教程主要涉及旋转,我确实找到了一个线性动画,但我仍然无法将其重新修改为我需要的东西。

Here is the code I have so far for the graph: 这是我到目前为止图表的代码:

<html>
  <head>
    <script type="application/javascript">
function loadImages(sources, callback) {
    var images = {};
    var loadedImages = 0;
    var numImages = 0;
    // get num of sources
    for(var src in sources) {
      numImages++;
    }
    for(var src in sources) {
      images[src] = new Image();
      images[src].onload = function() {
        if(++loadedImages >= numImages) {
          callback(images);
        }
      };
      images[src].src = sources[src];
    }
  }
function draw() {
  var canvas = document.getElementById("canvas");
   var canvasbg = document.getElementById("canvasbg");
  if (canvas.getContext) {
    var ctx = canvas.getContext("2d");
    var ctx2 = canvasbg.getContext("2d");
    var img = new Image();
    img.onload = function(){
        ctx2.drawImage(img,0,0);
    };
    img.src = 'skills_bg.jpg';
    ctx.fillStyle = "#0a4888";
    ctx.fillRect (0, 82, 34, 50);
    ctx.fillStyle = "#ed9323";
    ctx.fillRect (60, 82, 34, 50);
    ctx.fillStyle = "#87982d";
    ctx.fillRect (120, 82, 34, 50);
    ctx.fillStyle = "#902e63";
    ctx.fillRect (180, 82, 34, 50);
    ctx.fillStyle = "#262627";
    ctx.fillRect (360, 82, 34, 50);
    ctx.fillStyle = "#262627";
    ctx.fillRect (420, 82, 34, 50);
    ctx.fillStyle = "#262627";
    ctx.fillRect (480, 82, 34, 50);
    ctx.fillStyle = "#262627";
    ctx.fillRect (540, 82, 34, 50);
    ctx.fillStyle = "#262627";
    ctx.fillRect (600, 82, 34, 50);
    ctx.fillStyle = "#262627";
    ctx.fillRect (660, 82, 34, 50);
    ctx.fillStyle = "#262627";
    ctx.fillRect (720, 82, 34, 50);
    ctx.fillStyle = "#262627";
    ctx.fillRect (780, 82, 34, 50);
    ctx.fillStyle = "#262627";
    ctx.fillRect (840, 82, 34, 50);

    var sources = {
        ps: 'icn_ps.png',
        ai: 'icn_ai.png',
        dw: 'icn_dw.png',
        id: 'icn_id.png',
        ht: 'icn_html.png',
        cs: 'icn_css.png',
        js: 'icn_js.png',
        sql: 'icn_mysql.png',
        php: 'icn_php.png',
        perl: 'icn_perl.png',
        ruby: 'icn_ruby.png',
        cplus: 'icn_cplusplus.png',
        asp: 'icn_asp.png'
    };
    loadImages(sources, function(images) {
        ctx.drawImage(images.ps, 0, 132, 36, 37);
        ctx.drawImage(images.ai, 60, 132, 36, 37);
        ctx.drawImage(images.dw, 120, 132, 36, 37);
        ctx.drawImage(images.id, 180, 132, 36, 37);
        ctx.drawImage(images.ht, 360, 132, 36, 37);
        ctx.drawImage(images.cs, 420, 132, 36, 37);
        ctx.drawImage(images.js, 480, 132, 36, 37);
        ctx.drawImage(images.sql, 540, 132, 36, 37);
        ctx.drawImage(images.php, 600, 132, 36, 37);
        ctx.drawImage(images.perl, 660, 132, 36, 37);
        ctx.drawImage(images.ruby, 720, 132, 36, 37);
        ctx.drawImage(images.cplus, 780, 132, 36, 37);
        ctx.drawImage(images.asp, 840, 132, 36, 37);
    });

  }
}

</script>
</head>
<body onload="draw();">
<canvas id="canvasbg" width="960" height="200" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
<canvas id="canvas" width="960" height="200" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
</body>
</html>

You can use requestAnimationFrame to create animation loops to allow your bars to grow 您可以使用requestAnimationFrame创建动画循环以允许您的条形增长

To create uniform growth for bars that are uneven height you can apply a percentage 要为高度不均匀的条形创建均匀增长,您可以应用百分比

// this will grow all bars at an even rate

bar1Height = bar1.maxHeight * percentComplete/100;

bar2Height = bar2.maxHeight * percentComplete/100;  

percentComplete++;

Here's example code and a Demo: http://jsfiddle.net/m1erickson/YR4D7/ 这是示例代码和演示: http//jsfiddle.net/m1erickson/YR4D7/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
    $(function(){

        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");

        var skillBars=[];
        skillBars.push({max:200,color:"red"});
        skillBars.push({max:75,color:"green"});
        skillBars.push({max:275,color:"blue"});

        var chartBottomY=325;
        var chartBarWidth=30;
        var chartBarPadding=20;
        var percent=0;

        animate();

        function animate() {
            // if not 100% done, request another frame
            if(percent++<100){
                requestAnimationFrame(animate);
            }

            // Drawing code goes here
            ctx.clearRect(0,0,canvas.width,canvas.height);
            var x=chartBarPadding;
            for(var i=0;i<skillBars.length;i++){
                var height=skillBars[i].max*percent/100;
                ctx.fillStyle=skillBars[i].color;
                ctx.fillRect(x,chartBottomY,chartBarWidth,-height);
                x+=chartBarWidth+chartBarPadding;
            }
        }

    }); // end $(function(){});
</script>
</head>
<body>
    <canvas id="canvas" width=350 height=350></canvas>
</body>
</html>

I see a couple issues. 我看到了几个问题。

First, you draw everything at one time, whereas you should draw after each image is loaded, but yiu will want to use setTimeout or something similar to allow the canvas element to be drawn. 首先,您一次绘制所有内容,而您应该在每个图像加载后绘制,但是yiu将希望使用setTimeout或类似的东西来允许绘制canvas元素。

You should also have a method for the bar, and have it remember the current step value and it will just draw the next block. 你还应该有一个bar的方法,让它记住当前的步长值,它只会绘制下一个块。

I would put onload on the image tag, image.onload function with return , and when it loaded draw the next bar and load the next one. 我会把onload放在image标签上, 带有return的image.onload函数 ,当它加载时绘制下一个bar并加载下一个吧。

But remember to use setTimeout to allow the drawing to take place. 但请记住使用setTimeout来进行绘图。

Here are some links that may help 以下是一些可能有用的链接

JavaScript animation with multiple setTimeout 具有多个setTimeout的JavaScript动画

https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/AnimatingtheCanvas/AnimatingtheCanvas.html https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/AnimatingtheCanvas/AnimatingtheCanvas.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM