简体   繁体   中英

Fabric JS using mouse:over on an animating object

I can animate an object and then add a mouse:over event.

 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>

However the mouse:over event continues to fire from the rectangle's original position. Once the animate finishes then the mouse:over event works again over the animated object.

Is it possible to have a mouse:over event fire while an object is moving/animating?

I wasn't able to figure out a built-in way. You might want to submit this as an issue. In the meantime, I think I have a usable workaround:

 // 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(), oe); // 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>

Essentially, I listen for mouse:move . On each mouse move, I get the cursor coordinates and check to see if it's inside the shape.

Right now, it's hard-coded to only work on Rect s, but perhaps you could introduce a function like isInside(object, pos) which returns a boolean , and in there you can check what type object is and decide based on that.

i realise this topic is very old, but i've just run into the same issue.

after a bit of fiddling, it turned out that calling setCoords() after the object has moved will update the internal state so that mouseover works again correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM