HTML Canvas:如何绘制翻转/镜像图像?

发布于 2024-12-16 16:16:14 字数 194 浏览 2 评论 0原文

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

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

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

谢谢

I'm trying to flip/mirror an image as I paint it on an HTML canvas; I found a game tutorial showing a sprite sheet per direction a character has to face, but this doesn't seem quite right to me. Especially since each frame has a different size.

What would be the best technique to reach this goal?

I tried to call the setScale(-1, 1); on my canvas with no success. Maybe that isn't meant for this.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

初吻给了烟 2024-12-23 16:16:14
  1. 您可以通过使用 myContext.scale(-1 转换上下文来实现此目的,1) 在绘制图像之前,但是

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

  1. You can do this by transforming the context with myContext.scale(-1,1) before drawing your image, however

  2. This is going to slow down your game. It's a better idea to have a separate, reversed sprite.

奢华的一滴泪 2024-12-23 16:16:14

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

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

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

You need to set the scale of the canvas as well as inverting the width.

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

There are probably some performance issues with this but for me that was not an issue.

放飞的风筝 2024-12-23 16:16:14

如果您只是使用 ctx.scale(-1, 1) 水平翻转它,它就会越界...所以使用 translate 来调整其位置:

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

对于更短的时间代码中,您可以删除 translate 并使用图像大小作为 drawImage 的第二个参数(x 坐标)中的负偏移量:

ctx.scale(-1, 1);
ctx.drawImage(img, canvas.width * -1, 0);

如果您想稍后恢复上下文,在其前后添加 save/restore 全部:

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

If you just flip it horizontally using ctx.scale(-1, 1) it will get off of bounds... so use translate to adjust its position:

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

For a shorter code you can remove the translate and use the image size as negative offset in the second parameter of the drawImage (x coordinate) instead:

ctx.scale(-1, 1);
ctx.drawImage(img, canvas.width * -1, 0);

If you want to restore the context later, add save/restore before and after it all:

ctx.save();
ctx.scale(-1, 1);
ctx.drawImage(img, canvas.width * -1, 0);
ctx.restore();
生生漫 2024-12-23 16:16:14

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

 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>

You don't need to redraw the entire image when creating a reflection. An original reflection simply shows the bottom part of the image. This way you are redrawing a smaller part of the image which provides better performance and also you don't need to create linear gradient to hide the lower part of the image (since you never draw it).

 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>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文