【问题标题】:Fabric JS using mouse:over on an animating objectFabric JS 使用鼠标:在动画对象上
【发布时间】:2016-11-23 00:40:27
【问题描述】:

我可以为对象设置动画,然后添加mouse:over 事件。

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>

但是,mouse:over 事件会继续从矩形的原始位置触发。动画完成后,mouse:over 事件将再次作用于动画对象。

是否可以在对象移动/动画时触发 mouse:over 事件?

【问题讨论】:

    标签: javascript animation fabricjs mouseover


    【解决方案1】:

    我无法找到一种内置方式。您可能希望将此作为问题提交。同时,我认为我有一个可用的解决方法:

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

    基本上,我听的是mouse:move。在每次鼠标移动时,我都会获取光标坐标并检查它是否在形状内。

    现在,硬编码只能在 Rects 上工作,但也许你可以引入像 isInside(object, pos) 这样返回 boolean 的函数,在那里你可以检查 object 是什么类型和以此来决定。

    【讨论】:

    • 谢谢弗兰克。但是,哎呀,这可能会因为更多的对象而变得密集?
    • @JakeN 很可能就是这样。这是我能想到的最好的解决方法。希望其他人可以提出更好的建议,或者如果您报告问题,他们可能会做出回应。
    【解决方案2】:

    我意识到这个话题很老了,但我刚刚遇到了同样的问题。

    经过一番折腾,发现在对象移动后调用setCoords() 会更新内部状态,以便mouseover 再次正常工作。

    【讨论】:

      猜你喜欢
      • 2017-06-20
      • 2020-01-13
      • 2015-03-26
      • 1970-01-01
      • 2016-03-04
      • 2016-07-07
      • 2015-09-22
      • 2017-08-16
      • 1970-01-01
      相关资源
      最近更新 更多