HTML5 Canvas - 在不翻译上下文的情况下相对于对象的中心进行缩放

Posted

技术标签:

【中文标题】HTML5 Canvas - 在不翻译上下文的情况下相对于对象的中心进行缩放【英文标题】:HTML5 Canvas - Scaling relative to the center of an object without translating context 【发布时间】:2015-01-30 17:56:06 【问题描述】:

我正在开发一个有多个粒子生成器的画布游戏。粒子在创建后逐渐缩小。为了将粒子从它们的中心点缩小,我使用了 context.translate() 方法:

context.save();
context.translate(particle.x, particle.y);
context.translate(-particle.width/2, -particle.height/2);
context.drawImage(particle.image, 0, 0, particle.width, particle.height);
context.restore();

我已经阅读了一些声称 save()、translate() 和 restore() 方法在计算上非常昂贵的资料。我可以使用其他方法吗?

我的游戏是针对移动浏览器的,所以我尝试尽可能优化性能。

提前致谢!

【问题讨论】:

【参考方案1】:

是的,只需在末尾使用setTransform(),而不是使用保存/恢复:

//context.save();
context.translate(particle.x, particle.y);
context.translate(-particle.width/2, -particle.height/2);
context.drawImage(particle.image, 0, 0, particle.width, particle.height);
//context.restore();
context.setTransform(1,0,0,1,0,0);   // reset matrix

假设没有使用其他累积变换(在这种情况下,您可以重构代码以在需要时设置绝对变换)。

作为参数给出的数字是代表单位矩阵的数字,即。重置矩阵状态。

这比保存/恢复方法快得多,它不仅存储和恢复变换状态,还存储和恢复样式设置、阴影设置、剪切区域等等。

您还可以将两个翻译调用合并为一个调用,并使用乘法而不是除法(这在 CPU 级别上要快得多):

context.translate(particle.x-particle.width*0.5, particle.y-particle.height*0.5);

或者直接使用粒子“着色器”的 x/y 坐标而不进行任何平移。

【讨论】:

谢谢 - 这个小改动将移动性能提高了 10-20fps。非常感谢! 赞成通过一个好的答案显着改进提问者代码。我可能会补充一点,如果只需要翻译,那么您可能会完全避免 context.translate 而只是更改 x,y 坐标。 我最初避免使用它,因为我不知道完整的场景,但现在包含它,因此选项更加清晰(我个人更喜欢 - 我在我自己的粒子引擎中使用它) .谢谢马克E。还添加了更多细节。 感谢更新 - 我现在只使用 x 和 y 坐标:context.drawImage(particle.image, particle.x-particle.width/2, particle.y-particle.height/2, particle.width, particle.height); 但是现在旋转不起作用。假设此方法仅适用于缩放/翻译是否安全? @KenFyrstenberg 是的,我可能应该包括它......尽管我想让我的 sn-p 尽可能简洁。我对 *** 还是很陌生 :) 再次感谢您的建议

以上是关于HTML5 Canvas - 在不翻译上下文的情况下相对于对象的中心进行缩放的主要内容,如果未能解决你的问题,请参考以下文章

如何在不改变其图案的情况下改变 HTML5 Canvas 中图像的颜色

HTML5 Canvas 翻译、旋转、缩放

如何在不损失图像质量的情况下调整图像大小以适合小型 HTML5 画布? [复制]

HTML5 Canvas - 如何在画布中的图像上绘制矩形

html5 canvas 学习

如何使用 React 的 Context 功能将 HTML5 Canvas 上下文传递给 this.props.children?