I am learning javascript on the site mdn Drawing graphics and its first example draws a lot of triangles on canvas when open the web
here's the original code the site provided:
const canvas = document.querySelector('.myCanvas');
const width = canvas.width = window.innerWidth;
const height = canvas.height = window.innerHeight;
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(0,0,0)';
ctx.fillRect(0,0,width,height);
ctx.translate(width/2, height/2);
function degToRad(degrees) {
return degrees * Math.PI / 180;
};
function rand(min, max) {
return Math.floor(Math.random() * (max-min+1)) + (min);
}
let length = 250;
let moveOffset = 20;
for (let i = 0; i < length; i++) {
ctx.fillStyle = `rgba(${255-length},0,${255-length},0.9)`;
ctx.beginPath();
ctx.moveTo(moveOffset,moveOffset);
ctx.lineTo(moveOffset+length,moveOffset);
const triHeight = length/2 * Math.tan(degToRad(60));
ctx.lineTo(moveOffset+(length/2),moveOffset+triHeight);
ctx.lineTo(moveOffset,moveOffset);
ctx.fill();
length--;
moveOffset+=0.7;
ctx.rotate(degToRad(5));
}
and I want to modify the code to make it draw one triangle every second. and Here's my code:
const canvas = document.querySelector(".myCanvas");
const width = (canvas.width = window.innerWidth);
const height = (canvas.height = window.innerHeight);
const ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.fillRect(0, 0, width, height);
function degToRad(degrees) {
return (degrees * Math.PI) / 180;
}
let length = 250;
let moveOffset = 20;
let i=0;
let ani=0;
function animation(){
if(!ani){
ani=setInterval(draw,1000);
}
}
function draw(){
ctx.fillStyle = `rgba(${255 - length},0,${255 - length},0.9)`;
ctx.beginPath();
ctx.moveTo(moveOffset, moveOffset);
ctx.lineTo(moveOffset + length, moveOffset);
const triHeight = (length / 2) * Math.tan(degToRad(60));
ctx.lineTo(moveOffset + length / 2, moveOffset + triHeight);
ctx.lineTo(moveOffset, moveOffset);
ctx.fill();
length--;
moveOffset += 0.7;
ctx.rotate(degToRad(5));
console.log(i);
i++;
}
animation();
the code can console "i(second)" every second, but there's nothing(except the black canvas) on the canvas.
But when I try the window.requestAnimationFrame(draw)
method, the triangle don't appear one every second.
How can I fix this code to make it work as I wanted?
It's not necessary to use setInterval, I am free to use any method that works!
The requestAnimationFrame
function is some sort of setTimeout that syncs with the browser frame rate. Here's a simple animation loop with all you need to know to make this work (see code comments).
This code will move the square every 1 second (approximatively).
const ctx = document.getElementById("canvas").getContext("2d");
const canvasW = 500;
const canvasH = 500;
ctx.canvas.width = canvasW;
ctx.canvas.height = canvasH;
let timer = undefined;
const rectW = 50;
const rectH = 50;
const rectColor = "red";
let x = 0;
let y = 0;
function drawSquare(x, y) {
ctx.fillStyle = rectColor;
ctx.fillRect(x, y, rectW, rectH);
}
function draw() {
// Initial state
if (timer === undefined) {
timer = Date.now();
drawSquare(x, y);
}
// State of the animation for subsequent frames
if ((Date.now() - timer) >= 1000) {
// We use >= 1000 (1sec) because the precision can be an issue
timer = Date.now();
x += 10;
y += 10;
// important: clear your canvas before drawing next frame
ctx.clearRect(0, 0, 500, 500);
// Drawing
drawSquare(x, y);
}
// Draw next frame if condition is truthy
if (x < canvasW - rectW) {
// Loop using recursion
requestAnimationFrame(draw);
}
}
// Start animation loop and draw first frame
requestAnimationFrame(draw);
<canvas id="canvas" style="border: solid 1px black;"></canvas>