HTML旋转整个画布90度

5
我有一个绘制在html画布上的图像。我希望能够将整个画布图像旋转90度,但是我似乎找不到如何旋转整个画布图像的示例,只有可以旋转画布上的对象的示例。
有人有旋转整个画布90度的示例代码吗?
我接受下面的回答,但想提供额外的示例代码:http://jsfiddle.net/VTyNF/1/
<canvas id="myCanvas" width="578" height="200"></canvas>

<script>
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');

  context.translate(canvas.width/2,canvas.height/2) 
  context.rotate(90 * (Math.PI / 180));   
  context.beginPath();
  context.rect(188 - canvas.width/2, 50 - canvas.height/2, 200, 100);
  context.fillStyle = 'yellow';
  context.fill();
  context.lineWidth = 7;
  context.strokeStyle = 'black';
  context.stroke();
</script>

你能提供一些示例代码吗? - Shannon Hochkins
我猜应该像这样?http://jsfiddle.net/VTyNF/1/ 在旋转后,它应该是垂直的而不是水平的,并且仍然位于画布的中心。 - Kyle
2
请注意,您无法旋转已存在于画布上的任何图形。因此,请首先使用context.clearRect(0,0,canvas.width,canvas.height)清除画布上的所有现有图形;然后,要旋转整个画布,可以使用context.rotate(90*Math.PI/180)命令;最后,重新绘制您想要在画布上显示的所有内容,这些新的图形将会被旋转90度。 - markE
5个回答

4

在绘制画布之前,您需要应用此旋转。无法旋转已经绘制的任何内容。

因此:

要旋转画布,content.rotate() 需要一个弧度值。首先,让我们使用以下方法将角度转换为弧度:

function getRadianAngle(degreeValue) {
    return degreeValue * Math.PI / 180;
} 

在旋转画布之前,您可能需要先翻译画布,以便其原点正确设置。

context.translate(context.width/2,context.height/2);

一旦我们知道所需的值,我们就可以在绘制任何东西之前简单地旋转画布!

请注意,在您的示例中,您绘制的矩形也在context.rect(X,Y,W,H)的前两个参数中进行偏移。

我发现将宽度设置为变量,然后进行简单的数学运算以自动重新定位框更容易,现在请注意,它完美地置于中心并且可以很好地旋转!

演示: http://jsfiddle.net/shannonhochkins/VTyNF/6/


嗯,谢谢你迄今为止的帮助。这似乎是从左上角旋转它。有没有一种方法可以从中心旋转? - Kyle
1
在旋转之前,使用context.translate(canvas.width/2,canvas.height/2)。 - markE
嘿,@user1308743,我已经为你编辑了我的fiddle。添加了一个translate属性! - Shannon Hochkins
@user1308743,我已经修复了这个小例子,并且让它更加简洁,祝你编码愉快! - Shannon Hochkins

2

假设您的 canvas 元素有一个 id 为 "foo"。在 JavaScript 中,您可以这样做:

var canvas = document.getElementById('foo'),
    context = canvas.getContext('2d');

// Rotates the canvas 90 degrees
context.rotate(90 * (Math.PI / 180));

0

这个版本不需要90度转弯的中心点:(对新手来说不太容易,因为它是一个每像素4个值的一维数组。)

    //...
    const canvas = document.getElementById('canvas');
    const context = canvas.getContext('2d', {willReadFrequently: true});
    const img = document.createElement('img');
    const file = inp.files[0]; // file from user input
    img.src = URL.createObjectURL(file);

    img.addEventListener('load', function () {
        canvas.width = this.width;
        canvas.height = this.height;
        canvas.crossOrigin = "anonymous";
    
        context.drawImage(img, 0, 0);
        rotateClockwiseBy90(canvas, context, img);
    }   
}

function rotateClockwiseBy90(canvas, context, img) {
    const width = canvas.width;
    const height = canvas.height;

    const imageData = context.getImageData(0, 0, width, height);
    const rotatedImageData = context.createImageData(height, width);

    //[redIndex, greenIndex, blueIndex, alphaIndex]
    const width4 = width * 4;
    const height4 = height * 4;

    for (let y = 0; y < height4; y += 4) {
        for (let x = 0; x < width4; x += 4) {
            rotatedImageData.data[x * height + (height4 - y - 1) - 3] = imageData.data[y * width + x];
            rotatedImageData.data[x * height + (height4 - y - 1) - 2] = imageData.data[y * width + x + 1];
            rotatedImageData.data[x * height + (height4 - y - 1) - 1] = imageData.data[y * width + x + 2];
            rotatedImageData.data[x * height + (height4 - y - 1)] = imageData.data[y * width + x + 3];
        }
    }

    const cw = canvas.width;
    canvas.width = canvas.height;
    canvas.height = cw;
    context.putImageData(rotatedImageData, 0, 0);
}

如果有人试图理解逻辑:
rotatedImageData.data[x * height ...

应该真正是:

rotatedImageData.data[x / 4 * height * 4 ...

因为对于旋转数组,x 表示行数,而高度表示行长度,但结果是相同的。

逆时针旋转版本:

for (let y = 0; y < height4; y += 4) {
    for (let x = 0; x < width4; x += 4) {
        rotatedImageData.data[(height4 * (width - x/4) - height4 + y)] = imageData.data[y * width + x];
        rotatedImageData.data[(height4 * (width - x/4) - height4 + y) + 1] = imageData.data[y * width + x + 1];
        rotatedImageData.data[(height4 * (width - x/4) - height4 + y) + 2] = imageData.data[y * width + x + 2];
        rotatedImageData.data[(height4 * (width - x/4) - height4 + y) + 3] = imageData.data[y * width + x + 3];
    }
}

0
你能用CSS来旋转元素吗?使用transform: rotate(90deg)可以实现吗?

1
为什么他要那个? - aaronman
1
我希望实际的图像被旋转,而不仅仅是通过旋转画布元素来看起来被旋转。该图像将被保存。 - Kyle

0
您可以通过操作像素数据轻松将图像旋转九十度。 如果您的画布不是正方形,则需要就“正确”答案做出一些选择。
使用 getImageData 函数检索像素,以通常的方式操作它们,然后使用 putImageData 显示结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接