2012-08-22 58 views
2

对不起,如果这个问题已被问到,我试图找不到。性能变慢kineticjs

我有一个画布,最终应该显示约400-500矩形20-30像素的高度/宽度。它们中的每一个都应该将一个像素左右移动,并将鼠标移到鼠标上,然后再移出鼠标以创建某种选定的行为。 现在,我的代码很适合少量的形状,但其中500个开始大幅减速。 从互联网上的一些例子中,我看到我可以创建“动画层”并将需要动画的对象移动到那里。但是,这仍然需要我重新绘制主层去除移动的项目,从它原来的位置...... 下面的代码:

var seatMap = {}; 

seatMap.seatTypes = { 
    economy: { 
     width: 20, 
     height: 20, 
     fill: 'red', 
     stroke: 'black', 
     strokeWidth: 4, 
     cornerRadius: 5 
    }, 
    business: { 
     width: 22, 
     height: 22, 
     fill: 'red', 
     stroke: 'black', 
     strokeWidth: 4, 
     cornerRadius: 5 
    }, 
    first: { 
     width: 25, 
     height: 25, 
     fill: 'red', 
     stroke: 'black', 
     strokeWidth: 4, 
     cornerRadius: 5 
    } 
}; 

seatMap.Map = function (params) { 
    var stage = new Kinetic.Stage({ 
     container: params.container, 
     width: params.width, 
     height: params.height 
    }); 

    var mainLayer = new Kinetic.Layer(); 
    var animationLayer = new Kinetic.Layer(); 

    stage.add(mainLayer); 
    stage.add(animationLayer); 

    var addSeat = function (object) { 
     object.seat.mainLayerRef = mainLayer; 
     object.seat.animationLayerRef = animationLayer; 

     mainLayer.add(object.seat); 
    }; 

    var refresh = function() { 
     mainLayer.draw(); 
    } 

    return { 
     refresh: refresh, 
     addSeat: addSeat 
    } 
} 

seatMap.Seat = function (params) { 

    var seatType = params.seatType == null ? seatMap.seatTypes.economy : params.seatType; 

    var seat = new Kinetic.Rect({ 
     width: seatType.width, 
     height: seatType.height, 
     x: params.x, 
     y: params.y, 
     fill: seatType.fill, 
     stroke: seatType.stroke, 
     strokewidth: seatType.strokewidth, 
     cornerRadius: seatType.cornerRadius, 
     listening: true 
    }); 
    seat.staticXPosition = params.x; 
    seat.staticYPosition = params.y; 

    seat.on('mouseover', function (event) { 
     event.shape.moveTo(event.shape.animationLayerRef); 
     event.shape.setX(event.shape.staticXPosition - 2); 
     event.shape.setY(event.shape.staticYPosition - 2); 
     event.shape.animationLayerRef.draw(); 
     event.shape.mainLayerRef.draw(); 
    }); 
    seat.on('mouseout', function (event) { 
     event.shape.setX(event.shape.staticXPosition); 
     event.shape.setY(event.shape.staticYPosition); 
     event.shape.moveTo(event.shape.mainLayerRef); 
     event.shape.animationLayerRef.draw(); 
     event.shape.mainLayerRef.draw(); 
    }); 

    return { 
     seat: seat, 
    } 
} 

和代码呈现在画布上:

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title></title> 
    <script type="text/javascript" src="scripts/jquery-1.8.0.js"></script> 
    <script type="text/javascript" src="scripts/kinetic-v3.10.5.min.js"></script> 
    <script type="text/javascript" src="scripts/local/seatMapKineticExtender.js"></script> 
    <!--<script type="text/javascript" src="scripts/local/app.js"></script>--> 
    <script> 
     $(function() { 
      var map = new seatMap.Map({ 
       container: 'stage', 
       width: 1000, 
       height: 420 
      }); 

      for (var i = 0; i < 800; i += 30) { 
       for (var j = 0; j < 500; j+=30) { 
        var seat = new seatMap.Seat({ 
         seatType: seatMap.seatTypes.business, 
         x: i, 
         y: j 
        }); 
        map.addSeat(seat); 
       } 
      } 
      //var seat = new seatMap.Seat({ 
      // seatType: seatMap.seatTypes.business, 
      // x: 200, 
      // y: 200 
      //}); 

      //map.addSeat(seat); 
      map.refresh(); 
     }); 
    </script> 
