How do i just rotate a image in Javascript? - javascript

I am working on a program in Javascript while I tried to rotate my image I have drawn. I tried to search on google to find my answer but all I got was how to rotate the whole canvas. What I am searching for is a way to rotate just an image (think like this. I want to rotate a warrior dependent on the direction he is walking in). I tried many different codes but all went to the same, rotate the whole canvas.
Here is an example of what I used:
ctx.rotate(20*Math.PI/180);
and also:
var angle = 0; //init angle
images[0].onload = function () {
ctx.drawImage(images[0], 0, 0);
setInterval(function () {
ctx.save();
ctx.clearRect(-ctx.canvas.width / 2, -ctx.canvas.height / 2, ctx.canvas.width, ctx.canvas.height);
ctx.rotate(Math.PI / 180 * (angle += 10)); //rotating at 10 degrees interval..
ctx.drawImage(images[0], 0, 0);
ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.restore();
}, 16);
}
please help me out

The rotating of the canvas is part of how to create the rotation relative to the image.
To keep the image's visible position the same and not move it, you have to center it first.
Without centering the image you will only acheive the visual effect of rotating the entire canvas.
You have to throw in a bit of math to get it to rotate around the center of the image.
ctx.save();
ctx.translate(x, y); /*X and Y of the image, center point of the image */
ctx.rotate((Math.PI / 180) * rotation); /*rotation is in degrees, so this converts it to rads */
ctx.drawImage(img, -(img.width/2), -(img.height/2)); /* Draw and center the image */
ctx.restore();

Related

draw quadrilateral from center javascript

I am trying to draw a quadrilateral on my canvas with the p5.js library.
I am do this by creating a custom vertex shape. See the code below.
var tr;
function setup(){
createCanvas(window.innerWidth, window.innerHeight);
tr = new surface_triangle(width/2, height/2, 100, 90, "a", 12334);
}
function draw(){
background(0);
tr.draw_triangle();
}
class surface_triangle{
constructor(x, y, size, rotation, properties, id){
this.size = size;
this.h = size * (Math.sqrt(3)/2);
this.x = x;
this.y = y;
}
draw_triangle(){
beginShape();
fill(255,0,0);
vertex(this.x, this.y - this.h/2);
vertex(this.x - this.size/2, this.y + this.h/2);
vertex(this.x + this.size/2, this.y + this.h/2);
endShape(CLOSE)
fill(255);
ellipse(this.x, this.y, 10, 10);
}
}
As you see i managed to draw the triangle but the center point is not correct. And i have no idea why my center point is off? See image below:
#kevingworkman was totally right in his answer but i am trying to draw the triangle from the center point. So i will have a centerx and a centery and now i need to calculate the 3 points of the triangle relative to this center point. Like this image ->.
How would i go about doing this? Since my previous code clearly draws from a different point.
All tips and suggestions are greatly appreciated!
It's an optical illusion. The square is in the "center" of the top and bottom of the triangle. Zoom into your image and count the pixels above and below the edges of the circle. You'll find that there are 75 pixels above the circle, and 75 pixels below (give or take a couple because of anti-aliasing).
You can also see this by drawing a square with the same top and bottom as the triangle.
This looks weird to our human eyes because we want the center to be in between all three of the points, not just the top and bottom.
You can fix this by taking the average of all three points to find the center of the triangle.
Edit: If you want the provided center to be the real center of all three points, then you have to change how you calculate the three points. You can use basic trig (the cos() and sin() functions) for that.

Javascript Canvas rotate image in circle axis

