【问题标题】:HTML5 Canvas smooth scroll tilemapHTML5 Canvas 平滑滚动 tilemap
【发布时间】:2013-08-09 11:26:28
【问题描述】:

我尝试使用画布对象构建一个可滚动的图块地图,该对象会自动计算相对于屏幕分辨率的大小,并相对于(更大的)地图上的位置渲染图块。

我打算移动生成的图块,只绘制需要重新绘制的图块。

这意味着我滚动地图,在顶部绘制新图块(例如向上移动)并删除底部的最后一个图块,这些图块现在不在可见画布中。

我的问题是:

我认为改变画布中每个图块的位置对性能来说不是很好,我认为这可以使用getImageData()putImageData()来解决,但仍然存在一个问题:

如果我只是移动这些图块并绘制新图块,它总是会“跳跃”30 像素(1 个图块 = 30x30),那么有没有一种简单/性能技术上好的方法来实现平滑的线性滚动效果?

【问题讨论】:

    标签: javascript html performance canvas html5-canvas


    【解决方案1】:

    只需使用drawImage 或图案填充木板凋零(后者需要您使用翻译将瓷砖放在正确的位置)。

    drawImage 将新的目标大小作为参数,因此您也可以缩放图块。

    这是我为其他问题所做的模式实现,但我假设您应该能够看到代码中发生了什么:

    function fillPattern(img, w, h) {
    
        //draw the tile once
        ctx.drawImage(img, 0, 0, w, h);
    
        /// draw horizontal line by cloning
        /// already drawn tiles before it
        while (w < canvas.width) {
            ctx.drawImage(canvas, w, 0);
            w *= 2;
        }
    
        /// clone vertically, double steps each time
        while (h < canvas.height) {
            ctx.drawImage(canvas, 0, h);
            h *= 2;
        }
    }
    

    您可以在 implementation this was used for(具有实时缩放和平铺功能的视频墙)中看到性能良好。

    为了将它更多地投射到你所拥有的东西上 - 你可以简单地将画布绘制到一个新位置并填充新的“间隙”,而不是像上面那样绘制每个图块:

    ctx.drawImage(myCanvas, offsetX, offseY);
    fillGap();
    

    您可以使用 drawImage 进行剪辑,但画布会在内部将其剪辑为新的,因此当您将部分图像移到画布外时,在 JavaScript 中剪辑图像没有任何好处。

    【讨论】:

    • 感谢这篇有用的文字!我的网格是有纹理的,所以我不能只复制行,我必须从数据库中为每个字段加载纹理 ID,我目前正在寻找一种改进方法,因为我认为它不是很快。移动画布和填补空白的想法确实帮助了我,但有没有办法用线性动画做同样的事情?还是只能通过每秒执行 30 次才能使它看起来像动画?
    • @cybrox 不幸的是,在 x 次秒内绘制它是不可能的。这就是系统在低级别的处理方式以及视频播放器的处理方式。 Apropos 视频:这里的选项是预渲染所有内容,但它也有其成本,例如内存和初始加载时间。您还可以预渲染分组或不更改的图块,以及将更大的区域预渲染到屏幕外画布并制作某种缓存(与双缓冲相关)。如果您在一个底部画布上具有移动背景,而在顶部具有静态/不同动画,则使用 2 个画布也可能会有所帮助。
    • 感谢您的建议。我目前正在使用多个画布,一个用于瓷砖,一个用于其上的对象。瓦片存储在瓦片集中以大幅减少要加载的图像数量,一个瓦片集中始终包含 10x10 瓦片(= 300x300 像素),并且整个图像的一部分在画布中呈现为单个瓦片。但是,感谢您的帮助,我将尝试计算与给定 FPS 速率相关的所有内容,并使其看起来很流畅 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多