Javascript Fabric.js鼠标右键单击

Javascript Fabric.js鼠标右键单击,javascript,canvas,fabricjs,Javascript,Canvas,Fabricjs,是否有方法在Fabric.js画布上接收鼠标右键单击事件 以下代码仅适用于左键单击: canvas.observe('mouse:down', function(){console.log('mouse down')); 我这样做的方式是在整个画布上侦听右键单击事件,并将单击事件的x、y坐标与当前位于给定位置的对象相匹配。这个解决方案感觉有点像黑客,但嘿,它是有效的 $('#my_canvas').bind('contextmenu', function (env) { var x =

是否有方法在Fabric.js画布上接收鼠标右键单击事件

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

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

我这样做的方式是在整个画布上侦听右键单击事件,并将单击事件的x、y坐标与当前位于给定位置的对象相匹配。这个解决方案感觉有点像黑客,但嘿,它是有效的

$('#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
});
$('my#u canvas').bind('contextmenu',function(env){
var x=环境补偿x;
变量y=env.offsetY;
$.each(画布.\u对象、函数(即,e){
//e.left和e.top是对象的中间部分。使用一些“数学”来查找外部边缘
var d=e.宽度/2;
var h=e.高度/2;

如果(x>=(e.left-d)和&x=(e.top-h)和&y我已经通过扩展fabric.Canvas类实现了右键单击。请查看
\onMouseDown
方法


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

下面是我所做的,它使用了一些内置的fabric对象检测代码:

$('.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
        }
    });
});

若要处理右键单击(在画布或其对象上),请在上部画布元素上设置上下文菜单侦听器。使用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();
});
注意:以上大多数答案都已过时;此答案适用于最新的Fabric版本2.7.0


只需为您的结构画布启用右键/中键单击事件 可以找到画布中触发右键单击和中键单击事件的配置,默认情况下,和设置为
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
});
对于对象:
单击对象时,您可以通过event.e:

if(event.button === 3){
  console.log(event.e);
}

只需观察画布上的单击事件(不是通过fabric,而是使用DOM方法),然后检查它是右键单击而不是左键单击。对于最新版本(在fabric 2.7.0中测试)您只需在画布配置中启用这些事件即可。请参阅@jsbeckr它的工作原理是找到与这些坐标匹配的第一个画布对象,然后停止。您可以变得更聪明,在该x/y位置建立一个对象列表,然后选择其中一个对象进行操作(例如,z索引最高的对象?)是的,我这样做了。我意识到你的解决方案不考虑缩放对象……但是很容易修复:<代码> var d=E.Wux*E.ScCuEX/2;<代码> >和代码> var H.E.Health*E.ScCuy/2; @ jsBekr。旋转对象是什么?你也设法解决了吗?@ BR691抱歉,我没有。需要。:/hi!由于某些原因,当单击画布上的返回时,菜单不会消失。有什么想法吗?您的答案当然值得一点解释。请参考。非常棒,稍作修改,删除
discardActiveGroup
,并删除“group”和“aciveSelection”之间的类型区别.您好,这很好,但我仍然不明白。如果我在您的库中使用此扩展的_onMouseDown事件,右键单击会发生什么情况。问题上下文中需要的行为是-如果我们有上下文菜单插件,我们希望覆盖此.canvas.on('mouse:down',(e)=>someFunc(e))上的默认行为;并从插件中触发函数以显示上下文菜单。同时,右键单击时,默认浏览器上下文菜单不应出现。这应该是插件本身的责任,但只是想知道除了FabricJS之外,我们是否还应该做其他事情。我个人使用angular 6和$(“#我的画布”).bind('contextmenu'))不适合我。我更喜欢以typescript(OOP)方式“干净地”扩展事件和对象。阻止上下文菜单不适合我。我缺少什么?IE和Chrome都在画布上右键单击显示上下文菜单(控制台日志工作正常)。@ps0604您确定要对DOM事件调用
preventDefault()
event.e
)。您可以通过将DOM事件记录到控制台来仔细检查哪个对象是DOM事件。preventDefault对我也不起作用。使用event.e.preventDefault会给出“无法读取未定义的属性'preventDefault'将'element'打印到日志显示它是一个MouseEvent。打印'element.e'显示未定义。因此我将您的代码更改为event.preventDefault();但仍会出现弹出窗口。我缺少什么?如果您在控制台中收到该错误消息并输出,则表示事件变量是DOM事件。如果同时添加
event.preventDefault();event.stopPropagation()会发生什么情况
我将尝试一次。您使用的是canvas.js的哪个版本?这是一个显示结果的提琴。我还必须对按钮重新编号以确保正确。我一直在使用2.4.6,但在看到这篇文章时切换到了2.7.0。这两个版本都导致了相同的操作:
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");
    }
}
if(event.button === 3){
  console.log(event.e);
}