I need help, I have been trying to rotate my image which is a pointer. with my code below it rotates but it rotates not as I want.
Code:
var c = document.getElementById("ctx");
var ctx = c.getContext("2d");
for (var d = 0; d < 360; d++) {
setTimeout(function (d) {
c.globalAlpha = 0.5;
ctx.clearRect(0, 0, c.width, c.height);
ctx.save();
ctx.translate(c.width / 2, c.height / 2);
ctx.rotate(d * Math.PI / 180);
ctx.drawImage(imageLoader.pointer, -imageLoader.pointer.width / 2, -imageLoader.pointer.height / 2);
ctx.restore();
}, 100 * d, d);
}
This code makes my image rotate weirdly I think it rotates on its own axis but I am not sure.
However I need a rotation something like this image.
I think this rotation is around a circle, i need something like this , can someone give me a hint or help me out?
I was trying to do it with a shape but its more difficult because i need to find the tangent and more geometric formulas to make it rotate like this.
I appreciate your time in advance, thanks.
The function to draw a rotated image rotating around a point on the canvas and offset to its own center of rotation.
// x,y is the location on the canvas that the image will rotate around
// cx,cy is the coordinates on the image that is rotated around
// angle is the amount of rotation in radians
function drawImage(image,x,y,cx,cy,angle){
ctx.setTransform(1,0,0,1,x,y); // set the rotation origin
ctx.rotate(angle); // rotate
ctx.drawImage(image,-cx,-cy); // draw image offset to put cx,cy at the point of rotation
ctx.setTransform(1,0,0,1,0,0); // restore the transform
}
So if your image is 50 by 100 pixels and you want the image to rotate about the point on it at 25, 80 (center near bottom) and that rotation point to be on the canvas at 200,200 then
drawImage(image,200,200,25,80,3); //rotate 3 radians
To do so in an animation.
// assumes image has loaded and ctx is the context of the canvas.
requestAnimationFrame(mainLoop); // starts the animation
function mainLoop(time){ // time is passed by requestAnimationFrame
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); // clear
drawImage(image,200,200,25,80,(time / 5000) * Math.PI * 2); // rotate one every 5 seconds
requestAnimationFrame(mainLoop);
}
const image = new Image
image.src = "https://i.stack.imgur.com/C7qq2.png?s=328&g=1";
const ctx = myCanvas.getContext("2d");
function drawImage(image,x,y,cx,cy,angle){
ctx.setTransform(1,0,0,1,x,y); // set the rotation origin
ctx.rotate(angle); // rotate
ctx.drawImage(image,-cx,-cy); // draw image offset to put cx,cy at the point of rotation
ctx.setTransform(1,0,0,1,0,0); // restore the transform
}
// assumes image has loaded and ctx is the context of the canvas.
requestAnimationFrame(mainLoop); // starts the animation
function mainLoop(time){ // time is passed by requestAnimationFrame
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); // clear
if(image.complete){
drawImage(image,250,250,image.width / 2,image.height * 0.8,(time / 5000) * Math.PI * 2); // rotate one every 5 seconds
}
requestAnimationFrame(mainLoop);
}
canvas {
border : 2px black solid;
}
<canvas id="myCanvas" width = 500 height = 500></canvas>

FabricJS ClipTo shape with angle attribute on Image

I'm stuck with a problem, where I have to crop a shape out of an image. Everything works until I'm not giving an angle to the shape.
I'd like to know how am i supposed to modify my test case to fix this issue.
JSFiddle example
bg.clipTo = function(ctx) {
ctx.save();
ctx.rotate((angle * -1) * (Math.PI / 180));
ctx.rect(left, top, width, height);
ctx.restore();
ctx.stroke();
};

image and canvas rotation

