Multiple Canvas Objects (CE5)

I have taken a copy of Canvas Experiment 2 which grows and shrinks a circle and called it Canvas Experiment 5.

Here is the full .js script of the growing and shrinking circle with annotation:

//set a variable and use the querySelector method to target the canvas tag in the HTML
var canvas = document.querySelector('canvas'); 
canvas.width = window.innerWidth; // Using our shortened variable to target the tag, set the width to view port
canvas.height = 200; // Set the height of the canvas

// getContext is a 'method that returns a drawing context on the canvas' (Mozilla Developer Network, 2017).
var c = canvas.getContext('2d');

// Set variables for the circle
var x = 0;
var radius = Math.random();
var growing = true;

// This is the animate function, it is looped because it calls itself from within itself (recursion).
 function animate() {
 requestAnimationFrame(animate); // loops by calling the animate function over and over
 var size = radius*x; // Size used as a max. Radius is random between 0 and 1, x changes by 1 each frame
 c.clearRect(0, 0, innerWidth, 200); // Clear canvas between frames
 c.beginPath(); // Set a start point
 c.arc(innerWidth/2, 100, size, 0, Math.PI*2, false); // Describe an arc
 c.strokeStyle="#FF1111"; // Set a colour
 c.stroke(); // Draw the arc
 
 // Conditionals to decide if the circle is growing or shrinking and which way the next frame should change.
 if (size > 50) {
 growing = false;
 }
 if (size < 1) {
 growing = true;
 }
 if (growing == false) {
 x = x - 2;
 } else {
 x = x + 2;
 }
 }
 
// Initial call of animate function to start the loop.
animate();

I am going to make multiple growing and shrinking circles by making the circle into an object, then generating some starting parameters for 50 circles and setting them all off.

// Exactly the same setup as the single one
var canvas = document.querySelector('canvas'); 
canvas.width = window.innerWidth;
canvas.height = 200;

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

// Here's the circle object (denoted by a capital C on Circle)
// All variables prefaced by 'this.' means that each instance of the circle holds its own version of that variable, allowing them to act independently of each other.
function Circle(x, y) {
 this.x = x;
 this.y = y;
 this.growing = true;
 this.radius = 1;
 this.growSpeed = Math.random();
 this.maxSize = (Math.random()+0.3)*60;

// Same draw function, but now inside the Circle object and first drawn using parameters generated at the start.
 this.draw = function() {
 c.beginPath();
 c.arc(this.x, this.y, this.radius, Math.PI*2, false)
 c.strokeStyle = "#FF3333";
 c.stroke();
 }
 
// Update function for updating the position of this instance of the Circle.
// maxSize specifies the size the Circle can reach before shrinking.
// growSpeed is a random decimal between 0 and 1 generated once per grow/shrink cycle.
 this.update = function() {
 if (this.radius > this.maxSize) {
 this.growing = false;
 }
 if (this.radius < 1) {
 this.growing = true;
 this.x = Math.random() * innerWidth;
 this.y = Math.random() * canvas.height;
 this.growSpeed = Math.random();
 this.maxSize = (Math.random()+0.3)*60;
 }
 if (this.growing == false) {
 this.radius = this.radius - this.growSpeed;
 } else {
 this.radius = this.radius + this.growSpeed;
 }
 
 this.draw();
 
 }
}

// This for loop generates the initial starting parameters and keeps them in the growingArray.
var growingArray = [];

for (var i = 0; i < 75; i++) {
 var x = Math.random() * innerWidth;
 var y = Math.random() * canvas.height;
 
 growingArray.push(new Circle(x, y));
}

// The animate function calls itself again to clear the frames between drawings. This now also triggers an update of each Circle generated.
function animate() {
 requestAnimationFrame(animate);
 c.clearRect(0, 0, innerWidth, 200);
 
 for (var i = 0; i < growingArray.length; i++) {
 growingArray[i].update();
 }
 }

// Initial animate call.
animate();

This works! Here are the steps I worked through:

  1. Set up canvas
  2. Create a Circle object that can take arguments – have it draw and update itself
  3. Create an array of starting parameters (only x and y coordinates in this case)
  4. Clear the frame, ask each Circle to update, repeat!

 


References

Please find all references here.

Leave a Reply