Javascript Fabric.js鼠标右键单击
是否有方法在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 =
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);
}