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:
move(x,y)
relatif move(x,y)
au lieu des setX() setY()
pour les petits déplacements. 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:
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.