Performance lente avec kineticjs

Désolé si cette question a déjà été posée, j'ai essayé de le trouver par impossible.

J'ai une toile qui devrait éventuellement afficher environ 400 à 500 rectangles de 20 à 30 pixels de hauteur / largeur. Chacun d'entre eux devrait déplacer un pixel vers la gauche et vers le haut sur la souris sur et en arrière sur la souris pour créer un type de comportement sélectionné. Maintenant, mon code fonctionne très bien avec une petite quantité de formes, mais pour 500 d'entre eux, il commence à ralentir de façon spectaculaire. D'un exemple sur Internet, j'ai vu que je peux créer une «couche d'animation» et déplacer l'objet dont je dois animer. Mais, cela nécessite encore de redessiner la couche principale pour supprimer l'élément déplacé de sa position précédente … Voici le code:

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, } } 

Et le code qui rend le canevas:

 <!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> 

Je pense que je fais quelque chose de très mal ici, mais malheureusement, je ne connais pas très bien le kineticjs. Quelqu'un peut-il me diriger vers la bonne direction?

Merci d'avance, Danny

D'accord, c'était un bon défi. Je pensais que le problème était dans les événements de forme, mais l'amélioration était si petite.

Les événements de KineticJS s'appliquent aux formes spécifiques de l'écran en recherchant les coordonnées des modèles jusqu'à ce que l'on correspond aux coordonnées actuelles de la souris. Donc, en n'ayant qu'une seule couche, nous augmentons la taille du tableau à rechercher.

La correction consiste à utiliser de nombreuses couches. J'ai ajouté une couche pour chaque ligne.

Voici quelques-unes des autres modifications dans le code ci-dessous:

  1. Ne déplacez pas les formes entre les couches. Cela provoque une épissure de tableau et un changement d'indice.
  2. Utilisez la méthode de move(x,y) relatif move(x,y) au lieu des setX() setY() pour les petits déplacements.
  3. Le concept de couche d'animation que vous lisez dans un didacticiel est utilisé pour effectuer l'animation réelle sur un intervalle de trame chronométré. Nous ne faisons qu'un mouvement de forme normal sur un événement.
  4. Amélioration mineure de JS; Lorsque vous renvoyez un objet pour cacher des données et des méthodes privées, n'utilisez pas de new pour créer un objet.

Page

 <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> 

Code

 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, }; } 

Vérifiez KineticJS v4.0.0, le moteur de détection d'événement a été réécrit et produit une détection instantanée même s'il existe des centaines de milliers de formes:

http://kineticjs.com/

Dessiner 500 formes va le faire. Bien sûr, les performances dépendront également de la vitesse de l'ordinateur, du navigateur (chrome est actuellement le plus rapide – mais évidemment, vous aurez besoin de performances acceptables sur tous les navigateurs).

Consultez ce lien sur les performances et les moyens de l'améliorer.