HTML画布中的大量翻译会导致奇怪的行为

Large numbers in HTML canvas translate result in strange behavior

本文关键字:翻译 布中 HTML      更新时间:2023-09-26

我试图弄清楚为什么当我在HTML画布上给translate()调用的x组件一个很大的数字时,矩形似乎不再在适当的坐标处绘制。

在下面的示例中,绘制的两个矩形在x分量上仅相差1。因此,我希望它们的左边缘只相隔一个像素。正如您在Firefox和Chrome中看到的,情况并非如此。

<html>
<head>
    <script type="text/javascript">
        function go() {
            var canvas = document.getElementById("canvas");
            if(canvas.getContext) {
                var ctx = canvas.getContext("2d");
                ctx.translate(-1000000000, -500);
                ctx.fillStyle = '#F00'
                ctx.fillRect(1000000033, 520, 100, 200);
                ctx.fillStyle = '#00F';
                ctx.fillRect(1000000032, 720, 100, 200);
            }
        }
    </script>
</head>
<body onload="go();">
<canvas id="canvas" width="800" height="600">
</canvas>
</body>
</html>

下面是同样的例子:http://jsfiddle.net/pQst6/

我还制作了一个动画版本。http://jsfiddle.net/ry35e/正如您所看到的,图形开始时是正常的,但随着translate方法的x参数的增加,它会有越来越奇怪的行为。

Firefox和Chrome的行为似乎是一样的,所以这似乎是预期的行为,而不是浏览器错误。我猜这是某种精度问题。你同意/不同意?

如果画布存在某种精度问题,我想我将不得不找到或实现我自己的转换矩阵,并将其封装在画布上下文中。我相信它不会很难制作,但有人知道javascript库可以进行这样的转换(使用pop、push等)吗?

谢谢!

当调用具有2^24(16 777 216)或更大整数的fillRect时,会出现偏差。这恰好也是您可以用单精度表达的最大整数。工作草案表示支持双精度(2^53),但显然情况并非如此。CanvasRenderingContext2D的Mozilla开发者网络(MDN)文档声明只支持单精度(浮点)。

  • 单精度:http://en.wikipedia.org/wiki/Single-precision
  • 双精度:http://en.wikipedia.org/wiki/Double-precision
  • 工作草案:http://www.w3.org/TR/2dcontext/
  • MDN文档:https://developer.mozilla.org/en/DOM/CanvasRenderingContext2D#fillRect()