Reputation: 2661
I want to create a function that rotates a square on its axis.
var halfWidth = canvas.width/2;
var halfHeight = canvas.height/2;
var x = halfWidth-10;
var y = halfHeight-10;
var w = 20;
var h = 20;
var deg = 45;
rotate(x, y, w, h, deg);
ctx.fillRect(x, y, w, h);
The function:
function rotate(x, y, w, h, deg) {
// ctx.translate() and ctx.rotate()
// goes here.
}
How to do this?
Upvotes: 4
Views: 13806
Reputation: 1
Here's an another solution if you want to draw multiple square
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function rd(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
for (let i = 0; i < 10; i++) {
drawRect(rd(0, 400), rd(0, 400))
}
function drawRotatedRect(x, y, width, height, degrees) {
// first save the untranslated/unrotated context
ctx.save();
ctx.beginPath();
// move the rotation point to the center of the rect
ctx.translate(x + width / degrees, y + height / degrees);
// rotate the rect
ctx.rotate(degrees * Math.PI / 180);
// draw the rect on the transformed context
ctx.rect(-width / 2, -height / 2, width, height);
ctx.fillStyle = "gold";
ctx.fill();
// restore the context to its untranslated/unrotated state
ctx.restore();
}
function drawRect(x, y) {
const squareSize = 50;
const degrees = 60;
// draw an unrotated reference rect
ctx.beginPath();
ctx.rect(x - squareSize/2, y - squareSize/2 , squareSize, squareSize);
ctx.fillStyle = "blue";
ctx.fill();
// draw a rotated rect
drawRotatedRect(x, y, squareSize, squareSize, degrees);
// draw center coord reference point
drawDot(x, y, 5)
}
function drawDot(x, y, size) {
ctx.beginPath();
ctx.arc(x , y, size, 0, 2 * Math.PI);
ctx.fillStyle = 'black'
ctx.fill();
}
canvas {
border:1px solid red;
}
<canvas id="canvas" width=400 height=400></canvas>
Upvotes: 0
Reputation: 610
If you don't want to deal with ctx.save()
and all that, there's a brief way to calculate where each new point of the rotated square should be.
The following will draw a green square, and then draw a red square that has been rotated 22.5°.
const ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(50, 50, 50, 50)
/**
*
* @returns {[number, number]} (x3, y3)
*/
function f(x1, y1, x2, y2, degrees) {
const rad = degrees * Math.PI / 180;
return [
(x2 - x1) * Math.cos(rad) + x1 - (y2 - y1) * Math.sin(rad),
(x2 - x1) * Math.sin(rad) + y1 + (y2 - y1) * Math.cos(rad)
]
}
ctx.fillStyle = "red";
const centre = 75;
/*
* The centre of the square is at (75, 75)
* The corner points are at:
* (50, 50)
* (100, 50)
* (100, 100)
* (50, 100)
*/
ctx.beginPath();
let [newX, newY] = f(centre, centre, 50, 50, 22.5);
ctx.moveTo(newX, newY);
[newX, newY] = f(centre, centre, 100, 50, 22.5);
ctx.lineTo(newX, newY);
[newX, newY] = f(centre, centre, 100, 100, 22.5);
ctx.lineTo(newX, newY);
[newX, newY] = f(centre, centre, 50, 100, 22.5);
ctx.lineTo(newX, newY);
[newX, newY] = f(centre, centre, 50, 50, 22.5);
ctx.lineTo(newX, newY);
ctx.fill();
<canvas width=200 height=200 style="background:gray"></canvas>
I put this graphic together thinking it might help visualize what's going on.
Upvotes: 1
Reputation: 457
here is my opinion:
JAVASCRIPT
var canvas = document.getElementById("myCanvas");
var ctx2 = canvas.getContext("2d");
ctx2.fillStyle='#333';
ctx2.fillRect(50,50,100,100);
var ctx = canvas.getContext("2d");
ctx.fillStyle='red';
var deg = Math.PI/180;
ctx.save();
ctx.translate(100, 100);
ctx.rotate(45 * deg);
ctx.fillRect(-50,-50,100,100);
ctx.restore();
ctx2 is the old position and ctx is the new position of the shape. You have to translate the shape with the same x,y coordinates according to where you want position your shape. Then you have to enter values to ctx.fillRect(x,y,w,h);
keep x and y as the -ve values (half of height and width to keep it on the diagonal to the canvas otherwise change to manipulate it). and h, w as your desired values.
Upvotes: 0
Reputation: 2661
Thanks dr.dredel for the link.
var cx = canvas.width/2;
var cy = canvas.height/2;
var x = -10;
var y = -10;
var w = 20;
var h = 20;
var deg = 45;
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(deg * Math.PI/180);
ctx.fillRect(x, y, w, h);
ctx.restore();
Explanation:
ctx.save()
saves the current state of the coordinate system.
ctx.translate(cx, cy)
changes the origin to the center of canvas
ctx.rotate(deg * Math.PI/180)
rotates the square to 45 degrees (Note that the parameter is in radians, not degrees)
ctx.fillRect( x, y, w, h )
draws the square
ctx.restore()
restores the last state of the coordinate system.
Another JS Fiddle link, with a HTML5 slider.
Upvotes: 6
Reputation: 43263
If I remember correctly the translation involved was something like first translate to the center point of the rectangle, then rotate wanted amount, then draw. Or possibly first rotate, then translate, I'm a bit rusty =)
Upvotes: 0