织物.js - 在不按住鼠标按钮的情况下移动对象

Fabric.js - Move object without holding mouse button

本文关键字:按钮 情况下 移动 对象 鼠标 js 织物      更新时间:2023-09-26

在Fabric中.js可以通过左键单击,按住和移动鼠标在画布中移动对象。在这种情况下,所选对象跟随鼠标的光标并触发object:moving。释放鼠标左键将退出此模式。

有没有办法更改此行为并让对象使用不同的事件进入此模式?例如,单击一次以使对象跟随光标(并正确触发object:moving),然后单击第二次以使对象释放到其最终位置?

我希望避免从头开始编写这个听"鼠标移动"事件,因为这已经实现,但只有进入/存在此模式的触发器必须更改。

通过 Fabric.js 代码,将对象标记为要移动的位置在调用 canvas._setupCurrentTransform(e, target)canvas.__on_mouse_down(e)中(仅使用此方法的位置)。这将构造一个对象并将其分配给canvas._currentTransform 。反过来,此对象在canvas.__onMouseMove(e)中使用,以使用 canvas._transformObject(e) 实际移动所选对象。

问题是canvas.__onMouseUp(e)调用canvas._finalizeCurrentTransform(),所以拖动停止到此。幸运的是,它还会在之后立即触发"mouse:up"。所以我们可以在回调中覆盖它:

var mydragging = false;
canvas.on('mouse:up', function(o) {
  if (mydragging) {
    mydragging = false;
    canvas.currentTransform = null;
  }
  else {
    canvas._setupCurrentTransform(o.e, o.target);
    mydragging = true;
  }
});

这使canvas处于与按住鼠标按钮拖动时完全相同的状态(在引入此代码之前),因此所有内置行为都保持不变,包括触发"object:moving"。

不幸的是,canvas._currentTransformcanvas._setupCurrentTransform被标记为私有,不能依赖。也许他们愿意公开它。

我通过有一个名为 movedObject 的变量来实现这一点,如果没有移动对象,该变量null,如果移动对象,则包含一个对象。如果在移动对象时单击,则会将movedObject设置为 null 。如果您在不移动对象时单击,则当您单击一个对象,它会movedObject设置为对象。

我在mouse:move中添加了一个侦听器,如果movedObjectnull,则leftmovedObjecttop设置为鼠标xy(减去 movedObject widthheight/2)。

JSFiddle

法典:

var canvas = new fabric.Canvas('canvas');
canvas.setWidth(300);
canvas.setHeight(300);
var circle = new fabric.Circle({
  radius: 30,
  fill: '#f55',
  top: 100,
  left: 100
});
canvas.add(circle);
circle.hasControls = circle.hasBorders = circle.selectable = false;
var movedObject = null;
canvas.on({
  'mouse:down': function(e) {
    //If an object is selected already it'll be unselected
    if (movedObject !== null) {
        movedObject = null;
    } else {
      //If no object was selected and a click occured on an object it'll now be selected
      if (e.target) {
         movedObject = e.target;
      }
    }
  },
  'mouse:move': function(e) {
    //Moving the object along with mouse cursor
    if (movedObject !== null) {
        movedObject.left = (e.e.clientX - movedObject.width / 2);
        movedObject.top = (e.e.clientY - movedObject.height / 2);
        movedObject.setCoords();
        canvas.renderAll();
    }
  }
});