I'm trying to rotate an image and move it around the canvas using the arrow keys. The plan is to have the left and right keys control the rotation of the image, and the up-down key control the movement - a bit like a tank!
I can successfully rotate an image around a centre point and place it back where it should be in the canvas, but once I rotate it by, say 45 deg, I would like the up key to move it right, rotate 180 and the up-key moves it down the canvas etc. At the moment, I can rotate the image using left/right keys, but up/down keys are always up/down the canvas.
Do I somehow need to rotate the canvas coordinates by the same amount as the image?
This is what I have so far and is in my draw function…
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.translate(T1.x + base_image.width/2, T1.y + base_image.height/2);
ctx.rotate(rotation * Math.PI/180);
ctx.translate(-(T1.x + base_image.width/2), -(T1.y + base_image.height/2));
ctx.drawImage(base_image, T1.x, T1.y);
ctx.stroke();
ctx.restore()
T1.x and T1.y are the x and y coordinates of the image.
Thanks!
Finally got it! The solution was to separate the rotation and the movement rather than trying to do it all using ctx.translate.
In my draw function called every 100 Hz:
ctx.save();
ctx.translate(T1.x + base_image.width/2, T1.y + base_image.height/2);
ctx.rotate(rotation*Math.PI/180);
ctx.drawImage(base_image, -base_image.width/2, -base_image.height/2);
ctx.restore();
ctx.stroke();
The left key is, for example, like:
rotation = rotation - 5;
Draw();
The up key is, for example, like:
var radians = (rotation*Math.PI/180)
T1.x += 4*Math.cos(radians);
T1.y += 4*Math.sin(radians);
Draw();
Note: For this to work, I had to change the default orientation of the image in paint by 45 deg.
The quickest way to draw a rotated, uniformly-scaled image on Edge, Chrome, and Firefox is
// When the image has loaded add the center offsets
image.onload = function(){
// … your code
this.centerX = -this.width/2;
this.centerY = -this.height/2;
}
// When rendering
// x,y position of image center
// scale the uniform scale
// rotate angle in radians starting at 0 and + clockwise
var xdx = Math.cos(rotate) * scale;
var xdy = Math.sin(rotate) * scale;
ctx.setTransform(xdx, xdy, -xdy, xdx, x, y);
ctx.drawImage(image,image.centerX,image.centerY)
The above method with the extra sin and cos and the two multiplications is significantly quicker on Chrome, slightly quicker on Firefox, and I forget the margin on Edge, but it was quicker than the next quickest method:
ctx.setTransform(scale, 0, 0, scale, x, y);
ctx.rotate(rotate);
ctx.drawImage(image, image.centerX, image.centerY);
Though I am leaving the canvas transform state as it is, you can continue using both methods without having to reset the canvas state. When you are done with all the rendering, to restore the current transform, use
ctx.setTransform(1, 0, 0, 1, 0, 0);
To save a tiny bit of time, each time you convert from degrees to radians, create a const DEG2RAD = Math.PI/180;. Then, you can convert with var radians = degrees*DEG2RAD; or save by typing const D2R = Math.PI/180; or call const oneDeg = Math.PI/180;.

animating a rotated image in canvas

hey guys i have a function that strokes a line based on the angle received from the user and also moves an image using some basic maths. the only problem is i am unable to rotate image based on that angle as if i put this inside animation frame loop it doesn't work .please help
function move()
{
var theCanvas=document.getElementById("canvas1");
var context=theCanvas.getContext("2d");
context.clearRect(0, 0, theCanvas.width, theCanvas.height );
// context.fillStyle = "#EEEEEE";
//context.fillRect(0, 0,theCanvas.width, theCanvas.height );
context.beginPath();
context.setLineDash([3,2]);
context.lineWidth=10;
context.strokeStyle="black";
context.moveTo(x1,y1);
context.lineTo(x2,y2);
context.stroke();
context.drawImage(srcImg,x1+x_fact,y1-100+y_fact);
x_fact=x_fact+0.5;
y_fact=m*x_fact+c;
requestAnimationFrame(move);
}
move();
now please suggest me a way to rotate the image on the angle input only once so it can face according to the path and move in it.
thank you in advance.
If you want to rotate the image by its corner use something like this:
... your other code here ...
var x = x1+x_fact, // for simplicity
y = y1-100+y_fact;
context.save(); // save state
context.translate(x, y); // translate to origin of rotation
context.rotate(angle); // rotate, provide angle in radians
context.drawImage(srcImg, 0, 0); // as we are translated we draw at [0,0]
context.restore(); // restore state removing transforms
If you want to rotate it by center simply translate, rotate and then translate back 50% of the image's width and height.
save/restore are relative expensive operations - you can simply reset transformation all together after each draw if you don't need transformations elsewhere:
context.setTransform(1, 0, 0, 1, 0, 0); // instead of restore(), remove save()

Categories

Resources