Chrome浏览器无法显示大尺寸画布

4
我有一个应用程序,在画布上绘制超过260个图表。将它们放在单个画布上的决定是基于速度考虑的 - 对于各种任务(如缩放和平移),这种方式要快得多。也就是说,在这种情况下,将其分成260个画布不是一个选项。
在Opera、Firefox和IE上一切都正常。然而,在高度超过约8130像素(宽度恒定为834像素)时,Chrome停止显示画布。
也就是说,我有能力在飞行中添加/删除图表(它们一个接一个地堆叠),一旦高度超过8130像素,Chrome就会简单地“隐藏”画布。它仍然响应,并且没有错误被抛出 - 这可能是什么原因?

1
一个 bug,也许?你能在 fiddle 中重现它吗? - MaxArt
可能是这样,但也许有一些我不知道的 Chrome 选项?添加了一个 Fiddle http://jsfiddle.net/Y79s3/4/ 如果你将高度从 8130 改为 9130,则画布在 Chrome 中会被“隐藏”。 - lando
我仍然显示画布,但我正在使用Chrome 29 dev,它可能是比你的更高级的版本。这也可能取决于您的显卡设置。我有一个集成在CPU中的AMD HD 6410D。 - MaxArt
在我的Chrome 27 / Mac上显示 - nycynik
奇怪,可能与Windows有关?我正在使用Chrome 28.0.1500.72m / Windows 7。 - lando
1个回答

5
尽管标准规定画布的大小为无符号长整型:
interface HTMLCanvasElement : HTMLElement {
           attribute unsigned long width;
           attribute unsigned long height;

来源:WhatWG/Canvas元素

大多数浏览器似乎将画布大小限制在8192(Safari显然为6826)。

无论如何(一般而言)-

如果您需要比那更大的画布尺寸,我会说您应该重新考虑设计。画布很少需要比屏幕上实际可见的更大。将画布视为数据的视口而不是其持有者。这也是大多数操作系统在低级别上的工作方式,因为这已被证明是几十年来最好的方法。

考虑带宽要求(这并不完全准确,因为这基于实现及其优化 - 但为了指向我们正在处理的内容):

使用RGBA缓冲区的8192 x 8192像素画布消耗256 MB原始内存(根据浏览器实现情况,可能会加倍)。

更新频率为60Hz,带宽最低为15GB/秒。此外,其他浏览器和系统内容也会增加这个值。如果在典型的消费者电脑上使用(而不是开发人员机器),理论上的好处很容易丧失。

是的,您可以通过预渲染大区域并通过将像素从可见区域复制到视口中来获得速度-到一定程度和特定成本为止(内存是一个因素)。无论如何,使用JavaScript移动“blitting源”相对于更低级别的环境,这种收益都会损失。

通常最好将数据保留在矢量格式(数组/类型化数组/对象)中,并通过检查边界即可绘制出可见的部分。您可以通过各种方式优化数据以快速访问它(例如参见quad-trees)。

呈现矢量数据并不像人们想象的那么昂贵(如果“正确地”完成),并且画布越小,清除和重绘数据的速度就越快。

然而,主要的技巧是将已经在画布上的内容(与从一个巨大的画布贴图相同的效果)blit,并且只更新新的间隙。

我的两分钱意见...


有时候情况各不相同。 :-) 我不想争论设计本身——尝试了几种方法,在 JavaScript 环境的限制下,这被认为是最优的方法。我们正在谈论平均 120 Mb 的数据,必须一次性可视化和处理。这样可以避免过载服务器,并在 PC 上提供流畅的体验。顺便说一句,奇怪的是只有 Chrome 有这个限制,我已经让自己相信这是一个 bug? :-) - lando
我遇到这个限制的情况是,我正在客户端存储来自网络摄像头<video>的图像以进行重放。我首先遇到了画布#限制,然后尝试平铺画布,然后又遇到了尺寸限制。这不是画布的预期使用方式,但我还没有找到其他存储网络摄像头数据的方法。 - Frank Schwieterman
@FrankSchwieterman 我的希望是视频元素或其等效物将打开以存储视频的单个帧。但由于在与播放相关的格式上达成一致存在问题,我认为这不会很快发生。本地存储也是一种选择,例如File API(存储图像的缓存包),但这需要一段时间才能成熟和足够可用。 - user1693593

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接