javascript 将画布顺时针旋转 90 度并更新宽度高度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16645801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 05:29:51  来源:igfitidea点击:

Rotate canvas 90 degrees clockwise and update width height

javascriptimage-processingcanvas

提问by zaf

Say we have a canvas:

假设我们有一个画布:

<canvas id="one" width="100" height="200"></canvas>

And on a button click the canvas gets rotated 90 degrees clockwise (around the center) and the dimensions of the canvas get also updated, so in a sense it looks like this afterwards:

然后单击按钮,画布顺时针旋转 90 度(围绕中心),画布的尺寸也会更新,所以从某种意义上说,它之后看起来像这样:

<canvas id="one" width="200" height="100"></canvas>

Note that the id of the canvas is the same.

注意画布的id是一样的。

Imagine simply rotating an image clockwise without it being cropped or being padded.

想象一下简单地顺时针旋转图像而不对其进行裁剪或填充。

Any suggestions before I do it the long way of creating a new canvas and rotating and copying pixel by pixel?

在我创建新画布并逐像素旋转和复制的漫长过程之前,有什么建议吗?

UPDATEsample code with suggestion from comments still not working:

使用来自评论的建议更新示例代码仍然无效:

function imageRotatecw90(){

    var canvas = document.getElementById("one");
    var context = canvas.getContext("2d");

    var cw=canvas.width;
    var ch=canvas.height;

    var myImageData = context.getImageData(0,0, cw,ch);

    context.save();

    context.translate(cw / 2, ch / 2);
    context.rotate(Math.PI/2);

    context.putImageData(myImageData, 0, 0);

    context.restore();

    canvas.width=ch;
    canvas.height=cw;
}

FiddleJS

FiddleJS

回答by Gustavo Carvalho

Look at this DEMO.

看看这个演示

To achieve the results seen in demo, I made use of canvas.toDataURLto cache the canvas into an image, then reset the canvas to their new dimensions, translate and rotate the context properly and finally draw the cached image back to modified canvas.

为了实现演示中看到的结果,我使用canvas.toDataURL将画布缓存到图像中,然后将画布重置为新尺寸,正确平移和旋转上下文,最后将缓存的图像绘制回修改后的画布。

That way you easily rotate the canvas without need to redraw everything again. But because anti-aliasingmethods used by browser, each time this operation is done you'll notice some blurriness in result. If you don't like this behavior the only solution I could figure out is to draw everything again, what is much more difficult to track.

这样您就可以轻松旋转画布,而无需重新绘制所有内容。但是由于anti-aliasing浏览器使用的方法,每次执行此操作时,您都会注意到结果有些模糊。如果您不喜欢这种行为,我能想到的唯一解决方案就是重新绘制所有内容,这是更难以跟踪的。

Here follows the code:

下面是代码:

var canvas = document.getElementById("one");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;

// Sample graphic
context.beginPath();
context.rect(10, 10, 20, 50);
context.fillStyle = 'yellow';
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();

// create button
var button = document.getElementById("rotate");
button.onclick = function () {
    // rotate the canvas 90 degrees each time the button is pressed
    rotate();
}

var myImageData, rotating = false;   

var rotate = function () {
    if (!rotating) {
        rotating = true;            
        // store current data to an image
        myImageData = new Image();
        myImageData.src = canvas.toDataURL();

       myImageData.onload = function () {
            // reset the canvas with new dimensions
            canvas.width = ch;
            canvas.height = cw;
            cw = canvas.width;
            ch = canvas.height;

            context.save();
            // translate and rotate
            context.translate(cw, ch / cw);
            context.rotate(Math.PI / 2);
            // draw the previows image, now rotated
            context.drawImage(myImageData, 0, 0);               
            context.restore();

            // clear the temporary image
            myImageData = null;

            rotating = false;               
        }
    }
}

回答by flavian

Rotation

回转

Note it is not possible to rotate a single element.

请注意,无法旋转单个元素。

ctx.save();
ctx.rotate(0.17);

// Clear the current drawings.
ctx.fillRect()

// draw your object
ctx.restore();

Width/height adjustment

宽度/高度调整

The only way I ever found to properly deal with display ratios, screen sizes etc:

我发现正确处理显示比例、屏幕尺寸等的唯一方法:

canvas.width = 20;// DO NOT USE PIXELS
canvas.height = 40; // AGAIN NO PIXELS

Notice I am intentionally notusing canvas.style.widthor canvas.style.height. Also for an adjustable canvas don't rely on CSS or media queries to do the transformations, they are a headache because of the pixel ratio differences. JavaScript automatically accounts for those.

请注意,我故意使用canvas.style.widthcanvas.style.height。此外,对于不依赖 CSS 或媒体查询进行转换的可调整画布,由于像素比率差异,它们令人头疼。JavaScript 会自动考虑这些。

Update

更新

You also have to update the width and the height before you draw. Not sure what you are trying to achieve, but I guess this isn't a problem:

您还必须在绘制之前更新宽度和高度。不确定您要实现的目标,但我想这不是问题:

Demo here

演示在这里

var canvas = document.getElementById("one");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;

canvas.width = 200;
canvas.height = 400;

// Sample graphic
context.beginPath();
context.rect(10,10,20,50);
context.fillStyle = 'yellow';
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();


var myImageData = context.getImageData(0, 0, cw, ch);

context.save();

context.translate(cw / 2, ch / 2);
context.putImageData(myImageData, 0, 0);
context.rotate(0.20);