2012-08-22 54 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/