Nov 20, 2022

# Solution 1 :

## Anti aliasing edge.

The reason you are getting the ~1px line is because the `ctx.fillRect` you use to clear the canvas is transformed by the same transform used to draw the box.

When a shape is rendered its edges are anti-aliased, some of the edge pixels are drawn semi-transparent meaning that drawing over that same box will leave some of the original pixels behind.

## To fix

• Reset the transform to the default before you clear the canvas. `ctx.setTransform(1,0,0,1,0,0);`

• Use a variable to hold the total rotation of the box (see example)

• Use `setTransform` to replace the current transform rather than build the transform in stages using `ctx.translate` and `ctx.rotate`.

Transform basics while help understand how `setTransform` can be used to position, scale, and rotate rendered objects in the 2D canvas API.

## Other points

• Use `requestAnimationFrame` rather than `setInterval` to call the animation loop to ensure the smoothest possible animation.
• Use a single object to store related data. Eg the object `box` in example holds all relevant data needed to animate the box.
• Try to express animations in meaningfully ways. In the example the box rotation rate `box.rotSpeed` is set as rotations per second

## Example

``````requestAnimationFrame(mainLoop);
const ctx = canvas.getContext("2d")
canvas.height = canvas.width = 300;
canvas.style.backgroundColor = "#303030"

const box = {
color: "lime",
cx: 0.25,  // x rotation center as fraction of box size
cy: 0.25,  // y rotation center as fraction of box size
x: 150,
y: 150,
size: (150 * 150 / 2) ** 0.5, // makes diagonal size of box 150
rot: 0,
rotSpeed: 0.5,  // in rotations per second
};
function drawBox(box) {
box.rot += box.rotSpeed * Math.PI / 30; // 2*PI/60 is one rotation per second at 60FPS
ctx.fillStyle = box.color;
const xa = Math.cos(box.rot);
const ya = Math.sin(box.rot);
ctx.setTransform(xa, ya, -ya, xa, box.x, box.y);
ctx.fillRect(-box.cx * box.size, -box.cy * box.size, box.size, box.size);
}
function mainLoop() {
ctx.setTransform(1, 0, 0, 1, 0, 0); // set default transform
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBox(box);
requestAnimationFrame(mainLoop);
}``````
``<canvas id="canvas">``

# Solution 2 :

• Use a `let deg = 0` variable
• Use `clearRect` before repainting the canvas
• `.save()` the context before rotating it
• Rotate and translate the context before painting the square
• `.restore()` the context
``````let deg = 0; // Prepare degrees
const degree = input => 2 * Math.PI / 360 * input;
const ctx = document.getElementById("canvas").getContext("2d");

ctx.canvas.width = 300;
ctx.canvas.height = 300;

const rotateSquare = () => {
deg += degree(10); // Increment degrees
deg %= 360;        // Loop degrees
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

// BACKGROUND:
ctx.fillStyle = "#303030"
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)

// SQUARE:
ctx.save();
ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.rotate(deg);
ctx.fillStyle = "lime";
ctx.fillRect(0, 0, 100, 100);
ctx.restore();
}

let turnSquare = setInterval(rotateSquare, 1000 / 20)``````
``<canvas id="canvas"></canvas>``

# Problem :

I’m currently learning about the html5 canvas, and I was making a program that rotates a square around the center of the page using the .rotate() function, but it was leaving behind 1px lines from where the square used to be even though I was filling the canvas after every turn and nothing in the code was 1px. so can someone please explain why this is happening and how to stop it from happening

thanks!

``````const canvas = document.getElementById("canvas")
const ctx = canvas.getContext("2d")

canvas.width = 300;
canvas.height = 300;

//debugger;
/*
*/

ctx.fillStyle = "#303030";
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.translate(150, 150)

let turnSquare = setInterval(() =>{
ctx.fillStyle = "#303030"
ctx.fillRect(0, 0, canvas.width, canvas.height)

ctx.rotate(degree(10))

ctx.beginPath()
ctx.fillStyle = "lime"
ctx.fillRect(0, 0, 100, 100)

}, 1000 / 20)

function degree(input){
return 2 * Math.PI / 360 * input
}``````
``<canvas id="canvas">``

### Comment posted by 91WalcNosmirc

sorry, i didnt know you could do that

You can use

### Comment posted by 91WalcNosmirc

thanks, i’ll use that next time