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

nfg76nw0  于 2022-12-28  发布在  Java
关注(0)|答案(3)|浏览(377)

假设我们有一块画布:

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

点击一个按钮,画布会顺时针旋转90度(绕着中心),画布的尺寸也会更新,从某种意义上说,它看起来像这样:

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

注意,画布的id是相同的。
想象一下,简单地顺时针旋转图像,而不进行裁剪或填充。
在我创建一个新的画布和旋转和复制像素的漫长道路之前,有什么建议吗?

更新示例代码,注解中的建议仍然不起作用:

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

64jmpszr

64jmpszr1#

看看这个。
为了达到演示中看到的效果,我使用canvas.toDataURL将画布缓存到图像中,然后将画布重置为新的尺寸,适当地平移和旋转上下文,最后将缓存的图像绘制回修改后的画布。
这样你就可以很容易地旋转画布,而不需要重新绘制所有的东西。但是因为浏览器使用anti-aliasing方法,每次这个操作完成后,你都会注意到结果有些模糊。如果你不喜欢这个行为,我唯一能想到的解决办法就是重新绘制所有的东西,这是更难跟踪的。
下面是代码:

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;               
        }
    }
}
nzk0hqpo

nzk0hqpo2#

    • 轮换**

请注意,不能旋转单个元素。

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

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

// draw your object
ctx.restore();
    • 宽度/高度调整**

唯一的方法,我曾经发现妥善处理显示比例,屏幕大小等:

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

注意我故意使用canvas.style.widthcanvas.style.height。另外,对于可调画布,不要依赖CSS或媒体查询来进行转换,因为像素比率的差异,它们是一个令人头痛的问题。JavaScript会自动考虑这些问题。

    • 更新**

你还必须在绘制之前更新宽度和高度。不确定你想达到什么目的,但我想这不是问题:
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);
qoefvg9y

qoefvg9y3#

如果要将图像旋转90度,这可能会很有帮助:

export const rotateBase64Image = async (base64data: string) => {
  const image = new Image();
  image.src = base64data;

  return new Promise<string>((resolve, reject) => {
    image.onload = function () {
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");

      if (!ctx) throw new Error("cannnot get context '2d'");
      canvas.width = image.height;
      canvas.height = image.width;
      ctx.setTransform(0, 1, -1, 0, canvas.width, 0); // overwrite existing transform
      ctx!.drawImage(image, 0, 0);

      canvas.toBlob((blob) => {
        if (!blob) {
          return reject("Canvas is empty");
        }
        const fileUrl = window.URL.createObjectURL(blob);
        resolve(fileUrl);
      }, "image/jpeg");
    };
  });
};

如果你没有base64格式的图像,你可以这样做:

const handleRotate = async () => {
  const res = await fetch(link);
  const blob = await res.blob();
  const b64: string = await blobToB64(blob);
  const rotatedImage = await rotateBase64Image(b64)
  setLink(rotatedImage);
}

下面是我的blobTob64函数:

export const blobToB64 = async (blob) => {
  return new Promise((resolve, _) => {
      const reader = new FileReader();
      reader.onloadend = () => resolve(reader.result);
      reader.readAsDataURL(blob);
  });
};

相关问题