Javascript KineticJS-使用Stage.draggable移动4000块瓷砖

Javascript KineticJS-使用Stage.draggable移动4000块瓷砖,javascript,html,performance,google-chrome,kineticjs,Javascript,Html,Performance,Google Chrome,Kineticjs,(如果这是重复的,很抱歉,但我不认为是重复的) 正如你所知,我使用的是谷歌Chrome 29.0.1547.66 m 我现在有一个KineticJS项目正在进行,该项目将构建一个平铺的“交错”地图40 x 100平铺。渲染贴图大约需要500毫秒,这很好。所有4000块瓷砖都已铺在一层上 完成后,我尝试拖动舞台,但我的表现非常差,因为它试图一次移动所有4000个瓷砖。我们谈论的是160ms的CPU时间 我曾尝试将每一行分解为自己的独立层,但这使得情况更糟(620ms CPU时间),因为它必须单独移

(如果这是重复的,很抱歉,但我不认为是重复的)

正如你所知,我使用的是谷歌Chrome 29.0.1547.66 m

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

完成后,我尝试拖动舞台,但我的表现非常差,因为它试图一次移动所有4000个瓷砖。我们谈论的是160ms的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();
//阶段对象
window.stage=新的动能.stage({
容器:元素,
宽度:800,
身高:600,
德拉格布尔:是的
});
//用于创建和定位平铺的贴图循环
var tempLayer=map.addLayer()//创建一个新层并将其添加到舞台等。
对于(变量y=0;y-1;x--){//40瓷砖宽
var tileImg=map._tiles[mapArray[x][y]-1];//map._tiles只是一个dynamic.Image对象数组
if(typeof(tileImg)!=“未定义”){
var tileClone=tileImg.clone();
map.place(x,y,0,tileClone,tempLayer);//将平铺放置在世界范围的位置
}
}
}
tempLayer.draw();

如果我无法解决如何提高性能,任何人都无法运行此项目,项目将不得不装箱,因此所有想法都非常感谢!谢谢

看看这个问题:

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

基本上就是我所建议的(虽然我还没有完全尝试过,所以我不知道它是否能很好地工作):

  • 使用
    toImage
  • 在隐藏原始图层的同时,将图像拖动到其他图层上
  • 计算dx和dy(移动的距离)
  • 用dx和dy更新原始图层
  • 隐藏图像层,显示形状层
  • 我设法创建了一个快速的例子来使用,所以请查看它。我注意到的一件事是,阶段大小确实影响了拖动的性能,即使它只是1个矩形而不是4000个矩形。因此,如果舞台真的很大,即使有了这个图像缓存的东西,它也没有真正的帮助。但当我减小舞台尺寸时,它似乎会有所帮助

    更新

    //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();
    
    我在拖动时找到了“拉伸/缩放”图像的原因。这是因为我静态设置了图像大小,如下所示:

    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),对吧?现在检查并查看它的运行情况

    你能给我们一个工作的JSFIDLE来重现这个问题吗?你需要与瓷砖交互(除了移动它们之外)?如果没有,可以考虑用CSS(或几个较小的背景图像)重新定位大的背景HTML图像。虽然Kinetic很有效,但4000个单独的对象带来了大量的编程开销。JSFIDLE还没有完全工作,如果我得到它,我会告诉你,但是如果你愿意,你也可以测试它。我已经看过了,我想你已经了解了一些东西,但这只是我还是KineticJS只是缓存视图中的层的一部分?将向您显示缓存的图像延伸到原始平铺层上,如果一直向下,您将看到它们在同一个位置结束。不,我现在也看到了,这不是很奇怪吗?不确定是什么原因导致了哈哈贾姆斯,我更新了上面的答案,现在看起来很不错!让我知道它是如何运行的,或者是否遇到任何其他问题。哦,我从中添加了随机颜色,以便在Rect和图像之间进行比较时看起来更好