当前位置: 首页 > 知识库问答 >
问题:

使用>10k对象缩放和平移HTML5画布的最佳实践

拓拔嘉运
2023-03-14

我需要在画布上构建一种地图,显示超过10000个元素(圆),并且需要缩放和可移动。我在这里描述了我的方法,Android在调整和移动多个画布元素方面明显较慢,并根据评论中提出的建议更改了我的实现。

平移贴图现在在画布上下文中使用setTransform,然后在擦除画布后重新绘制视口中的所有元素。(我把它们从R树上取下来)。这发生在每个mousemove事件上。

当我有一个缩放的地图要绘制200个左右的对象时,这是非常快的,但当缩小时,平移速度非常慢,需要绘制超过10k个对象。我显然也需要快点。

满足这一要求的最佳做法是什么?我的方法如下:

  • 在画布上进行视口div,并将画布变大(如每侧50%)

共有2个答案

陶征
2023-03-14

我支持斯特里勒的回答。

下面是一个过滤示例,在计算所有精灵和计算仅可见精灵之间切换,每次间隔5秒:

var canvas = document.body.appendChild(document.createElement("canvas"));
canvas.width = 100;
canvas.height = canvas.width;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(255,0,0,0.1)";
;
var sprites = [];
while (sprites.length < 100000) {
    sprites.push({
        x: Math.round(Math.random() * 10000 - 5000),
        y: Math.round(Math.random() * 10000 - 5000)
    });
}
var drawAll = true;
function draw() {
    var targets;
    if (drawAll == true) {
        targets = sprites.slice(0);
    }
    else {
        targets = sprites.filter(function (sprite) {
            return sprite.x > -10 && sprite.x < 110 && sprite.y > -10 && sprite.y < 110;
        });
    }
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    for (var t = 0; t < targets.length; t++) {
        var target = targets[t];
        ctx.fillRect(target.x - 5, target.y - 5, 10, 10);
        ctx.strokeRect(target.x - 5, target.y - 5, 10, 10);
    }
}
function main() {
    requestAnimationFrame(main);
    for (var i = 0; i < sprites.length; i++) {
        var sprite = sprites[i];
        sprite.y++;
        if (sprite.y > 110) {
            sprite.y -= 200;
        }
    }
    draw();
}
setInterval(function () {
    drawAll = !drawAll;
    console.log(drawAll ? "Draw all" : "Draw filtered");
}, 5000);
main();
长孙鸿振
2023-03-14

我的方法可能是:

>

  • 创建一个“视口”大小的屏幕画布(例如浏览器窗口的大小)

    将要绘制的对象存储在数据结构中,该数据结构允许您快速确定在任何给定时间(给定当前视口位置和缩放)哪些对象可见。

    然后在每个渲染:

    • 清除画布

  •  类似资料:
    • 我正在做自己的画布抽屉项目,只是停留在放大/缩小功能上。在我的项目中,我使用缩放和平移来进行缩放,因为我想将所有画布及其元素保持在中心。在画了一点草图(不是数学天才)之后,我成功地画出了下面的公式用于翻译过程,因此缩放后画布将保持在它的视口的中间:旧的宽度和高度/ 2 -新的宽度和高度(这是旧的宽度和高度乘以比例步长,在我的例子中是1.1)/2。从逻辑上讲,这应该行得通。但是在尝试了几次放大和缩小

    • 问题内容: 这里是我想要的描述:在tkinter画布中绘制几何对象(在此为矩形)的集合,然后蜜蜂通过鼠标探索该画布。单击并拖动以移动画布,滚动放大和缩小。 使用本主题,我找到了单击和拖动部分:使用Mousewith-mouse 移动tkinter画布 我设法写了一些滚动缩放。移动和缩放都可以很好地分开工作。 问题 :如果移动然后放大,则变焦的焦点不再是光标所在的位置。 有什么建议吗? 这是一段要测

    • 问题内容: 如何才能平滑地为画布创建缩放动画?GWT提供了一种获取滚轮数量的方法和。 这里的问题是,每个车轮运动都会执行此方法,并且如果我在该方法本身中调用画布重绘,事情会变得很滞后。 因此,我想到了以某种方式制作缩放动画的方法。但是如何? 我考虑过创建一个,但没有真正的主意,因为只有mousewheelevent作为起点,而用户没有完成用滚轮缩放的终点… 问题答案: 这是我用来缩放图像的可伸缩图

    • 问题内容: 我希望能够放大HTML 5画布中鼠标下方的点,例如Google Maps上的。我该如何实现? 问题答案: 终于解决了: 关键是计算轴位置,以便缩放点(鼠标指针)在缩放后保持在同一位置。 最初,鼠标与角之间有一段距离,我们希望鼠标下方的点在缩放后保持在同一位置,但这是远离角的地方。因此,我们需要移动(角的坐标)以解决此问题。 然后,其余代码需要应用缩放并转换到绘制上下文,以便其原点与画布

    • 我在Java中编码了一个Mandelbrot集分形,并包含了平移和放大分形的能力。唯一的问题是,当我平移图像并试图放大时,它看起来好像试图放大中心并平移一点。平移和缩放不是真正的平移或缩放,而是对分形的重新计算,看起来像是平移或缩放。 这是我的代码。 我能告诉用户在哪里可以让相机更精确地缩放吗? 先谢谢你。 编辑:图片对于任何想知道这个程序将呈现什么。

    • 问题内容: 如果我有画布,则可以在其上绘制如下的位图: 然后缩放位图: 我想获得比例尺后位图的位置。如果小数位数前的位置是(0,0),小数位数后的位置有一个偏移量,那么我需要该偏移量。如何获取? 谢谢你,很抱歉这个简单的问题,新手在这里… 问题答案: 好吧,让我们尝试为此制定最佳的公式 对于objectNewY也是一样。位图的新宽度和高度当然将是旧大小和比例的倍数。