我需要在画布中构建一种地图,它显示超过10,000个元素(圆圈),需要缩放和平移。我在这里描述了我的方法Android significantly slower in resizing and moving multiple canvas elements,并根据评论中提出的建议改变了我的实施方式。
要平移地图setTransform
现在在画布上下文中使用,然后在删除画布后重绘视口中的所有元素。 (我把它们从R树中取出来)。每次mousemove
事件都会发生这种情况。
虽然当我有一个约200个要绘制的对象的缩放地图时,这非常快,但是当缩小时需要绘制超过10k个对象时平移非常慢。我显然也需要快速。
满足此要求的最佳做法是什么? 我的方法如下:
top
和left
样式移动div中的画布并减少重绘次数(当画布靠近视口边框时)答案 0 :(得分:4)
我的方法可能是:
创建一个大小为“viewport”的屏幕画布(例如浏览器窗口的大小)
将对象存储在数据结构中,以便您可以在任何给定时间快速确定哪些对象可见(给定当前视口位置和缩放)。
然后在每个渲染上:
答案 1 :(得分:1)
我第二次回答@Strilles。
这是一个过滤示例,可以在计算所有精灵和计算仅可见精灵之间切换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();