Ne rendez pas dans IO EVENTS !
Bien qu'il ne s'agisse pas d'une solution complète au problème de la vitesse de mise à jour, cette réponse permettra de doubler la vitesse d'interaction.
Une erreur courante, presque standard, commise avec l'interaction de la souris et des événements avec le canevas (et le DOM) est de déléguer le rendu aux événements de la souris/du toucher. Il s'agit d'une très mauvaise pratique, car les événements de la souris se déclenchent à une vitesse bien supérieure à celle que l'écran peut afficher. C'est encore pire lorsque le temps de rendu est élevé, car vous mettez en file d'attente les événements de la souris (pseudo-événements de rendu) et effectuez un nouveau rendu à chaque mouvement de la souris.
Note Le code de blocage arrêtera les événements de la souris mais dès que le moteur sera au ralenti, la souris recommencera à tirer à plein régime.
Utilisez les événements de la souris juste pour obtenir l'état de la souris. Utilisez une boucle d'animation synchronisée avec l'affichage pour effectuer le rendu uniquement lorsque cela est nécessaire et qu'il y a du temps disponible. Les éléments tels que la roue et les deltas de mouvement de la souris doivent être enregistrés de manière cumulative.
mouse.dx += event.movementX;
mouse.dy += event.movementY;
mouse.wheel += event.wheelDelta;
Et les consommer dans la boucle de rendu principale...
function update(){
// ... code to use mouse
// consume deltas
mouse.x = mouse.y = mouse.wheel = 0;
...cela permet de s'assurer que l'état de la souris est suivi avec précision lorsque vous pouvez avoir de nombreux événements de souris entre les mises à jour du rendu.
Exemple, séparer les événements du rendu.
Changez votre code dans le fiddle que vous avez fourni par le suivant, sur ma machine cela a doublé la vitesse de rendu (qui est toujours très lente).
// from just after the function applyZoom replace all the code
var mouse = { // holds the mouse state
x : 0,
y : 0,
down : false,
w : 0,
delta : new fabric.Point(0,0),
}
// event just track mouse state
function zoom(e) {
if(e != null) { e.preventDefault() }
var evt=window.event || e;
mouse.x = e.offsetX;
mouse.y = e.offsetY;
mouse.w += evt.detail? evt.detail*(-120) : evt.wheelDelta;
return false;
}
canvas.on('mouse:up', function (e) { mouse.down = false });
canvas.on('mouse:out', function (e) { mouse.down = false });
canvas.on('mouse:down', function (e) { mouse.down = true });
canvas.on('mouse:move', function(e) {
if (e && e.e) {
mouse.delta.x += e.e.movementX;
mouse.delta.y += e.e.movementY;
}
});
// main animation loop
function update(){
if(mouse.w !== 0){ // if the wheel has moved do zoom
var curZoom = canvas.getZoom();
canvas.zoomToPoint(
{ x : mouse.x, y: mouse.y },
canvas.getZoom() + mouse.w / 4000
);
mouse.w = 0; // consume wheel delta
}else if(mouse.down) { // if mouse button down
canvas.relativePan(mouse.delta);
}
// consume mouse delta
mouse.delta.x = 0;
mouse.delta.y = 0;
requestAnimationFrame(update);
}
requestAnimationFrame(update);