</head> 
<body> 
    <div id="stage" style="width: 1000px; height: 420px; margin: 0 auto; border: 1px solid black; position: relative"> 
     <div style="position: absolute; top: 0; z-index: 1000"> 
      <button id="zoomIn" type="button">Zoom In</button> 
      <button id="zoomOut" type="button">Zoom Out</button> 
     </div> 

    </div> 
</body> 
</html> 

我觉得我在这里做了一些非常错误的事情,但不幸的是我对kineticjs不够熟悉。 任何人都可以指向正确的方向吗?

由于提前, 丹尼

回答

2

好的,这是一个很好的挑战。我认为问题出在塑造事件上,但是改善的程度却很小。

KineticJS中的事件通过搜索模型的坐标,直到匹配当前的鼠标坐标,应用于特定的屏幕形状。所以通过只有一个图层,我们增加了要搜索的数组的大小。

修复是使用很多层。我为每一行添加了一个图层。

一些在下面的代码中的其他变化是:

  1. 不要层之间移动的形状。它会导致数组拼接和索引移位。
  2. 使用相对的move(x,y)方法代替setX() setY()方法进行小班制。
  3. 您在教程中阅读的动画层概念用于在定时帧间隔上进行实际动画。我们只是在一个事件上进行正常的移动。
  4. 小JS改进;当返回一个对象来隐藏私有数据和方法时,不要使用new来创建一个对象。

<script> 
    $(function() { 
     var map = seatMap.Map({ 
      container: 'stage', 
      width: 1000, 
      height: 420 
     }); 

     for (var i = 0; i < 800; i += 30) { 
      var layer = map.createLayer(); 
      for (var j = 0; j < 500; j+=30) { 
       var seat = seatMap.Seat({ 
        seatType: seatMap.seatTypes.business, 
        x: i, 
        y: j 
       }); 
       map.addSeat(seat, layer); 
      } 
      layer.draw(); 
     } 
     //var seat = new seatMap.Seat({ 
     // seatType: seatMap.seatTypes.business, 
     // x: 200, 
     // y: 200 
     //}); 

     //map.addSeat(seat); 
     map.refresh(); 
    }); 
</script> 

代码

seatMap.Map = function (params) { 
var stage = new Kinetic.Stage({ 
    container: params.container, 
    width: params.width, 
    height: params.height 
}); 

var addSeat = function (object, layer) { 
    object.seat.layer = layer; 
    layer.add(object.seat);  
}; 

var refresh = function() { 
    mainLayer.draw(); 
}; 

var createLayer = function() { 
    var layer = new Kinetic.Layer(); 
    stage.add(layer); 
    return layer; 
}; 
return { 
    createLayer : createLayer, 
    refresh: refresh, 
    addSeat: addSeat 
}; 
} 

seatMap.Seat = function (params) { 

var seatType = params.seatType == null ? seatMap.seatTypes.economy : params.seatType; 

var seat = new Kinetic.Rect({ 
    width: seatType.width, 
    height: seatType.height, 
    x: params.x, 
    y: params.y, 
    fill: seatType.fill, 
    stroke: seatType.stroke, 
    strokewidth: seatType.strokewidth, 
    cornerRadius: seatType.cornerRadius, 
    listening: true 
}); 
seat.staticXPosition = params.x; 
seat.staticYPosition = params.y; 

seat.on('mouseover', function (event) { 
    event.shape.move(-3,-3); 
    event.shape.layer.draw(); 
}); 
seat.on('mouseout', function (event) { 

    event.shape.move(3,3); 
    event.shape.layer.draw(); 
}); 

return { 
    seat: seat, 
}; 
} 
+0

谢谢,其实我已经考虑过这个方案,但认为也许我失去了一些东西,并我可以在一层完成所有这些。此外,我已经改变了动画,现在悬停的形状增长到所有的方向,因此我不必重绘mainLayer,一切工作顺利。再次感谢 – Dimkin

1

绘制500层的形状将这样做。当然,性能还取决于计算机的速度,浏览器(Chrome目前是最快的 - 但显然你需要在所有浏览器上都可以接受的性能)。

查看此link关于性能和改进方法。

4

请检查KineticJS V4.0。0,事件检测引擎被重写和产量瞬时命中检测,即使有形状的数十万:

http://kineticjs.com/