2016-07-19 10 views
2

Ich kann ein Objekt animieren und dann ein mouse:over Ereignis hinzufügen.Fabric JS mit der Maus: über ein animierendes Objekt

var canvas = new fabric.Canvas('c'); 
 
var x1 = 5; 
 
var y1 = 5; 
 
var x2 = 100; 
 
var y2 = 100; 
 

 
var rect = new fabric.Rect({ 
 
    width: 10, 
 
    height: 10, 
 
    left: x1, 
 
    top: y1, 
 
    stroke: '#000', 
 
    strokeWidth: 2, 
 
    fill: '#faa', 
 
    selectable: false 
 
}); 
 
canvas.add(rect); 
 

 
rect.animate({ 
 
    'left': x2, 
 
    'top': y2 
 
}, { 
 
    duration: 10000, 
 
    onChange: canvas.renderAll.bind(canvas), 
 
    onComplete: function() { 
 
    } 
 
}); 
 

 
canvas.on('mouse:over', function (e) { 
 
    console.log('mouseover'); 
 
});
<canvas id="c"></canvas> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.min.js"></script>

jedoch das mouse:over Ereignis aus dem Rechteck ursprünglichen Position schießen weiter. Sobald die Animation beendet ist, arbeitet das Ereignis mouse:over erneut über dem animierten Objekt.

Kann ein Ereignis mouse:over ausgelöst werden, während sich ein Objekt bewegt/animiert?

Antwort

1

Ich war nicht in der Lage, einen eingebauten Weg herauszufinden. Möglicherweise möchten Sie dies als Problem einreichen. In der Zwischenzeit, ich glaube, ich habe eine brauchbare Abhilfe:

// Setup 
 

 
var canvas = new fabric.Canvas('c'); 
 
var x1 = 5; 
 
var y1 = 5; 
 
var x2 = 100; 
 
var y2 = 100; 
 
var rectWidth = 10; 
 
var rectHeight = 10; 
 

 
var rect = new fabric.Rect({ 
 
    width: rectWidth, 
 
    height: rectHeight, 
 
    left: x1, 
 
    top: y1, 
 
    stroke: '#000', 
 
    strokeWidth: 2, 
 
    fill: '#faa', 
 
    selectable: false 
 
}); 
 
canvas.add(rect); 
 

 
rect.animate({ 
 
    'left': x2, 
 
    'top': y2 
 
}, { 
 
    duration: 10000, 
 
    onChange: canvas.renderAll.bind(canvas), 
 
    onComplete: function() { 
 
    } 
 
}); 
 

 
// http://stackoverflow.com/questions/17130395/real-mouse-position-in-canvas 
 
function getMousePos(canvas, evt) { 
 
    var rect = canvas.getBoundingClientRect(), // abs. size of element 
 
     scaleX = canvas.width/rect.width, // relationship bitmap vs. element for X 
 
     scaleY = canvas.height/rect.height; // relationship bitmap vs. element for Y 
 

 
    return { 
 
    x: (evt.clientX - rect.left) * scaleX, // scale mouse coordinates after they have 
 
    y: (evt.clientY - rect.top) * scaleY  // been adjusted to be relative to element 
 
    } 
 
} 
 

 
// The important stuff 
 

 
canvas.on('mouse:move', function (o) { 
 
    var pos = getMousePos(canvas.getElement(), o.e); 
 
    // Do math to figure out if the mouse move was inside the the object. For a Rect: 
 
    if (
 
    pos.x >= rect.left && 
 
    pos.x <= rect.left + rectWidth && 
 
    pos.y >= rect.top && 
 
    pos.y <= rect.top + rectHeight 
 
) { 
 
    console.log('mouseover'); 
 
    } 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.min.js"></script> 
 
<canvas id="c"></canvas>

Wesentlichen hören, die ich für mouse:move. Bei jeder Mausbewegung erhalte ich die Cursorkoordinaten und überprüfe, ob es sich innerhalb der Form befindet.

Gerade jetzt, es ist hart codiert, um nur die Arbeit an Rect s, aber vielleicht könnten Sie eine Funktion wie isInside(object, pos) einführen, die eine boolean zurückkehrt und dort können Sie überprüfen, welche Art object ist und entscheidet auf dieser Grundlage.

+0

Danke Frank. Aber autsch, das könnte mit mehr Objekten intensiv werden? –

+0

@JakeN Das kann sehr wohl der Fall sein. Das ist die beste Problemumgehung, die ich mir vorstellen kann. Hoffentlich kann jemand anderes etwas besser vorschlagen, oder vielleicht werden sie antworten, wenn Sie ein Problem melden. –