简体   繁体   中英

Animating Multiple Custom Shapes in html5 Canvas

Very first post so I apologize if I format my question wrong.

I have had some experience animating multiple circles with canvas prior to this project but currently am trying to animate a custom made letter Z.

Currently in the process of trying to make 100 Z's do the same thing, for some reason my constructor object is only drawing one.

So far I have:

  • console logged in my draw function to see if its getting that far and it is
  • console logged the array of Z objects, and all 100 are there.
  • in that array of objects I've checked all their x-coordinates and they are different, so I don't think all 100 are just sitting on top of each other.

My suspicions are that update function is some how wrong with my use of "this"

I guess ill just dump my whole javascript file incase its something else. Sorry i dont know typical protocol.


var canvas = document.getElementById('myCanvas');

var context = canvas.getContext('2d');

canvas.height = window.innerHeight;

canvas.width = window.innerWidth;

canvasHeight = canvas.height;

canvasWidth = canvas.width

var dx = 0 
var dy = 0;
var direction = true

function Z(xCoord, yCoord, dx, dy, direction) {
    this.x = xCoord  
    this.y = yCoord    
    this.dy = dy    
    this.dx = dx    
    this.direction = direction


    this.update = function(){
        //making the Z wiggle
        if (this.dx < 20 && this.direction) {
            this.dx++
        }
        else if (this.dx === 20 && this.direction) {
            this.direction = false;
        }

        if (this.dx > -20 && !this.direction) {
            this.dx--
        }
        else if (this.dx === -20 && !this.direction)  {
            this.direction = true;
        }

        //if Z gets to top of page it resets down at the bottom
        if (this.dy === -canvasHeight - this.y) {
            this.dy = 0
        }

        this.dy--;
        this.draw()
    }

    this.draw = function() {
        context.clearRect(0, 0, context.canvas.width, context.canvas.height);
        context.translate(this.dx, this.dy); /// translate (move)

        //The Letter Z
        context.beginPath();

        context.moveTo(this.x, this.y + canvasHeight); // x+0
        context.lineTo(this.x+10, this.y + canvasHeight); // x+10
        context.lineTo(this.x+2, this.y + canvasHeight-9); // x+2
        context.lineTo(this.x+5, this.y + canvasHeight-9); // x+5
        context.lineTo(this.x+10, this.y + canvasHeight-9); // x+10
        context.lineTo(this.x+10, this.y + canvasHeight-10); // x+10
        context.lineTo(this.x, this.y + canvasHeight-10); // x+0
        context.lineTo(this.x+8, this.y + canvasHeight-1); // x+8
        context.lineTo(this.x, this.y + canvasHeight-1); // x+0
        context.lineTo(this.x, this.y + canvasHeight);  // x+0

        // complete custom shape
        context.closePath();
        context.lineWidth = 4;
        context.fillStyle = 'white';
        context.fill();
        context.strokeStyle = 'black';
        context.stroke();

        context.translate(-this.dx, -this.dy); /// translate (move)


    }

}

var ZArr = []
//for loop to make all the Z's
for (var index = 0; index < 100; index++) {

    var randomX = Math.random() * canvasWidth;
    var randomY = Math.floor(Math.random() * 500) + 1  

    var newZ = new Z(randomX, randomY, dx, dy, direction);

    ZArr.push(newZ)
}

// console.log(ZArr)

function executeFrame() {

    for (let index = 0; index < ZArr.length; index++) {
        ZArr[index].update();  
    }

    requestAnimationFrame(executeFrame);
}

//start animation
executeFrame();

Move context.clearRect(0, 0, context.canvas.width, context.canvas.height); to your render loop. Your erasing each drawing every loop of your array.

function executeFrame() {
    context.clearRect(0, 0, context.canvas.width, context.canvas.height);
    for (let index = 0; index < ZArr.length; index++) {
        ZArr[index].update();  
    }

    requestAnimationFrame(executeFrame);
}

This is because your clear canvas line is inside of your Z object's draw function, so the field will be cleared everytime you try to draw a new Z. This means only the last one in the array will be visible. Just move this line.

context.clearRect(0, 0, context.canvas.width, context.canvas.height);

To your executeFrame function just above the for loop.

Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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