M.Malinowski M.Malinowski - 1 month ago 15
Javascript Question

How to rotate selected element in canvas

so I am trying to build a small image editor in canvas, currently I have buttons that onclick will draw a specific image to the canvas (buildLayers()) then I can select any image that is on the canvas and I can move it around. My next step was to add rotation but only to selected image. Currently rotated image will appear however original one is also there... another problem is that I cannot select rotated image and when I am dragging original one, rotated image goes to a different direction eq when I move original to right, rotated moves down.



function renderCanvas() {
requestAnimationFrame(renderCanvas);

g.clearRect(0, 0, canvas.width, canvas.height);
g2.clearRect(0, 0, canvas.width, canvas.height);

for (var i = 0; i < numOfImages; i++) {
drawImg(imgX[i], imgY[i], images[i]);
}
//draw a border on selected image
if (numOfImages > 0) {
drawBorder(imgX[selectedImg], imgY[selectedImg]);
rotareImage(imgX[selectedImg], imgY[selectedImg], images[selectedImg]);
}


}
// -------------------------------------------------------------------

function drawImg(x, y, images) {
g.drawImage(images, x - (imgWidth / 2), y - (imgHeight / 2), imgWidth, imgHeight);
}

function buildLayers() {
for (var layer = 0; layer < numOfImages + 1; layer++) {
imgX[layer + numOfImages] = canvas.width / 2;
imgY[layer + numOfImages] = canvas.height / 2;
}
}
function rotareImage(x, y, images) {

g.save();

g.translate(canvas.width / 2, canvas.height / 2);
g.rotate(Math.radians(90));
g.translate(-canvas.width / 2, -canvas.height / 2);

drawImg(x, y, images);
g.restore();

}

Math.radians = function (degrees) {
return degrees * Math.PI / 180;
};




Answer

You'll need to rotate only the single image instead of the whole canvas, and you have to do it before drawImg() is called on it.

In your renderCanvas function:

for (var i = 0; i < numOfImages; i++) {

    // If this image is to be rotated/bordered
    // it needs to be done now, before drawImg() is called,
    // on the layer, not on the entire canvas
    if(i===selectedImg){

        // Draw the border
        drawBorder(imgX[i], imgY[i]);

        // Overwrite the Image object with the rotated version
        imgX[i] = rotateLayer(imgX[i], 90); // 90 degree rotation
    }

    // Now add it to the canvas
    drawImg(imgX[i], imgY[i], images[i]);
}

Then create a rotateLayer function that will rotate the image using a headless canvas and then return the Image object.

function rotateLayer(img, degrees){

    // Create a headless canvas
    var c = document.createElement("canvas");
    c.width = img.width; c.height = img.height;
    var ctx = c.getContext("2d");

    // Draw the image and rotate it on the headless canvas
    ctx.drawImage(img, 0, 0);
    ctx.rotate(Math.radians(degrees));

    // Get the rotated image back from the headless canvas
    var image = new Image();
    image.src = c.toDataURL();

    return image;
}

See the code explanation in the comments.

Disclaimer: I just wrote this in the answer box and did not test it. It may or may not work if you simply copy and paste, it was intended to show you how to do it, not to do it for you.

Comments