Canvas只旋转图片而不旋转整个画布的方法

Canvas只旋转图片而不旋转整个画布的方法

场景:因为drawImage()并没有旋转图片的api,只能缩放图片大小而不能旋转。所以,一般,当我们想在canvas中绘制一幅旋转的图片时,首先得rotate()旋转整个canvas,再drawImage()把图片绘制到canvas上,以此来达到旋转图片的效果。但是,这样会导致整个canvas都旋转,会有很多弊端。所以,下面是在不旋转整个canvas的情况下,绘制旋转图片的方法:

思路:因为canvas不支持旋转drawImage()的图片,但是我们也不能旋转整个canvas,但是图片又需要旋转,所以我们需要另一个离屏canvas绘制已经绘制好图片的离屏canvas:

  1. 用一个离屏canvas(此处称为imageCanvas)调用drawImage(image)将图片绘制出来。
  2. 将另一个离屏canvas(此处称为imageWrapperCanvas)以中心为原点旋转(注意,imageWrapperCanvas的宽和高需要足够大来使得旋转后依旧能将imageCanvas显示完全)。
  3. 旋转后调用drawImage(imageCanvas, x, y)居中绘制出imageCanvas,注意此处的x和y分别是:
    x = 0 - imageWrapperCanvas.width / 2 ,
    y = (imageWrapperCanvas.height - imageCanvas.height -
    imageWrapperCanvas.height) / 2 = - imageCanvas.height / 2
    这里x和y的作用是将旋转后的图片的位置调整到imageWrapperCanvas的中心
  4. 将imageWrapper绘制到canvas中。

以上步骤,即可实现。示例代码如下:

const createImageCanvas = () => {
  let imageCanvas = document.createElement('canvas'),
    imageWrapperCanvas = document.createElement('canvas'),
    imageWrapperCtx = imageWrapperCanvas.getContext('2d'),
    imageCtx = imageCanvas.getContext('2d'),
  // 保证imageWrapper的宽高能在旋转任何角度后足够显示imageCanvas
  imageWrapperCanvas.width = 400;
  imageWrapperCanvas.height = 400;
  imageCanvas.width = 400;
  imageCanvas.height = 20;

  // 将图片image绘制到imageCanvas上
  imageCtx.drawImage(image);
  
  // 设置旋转原点为图片的中心点,由于之后会居中绘制imageCanvas,所以imageWrapperCanvas的中心点就是图片的中心点
  imageWrapperCtx.translate(
    imageWrapperCanvas.width / 2,
    imageWrapperCanvas.height / 2
  );

  // 将imageWrapperCanvas以图片中心为旋转中心,旋转slope角度(slope为旋转的角度)
  imageWrapperCtx.rotate((slope * Math.PI) / 180);

  // 调整位置,将imageCanvas在imageWrapperCanvas中居中显示
  imageWrapperCtx.drawImage(
    imageCanvas,
    -(imageWrapperCanvas.width / 2),
    (imageWrapperCanvas.height -
      imageCanvas.height -
      imageWrapperCanvas.height) /
      2
  );
  return imageWrapperCanvas;
};

const imageCanvas = createImageCanvas();
// 将imageWrapperCanvas绘制到canvas你想要的位置(x, y)上
ctx.drawImage(imageCanvas, x, y);

你可能感兴趣的:(Canvas只旋转图片而不旋转整个画布的方法)