canvas 镜像反转图片,二重翻转实现单独反转图片不反转背景色

235 阅读2分钟

起因

  • 因为素材只有向左的动画,所以有此需求
  • 网上居然没有搜到,我很失望

补充

scale()失败的原因找到了,因为翻转了画布,所以是从画布右侧开始绘制,后面的不用看了

if (this.speed < 0) {
      context.save();
      context.scale(-1, 1);
      context.drawImage(
        this.image,
        this.frameX * this.width,
        this.frameY * this.height,
        this.spriteWidth,
        this.spriteHeight,
        //关键代码
        -this.x - this.width,
        this.y,
        this.width,
        this.height,
      );
      context.restore();
    } else {
      context.drawImage(
        this.image,
        this.frameX * this.width,
        this.frameY * this.height,
        this.spriteWidth,
        this.spriteHeight,
        this.x,
        this.y,
        this.width,
        this.height,
      );
    }

经过

  1. 尝试scale() api,失败,所以选择操作像素点,这样也更灵活,但是背景也一起反转了
  2. 去掉背景再复制(保存当前背景单独绘制角色,然后绘制保存的背景和反转的角色)。失败:背景变白色,设置背景透明也无效
  3. 把白色像素点转为透明,失败:原因不明,打印出的像素点是一维数组,不知道如何修改,至少ai没有给出正确答案

结果

  • 复制两次背景,反转一次背景,然后让角色和被反转的背景一起反转
  • 没时间就不放图了,直接给代码
context.save();
      // 保存背景
      let bkgOldImageData = context.getImageData(0, 0, this.game.width, this.game.height);
      // 二重翻转准备,获取目标区域背景
      let bkgImageData = context.getImageData(this.x, this.y, this.width, this.height);
      let bkgNewImageData = context.getImageData(this.x, this.y, this.width, this.height);
      
      context.clearRect(0, 0, this.game.width, this.game.height);
      
      // 获取带反转背景的角色图片
      context.putImageData(imageDataHRevert(bkgNewImageData, bkgImageData), this.x, this.y,);
      context.drawImage(
        this.image,
        this.frameX * this.width,
        this.frameY * this.height,
        this.spriteWidth,
        this.spriteHeight,
        this.x,
        this.y,
        this.width,
        this.height,
      );
      let imgData = context.getImageData(this.x, this.y, this.width, this.height);
      let newImgData = context.getImageData(this.x, this.y, this.width, this.height);

      // 将保存的背景重新绘制到画布上
      context.putImageData(bkgOldImageData, 0, 0);
      //反转角色部分
      context.putImageData(imageDataHRevert(newImgData, imgData), this.x, this.y); //左右翻转
context.restore();

/横向像素反转
export function imageDataHRevert(sourceData, newData) {
  for (var i = 0, h = sourceData.height; i < h; i++) {
    for (var j = 0, w = sourceData.width; j < w; j++) {
      newData.data[i * w * 4 + j * 4 + 0] = sourceData.data[i * w * 4 + (w - j) * 4 + 0];
      newData.data[i * w * 4 + j * 4 + 1] = sourceData.data[i * w * 4 + (w - j) * 4 + 1];
      newData.data[i * w * 4 + j * 4 + 2] = sourceData.data[i * w * 4 + (w - j) * 4 + 2];
      newData.data[i * w * 4 + j * 4 + 3] = sourceData.data[i * w * 4 + (w - j) * 4 + 3];
    }
  }
  return newData;
}

更新

好像有人看,不是单机互联网,附上成果图

在这里插入图片描述

失败效果:

  • 仅仅反转像素,会一起反转 在这里插入图片描述
  • 去掉背景再复制 经过2