6

有没有办法在 Fabric.js 画布上接收右键单击鼠标事件?

以下代码仅适用于左键单击:

canvas.observe('mouse:down', function(){console.log('mouse down'));
4

5 回答 5

15

注意: 上面的大多数答案都已过时;此答案适用于最新的 Fabric 版本 2.7.0


只需为您的 Fabric 画布启用触发右键/中键单击事​​件

在画布中触发右键单击和中键单击事​​件的配置可以在此处fireRightClick找到fireMiddleClick,并且默认设置为false。这意味着默认情况下禁用右键和中键单击事​​件。右键单击时停止上下文菜单显示在画布上的参数stopContextMenu可以在这里找到

您可以通过在创建画布时设置值来启用这些:

var canvas = new fabric.Canvas('canvas', {
  height: height,
  width: width,
  fireRightClick: true,  // <-- enable firing of right click events
  fireMiddleClick: true, // <-- enable firing of middle click events
  stopContextMenu: true, // <--  prevent context menu from showing
});

现在您的mousedown事件将为所有点击触发,您可以使用事件上的按钮标识符来区分它们:

对于画布:

canvas.on('mouse:down', (event) => {
    if(event.button === 1) {
        console.log("left click");
    }
    if(event.button === 2) {
        console.log("middle click");
    }
    if(event.button === 3) {
        console.log("right click");
    }
}

对于对象:

object.on('mousedown', (event) => {
    if(event.button === 1) {
        console.log("left click");
    }
    if(event.button === 2) {
        console.log("middle click");
    }
    if(event.button === 3) {
        console.log("right click");
    }
}

单击对象时,您可以通过 event.e 到达“真正的”鼠标 dom 事件:

if(event.button === 3){
  console.log(event.e);
}
于 2019-04-10T13:42:43.197 回答
4

我通过扩展 fabric.Canvas 类实现了右键单击。看看这里_onMouseDown方法。

基本上,默认情况下,fabricjs 中禁用了对象的鼠标右键事件。

于 2014-10-03T05:09:13.727 回答
4

如果要处理右键单击(在画布或其对象上),则在上部画布元素上设置上下文菜单侦听器。使用 canvas 方法 findTarget 您可以检查是否单击了任何目标,如果是,您可以检查目标的类型。

let scope = this;
jQuery(".upper-canvas").on('contextmenu', function (options: any) {
    let target: any = scope.canvas.findTarget(options, false);
    if (target) {
        let type: string = target.type;
        if (type === "group") {
            console.log('right click on group');
        } else {
            scope.canvas.setActiveObject(target);
            console.log('right click on target, type: ' + type);
        }
    } else {
        scope.canvas.discardActiveObject();
        scope.canvas.discardActiveGroup();
        scope.canvas.renderAll();
        console.log('right click on canvas');
    }
    options.preventDefault();
});
于 2017-03-08T09:51:59.083 回答
3

The way I did this was to listen for a right click event across the entire canvas and match up the x,y coordinates of the click event to the object which is currently sitting at the given location. This solution feels a little like a hack but hey, it works!

$('#my_canvas').bind('contextmenu', function (env) {
    var x = env.offsetX;
    var y = env.offsetY;
    $.each (canvas._objects, function(i, e) {
        // e.left and e.top are the middle of the object use some "math" to find the outer edges
        var d = e.width / 2;
        var h = e.height / 2;
        if (x >= (e.left - d) && x <= (e.left+d)) {
            if(y >= (e.top - h) && y <= (e.top+h)) {
                console.log("clicked canvas obj #"+i);
                //TODO show custom menu at x, y
                return false; //in case the icons are stacked only take action on one.
            }
        }
    });
    return false; //stops the event propigation
});
于 2012-12-04T04:52:08.090 回答
2

这是我所做的,它使用了一些内置的织物对象检测代码:

$('.upper-canvas').bind('contextmenu', function (e) {
    var objectFound = false;
    var clickPoint = new fabric.Point(e.offsetX, e.offsetY);

    e.preventDefault();

    canvas.forEachObject(function (obj) {
        if (!objectFound && obj.containsPoint(clickPoint)) {
            objectFound = true;
            //TODO: whatever you want with the object
        }
    });
});
于 2016-01-06T21:22:06.230 回答