HTML5 canvas draw multiple rectangles that move in

2019-07-09 06:59发布

In this code i have a rectangle moving from the middle-left to the right at 30ticks, however, my brain hurts when i try to think how im going to add another square about the same size as the one antimated, but starting from a different direction. The issue is how i can add multiple objects, whether rectangle-circle and have it animate like the square in another starting x y location, here's what i have so far:

        var rectY=200, rectW=40;
        var rectX = -rectW;
        var canvas = null;
        var context = null;

        function init() {
            canvas = document.getElementById('testCanvas');
            context = canvas.getContext("2d");

            blank();

            context.fillStyle= "yellow";
            context.fillRect(rectX,rectY,rectW,rectW);
            setInterval(anim, 30);
        }

        function blank() {
            context.fillStyle = "#00ddee";
            context.fillRect(0,0,context.canvas.width, context.canvas.height);
        }

        function anim() {
            if (rectX < context.canvas.width) {
                blank();
                rectX += 5;
                context.fillStyle = "yellow";
                context.strokeStyle = "red";
                context.lineWidth = 3;
                context.fillRect(rectX,rectY,rectW,rectW);
                context.strokeRect(rectX,rectY,rectW,rectW);
            }
            else rectX=-rectW;
        }

2条回答
一夜七次
2楼-- · 2019-07-09 07:28

Use JavaScript objects to represent multiple rectangles

Here's an outline of how to do it:

  • Use a javascript object to describe each of your rectangles
  • Put each rect object in a rects[] array
  • Inside an animation loop:
    • Change each rect's x value
    • Redraw the canvas with the rects in their new positions
    • Request another loop in the animation

Annotated code and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

// define a rect using a javascript object
var rect1={
  x:20,
  y:20,
  width:40,
  height:40,
  directionX:1
}

// define another rect using a javascript object
var rect2={
  x:250,
  y:90,
  width:40,
  height:40,
  directionX:-1
}

// put each rect in a rects[] array
var rects=[rect1,rect2];

// start the animation loop
requestAnimationFrame(animate);

function animate(time){

  // move each rect in the rects[] array by its 
  // own directionx
  for(var i=0;i<rects.length;i++){
    rects[i].x+=rects[i].directionX;
  }

  // draw all the rects in their new positions
  draw();

  // request another frame in the animation loop
  requestAnimationFrame(animate);
}

function draw(){
  ctx.clearRect(0,0,cw,ch);
  for(var i=0;i<rects.length;i++){
    var r=rects[i]
    ctx.strokeRect(r.x,r.y,r.width,r.height);
  }
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

An improvement I leave for you to do is to stop the animation when all rectangles have left the visible canvas.

查看更多
可以哭但决不认输i
3楼-- · 2019-07-09 07:31

This is the point of OOP (Object Orientated Programming), where each item in your program is represented as an object. In your case we can have a Square object that has a: x, y, width, and color. Along with a function to draw itself anim():

function Square(x, y, w, color) 
{
    this.x = x;
    this.y = y;
    this.w = w;
    this.color = color;

    this.anim = function() 
    {
        if (this.x < context.canvas.width) {
            this.x += 5;
            context.fillStyle = this.color;
            context.strokeStyle = "red";
            context.lineWidth = 3;
            context.fillRect(this.x,this.y,this.w,this.w);
            context.strokeRect(this.x,this.y,this.w,this.w);
        }
        else this.x=-this.w;
    }
}

Then you can easily create objects, to animate each one place them inside an array and call anim() for each square in objects:

var rect1 = new Square(-40, 200, 40, "yellow");
var rect2 = new Square(0, 100, 40, "blue");
var objects = [ rect1, rect2 ];

setInterval(function(){
    blank();
    for(rect in objects){
        objects[rect].anim();
    }
}, 30);

Fiddle Example

查看更多
登录 后发表回答