4

我已经阅读了有关滚动的所有内容:

构建 HTML5 Canvas/JS 游戏

等等:

(最新的一个令人印象深刻,但即使几乎所有事情都完成了,也没有关于滚动的内容)。

这就是我正在考虑的,我没有发现任何有价值的东西。一个想法刚刚出现在我的脑海中,我想知道我是否应该花很多时间思考并尝试,或者不(这就是我实际上在这里问的原因)。

我打算做一个带有滚动“à la”马里奥的游戏。

滚动的最大缺点是您必须重新绘制整个背景。我已经避免了精灵/滚动的两个性能问题:创建两个画布彼此重叠:

  • 的背景
  • 精灵

只需擦除精灵。

问题在于背景:我正在将背景的完整副本复制到“可见”画布上。(注意:闪烁没有问题,因为用 JavaScript 编写是一个阻塞操作,并且所有现代浏览器都处理垂直同步,因此不需要双缓冲)。

这是我正在写的旧版本,但你会得到大图:

测试 HTML5

现在我想知道滚动:如果我用适当的 CSS(背景图像作为背景)做一个“背景 div”而不是画布,然后直接在图像上写瓷砖,然后改变 CSS 来模拟滚动?它应该更快吗?如果是这样,为什么?有什么好主意吗?

4

4 回答 4

1

在半现代+ 带有半最新+ 浏览器的计算机上,最快的做法可能是获取带有背景图像的超长 div,将溢出设置为隐藏并通过调整 scrollLeft 或 scrollTop 属性进行滚动。这比调整 CSS 属性要快得多,因为它不应该触发 CSS 引擎中的任何回流计算。基本上,任何时候你触及一个可能对 CSS 产生影响的 DOM 属性,整个(或至少很多)文档的结构都需要重新检查和重新渲染。

您可以在背景接近时加载它们,以避免加载一个巨大的大量图像。我不相信有任何 100% 万无一失的方法可以跨浏览器将图像从内存中拉出,但是当您滚动到足够远的地方时,在 DOM 或 CSS 中删除对它的引用可能不会受到伤害背景。这样浏览器的垃圾收集器至少可以选择清除内存。

然而,在依赖 webviews(如 Cordova/Phonegap)的泛移动解决方案中,这就是我提出这个问题的原因。

我不知道,但我很确定混合 HTML 和画布对于性能而言是一个糟糕的想法。现在,我有一个不是超级复杂的 android 游戏,在 android web 视图中的 canvas 元素中的 50x50 100px 瓷砖上窒息,其中还混合了一些基本的 HTML,用于控件之类的东西,并将其他几个 canvas 元素与休息。我基本上有一艘鸟瞰船在周围巡航,并使用俗气的辐射圆图形进行扫描,该图形显示了地图战争迷雾风格的元素。在浏览器中效果很好。科尔多瓦应用程序版本中的彻底灾难。

我怀疑我要实现我的泛移动游戏开发梦想的唯一方法是使用许多 openGL-wrapped-in-a-canvas-API 解决方案中的一种,并完全放弃我认为该死的方便的 HTML UI 实现,因为我的大部分经验是在 Web UI 中。Web 视图 HTML 的另一个一般提示是尽可能避免在内部元素内滚动(所以只要让 body 处理溢出)。除了 body 之外的任何内容都滚动溢出,甚至在 Android 2 的 web 视图中都不起作用,而且它似乎仍然导致 4.1 的视图在我正在开发的应用程序的早期/更简单版本上窒息。

于 2013-11-10T21:40:53.623 回答
0

最快的滚动是使用 CSS 滚动。因此,您绘制所有背景一次,不仅是可见部分,而且是全部,并隐藏不可见的部分,并使用 css 滚动它(边距或位置)。没有重绘,只有 CSS 更改。这项工作真的最快。但如果所有地图都非常庞大,其他自定义方式可能会更好。

于 2013-08-19T19:18:07.253 回答
0

我的最终结论:经过多次尝试,包括 Eirk Reppen 的建议,我直接将“原始”写入画布的隐藏部分并使用 CSS:所有网络浏览器都已经处理了图像闪烁和所有这些问题,并且他们已经优化了所有内容。

所以每次我尝试“优化”时,结果都更糟

似乎网络浏览器可以正确处理初学者制作的基本内容......也许是因为 99% 的 HTML 内容是由初学者制作的。

于 2013-11-25T08:51:03.697 回答
0

这是一个通过更改 CSS 边距来滚动超大画布的演示,这个演示基于随时间滚动:https ://jsfiddle.net/6othtm0c/

而这个带有鼠标拖动的版本:https ://jsfiddle.net/ax7n8944/

HTML:

<div id="canvasdiv" style="width: 500px; height: 250px; overflow: hidden">
    <canvas id="canvas" width="10000px" height="250px"></canvas>
</div>

JS 用于随时间滚动的版本:

canvas = document.getElementById("canvas");
context = canvas.getContext('2d');

for (var i = 0; i < 1000; i++) {
    context.beginPath();
    context.arc(Math.random() * 10000, Math.random() * 250, 20.0, 0, 2 * Math.PI, false);
    context.stroke();
} 

var t0 = window.performance.now();
setInterval(function(){
    canvas.style.marginLeft = -(window.performance.now() - t0)/5 + "px";
}, 5);
于 2016-04-09T00:43:25.417 回答