3

(对不起,如果这是重复的,但我认为不是)

请注意,我使用的是 Google Chrome 29.0.1547.66 m。

我目前正在进行一个KineticJS项目,它构建了一个 40 x 100 瓷砖的平铺“交错”地图。地图渲染大约需要 500 毫秒,这很好。所有4000 块瓷砖都放在了一层上。

完成后,我尝试拖动舞台,但性能很差,因为它试图一次移动所有 4000 个图块。我们谈论的是160 毫秒的 CPU 时间

我已经尝试按照其他人的建议将每一行分成自己的单独层,但这使它变得更糟(620ms CPU 时间),因为它必须单独移动每一层。

我不会说我非常擅长 JavaScript,但我看不到提高拖动性能的方法,我已经做了一些血统研究。

也许缓存 整个层或其他东西可以工作?

到目前为止,该项目有相当多的代码,所以我只显示片段

//Stage Object
window.stage = new Kinetic.Stage({
    container: element,
    width: 800,
    height: 600,
    draggable: true
});

//Map Loop for create and position tiles
var tempLayer = map.addLayer(); //makes a new layer and adds it to stage etc.
for (var y = 0; y < height; y++) { //100 tiles high
    for (var x = width-1; x > -1; x--) { //40 tiles wide
        var tileImg = map._tiles[mapArray[x][y]-1]; //map._tiles is just an array of Kinetic.Image objects
        if (typeof(tileImg) != "undefined"){
            var tileClone = tileImg.clone();
            map.place(x, y, 0, tileClone, tempLayer); //places tile in world scope positions
        }
    }
}
tempLayer.draw();

如果我无法弄清楚如何提高性能,那么任何人都无法运行它,并且该项目将不得不被装箱,因此所有想法都值得赞赏!谢谢!

4

1 回答 1

3

看看这个 SO Question: How to cache a whole layer right before dragstart and revert it back on dragend?

这个问题和我的回答描述了一个类似的问题,我认为我提出的解决方案可能会有所帮助。

基本上是我的建议(虽然我没有完全尝试过,所以我不知道它是否会很好用):

  1. 使用缓存层toImage
  2. 将图像拖到不同的图层上,同时隐藏原始图层。
  3. 计算dx 和 dy(你移动的距离)
  4. 用dx 和 dy更新原始层
  5. 隐藏图像层,显示形状层。

我设法创建了一个快速示例JSFIDDLE来使用,所以检查一下。我注意到的一件事是舞台大小确实影响了拖动的性能,即使它只是1 rectangle 而不是 4000。所以,如果舞台真的很大,即使有这个图像缓存的东西,它也没有真正的帮助。但是当我减小舞台大小时,它似乎有帮助

更新

我在拖动时找到了“拉伸/缩放”图像的原因。这是因为我静态设置了图像大小,如下所示:

var image = new Kinetic.Image({
    image: img,
    x: 0,
    y: 0,
    width: 2000,
    height: 5000
});

这导致图像拉伸,因为图像大于舞台。如果我们像这样删除宽度和高度属性:

var image = new Kinetic.Image({
    image: img,
    x: 0,
    y: 0
});

您会看到图像不再拉伸。

另一个好消息是我将舞台尺寸减少了一半(尽管矩形的数量、矩形占用的面积和图像的大小保持不变)并且性能有了很大的提高。希望你的舞台尺寸没有我之前的那么大(2000x5000),对吧?现在检查JSFIDDLE并查看它的实际效果!

于 2013-09-13T15:02:32.873 回答