【问题标题】:HTML Canvas: How to draw a flipped/mirrored image?HTML Canvas:如何绘制翻转/镜像的图像?
【发布时间】:2011-12-31 09:05:15
【问题描述】:

我正在尝试在 HTML 画布上绘制图像时翻转/镜像图像;我找到了一个游戏教程,显示角色必须面对的每个方向的精灵表,但这对我来说似乎不太正确。特别是因为每一帧都有不同的大小。

实现这一目标的最佳技术是什么?

我试图在我的画布上调用setScale(-1, 1);,但没有成功。也许这不是为了这个。

谢谢

【问题讨论】:

标签: javascript html canvas flip mirror


【解决方案1】:

drawImage 之前添加这段代码。如果你只是水平翻转它,它会越界......所以使用translate调整它的位置:

ctx.translate(canvas.width, 0);
ctx.scale(-1, 1);

如果你想稍后恢复上下文,添加save/restore

ctx.save();
ctx.translate(canvas.width, 0);
ctx.scale(-1, 1);
ctx.drawImage(img, 0, 0);
ctx.restore();

【讨论】:

  • 最简单的方法
  • 如何恢复上下文?每隔一段时间就倒置一次
  • 在之前使用context.save(),在之后使用context.restore(),以便恢复之前的上下文状态。
【解决方案2】:

您需要设置画布的比例以及反转宽度。

drawToCanvas : function(v, context, width, height){
    context.save();
    context.scale(-1, 1);
    context.drawImage(v, 0, 0, width*-1, height);
    context.restore();
}

这可能存在一些性能问题,但对我来说这不是问题。

【讨论】:

  • 注意canvas的变量应该是调用得到的上下文canvasElem.getContext("2d")
  • "...以及反转宽度。"这就是我所缺少的......
【解决方案3】:

创建倒影时无需重新绘制整个图像。原始反射仅显示图像的底部。这样,您可以重绘图像的较小部分,从而提供更好的性能,并且您不需要创建线性渐变来隐藏图像的下部(因为您从不绘制它)。

 var img = new Image();
 img.src = "//vignette2.wikia.nocookie.net/tomandjerryfan/images/9/99/Jerry_Mouse.jpg/revision/latest?cb=20110522075610";
 img.onload = function() {
   var thumbWidth = 250;
   var REFLECTION_HEIGHT = 50;
   var c = document.getElementById("output");
   var ctx = c.getContext("2d");
   var x = 1;
   var y = 1;

	//draw the original image
   ctx.drawImage(img, x, y, thumbWidth, thumbWidth);
	ctx.save();
	//translate to a point from where we want to redraw the new image
   ctx.translate(0, y + thumbWidth + REFLECTION_HEIGHT + 10);
   ctx.scale(1, -1);
   ctx.globalAlpha = 0.25;
   
   //redraw only bottom part of the image
   //g.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
   ctx.drawImage(img, 0, img.height - REFLECTION_HEIGHT, img.width, REFLECTION_HEIGHT, x, y, thumbWidth, REFLECTION_HEIGHT);

   // Revert transform and scale
  ctx.restore();

 };
 body {
   background-color: #FFF;
   text-align: center;
   padding-top: 10px;
 }
<canvas id="output" width="500" height="500"></canvas>

【讨论】:

    【解决方案4】:
    1. 不过,您可以通过在绘制图像之前使用 myContext.scale(-1,1) 转换上下文来做到这一点

    2. 这会减慢您的游戏速度。最好有一个单独的反向精灵。

    【讨论】:

    • 好吧,我只是担心内存使用情况,但移动设备上的 cpu 可用性可能会更加稀少。我会按照你建议的方式走。感谢您的建议!
    • 好吧,不要只相信我的话。对其进行分析,并确保我对您的特定用法没有错。 :)
    • 同意,只创建一个具有两个独立边的图像精灵会快得多。
    • 考虑优化的上下文总是值得的。在游戏男孩或游戏男孩高级游戏的情况下,开发人员受到他们拥有的内存和存储量的极大限制。今天,您不太可能遇到尺寸问题。不过,您仍然可以将其作为优先事项。例如,如果您想将其作为练习来做,为什么不创建一个仅包含紧凑要素的小精灵表,然后在开始游戏之前将面向不同方向的精灵版本写入内存。您以加载速度为代价获得速度和内存优势。
    • 实际上它根本不会降低性能。 2D 画布上下文使用转换矩阵将缩放等应用到渲染的顶点。无论是否调用缩放,变换矩阵都是活动的,因此应用缩放不会改变渲染速度。
    猜你喜欢
    • 2017-06-24
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    • 2011-06-15
    • 1970-01-01
    • 2013-08-18
    相关资源
    最近更新 更多