返回 导航

其他

hangge.com

Fabric.js - 添加鼠标右键点击事件响应(附:右键菜单)

作者:hangge | 2017-11-17 08:10
Fabric.js Canvas 有个 mouse:down 事件,通过它我们可以监听到鼠标按下的行为。不过该事件只对鼠标左键其作用,如果是右键按下则不会触发该事件。
Canvas 上又无法直接监听 contextmenu 事件,所以想要实现右键点击响应就需要换种方式实现。

1,实现原理

  • Fabric.jsCanvas 初始化完毕后,会自动在其上方覆盖一个 class 名为 upper-canvas canvas
  • 我们可以在上层这个 canvas 上添加 contextmenu 事件监听。当右键按下时会触发该事件,然后将点击的坐标转换成底下实际的 canvas 里的坐标(坐标需要转换是因为下面 canvas 可能会被移动,缩放)。

2,效果图

  • 默认情况下,鼠标左键点击对象即可选择中该对象。
  • 这里增加个右键选中功能,即通过右键同样可以选中对象。

3,样例代码

<!DOCTYPE html>
<html>
<head>
<style>
    canvas {
        border: 1px dashed black;
    }
</style>
<script src="fabric.js"></script>
<script src="jquery-3.1.1.js"></script>
<script>
  var canvas;

  window.onload = function() {
    canvas = new fabric.Canvas('canvas');

    var rect1 = new fabric.Rect({top: 50, left: 50, width: 70, height: 70, fill: 'red'});
    canvas.add(rect1);
    var rect2 = new fabric.Rect({top: 50, left: 150, width: 70, height: 70, fill: 'red'});
    canvas.add(rect2);
    var rect3 = new fabric.Rect({top: 50, left: 250, width: 70, height: 70, fill: 'red'});
    canvas.add(rect3);

    //在canvas上层对象上添加右键事件监听
    $(".upper-canvas").contextmenu(onContextmenu);
  }

  //右键点击事件响应
  var onContextmenu = function(event) {
    var pointer = canvas.getPointer(event.originalEvent);
    var objects = canvas.getObjects();
    for (var i = objects.length - 1; i >= 0; i--) {
      var object = objects[i];
       //判断该对象是否在鼠标点击处
       if (canvas.containsPoint(event, object)) {
         //选中该对象
         canvas.setActiveObject(object);
       }
    }

    //阻止系统右键菜单
    event.preventDefault();
    return false;
  }
</script>
</head>
<body>
    <canvas id="canvas" width="450" height="200"></canvas>
</body>
</html>

附:添加一个自定义的右键菜单

1,实现原理


2,效果图

(1)当鼠标在对像上按下右键时,会出现个菜单。

(2)点击菜单里的“删除”项,即可将对象删除。

3,样例代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
    canvas {
        border: 1px dashed black;
    }
</style>
<script src="fabric.js"></script>
<script src="jquery-3.1.1.js"></script>
<script src="contextMenu/jquery.ui.position.min.js" type="text/javascript"></script>
<script src="contextMenu/jquery.contextMenu.js" type="text/javascript"></script>
<link href="contextMenu/jquery.contextMenu.css" rel="stylesheet" type="text/css" />
<script>
  var canvas;
  //菜单项
  var contextMenuItems;

  window.onload = function() {
    canvas = new fabric.Canvas('canvas');

    var rect1 = new fabric.Rect({top: 50, left: 50, width: 70, height: 70, fill: 'red'});
    canvas.add(rect1);
    var rect2 = new fabric.Rect({top: 50, left: 150, width: 70, height: 70, fill: 'red'});
    canvas.add(rect2);
    var rect3 = new fabric.Rect({top: 50, left: 250, width: 70, height: 70, fill: 'red'});
    canvas.add(rect3);

    //在canvas上层对象上添加右键事件监听
    $(".upper-canvas").contextmenu(onContextmenu);

    //初始化右键菜单
    $.contextMenu({
          selector: '#contextmenu-output',
          trigger: 'none',
          build: function($trigger, e) {
              //构建菜单项build方法在每次右键点击会执行
              return {
                  callback: contextMenuClick,
                  items: contextMenuItems
              };
          },
      });
  }

  //右键点击事件响应
  function onContextmenu(event) {
    var pointer = canvas.getPointer(event.originalEvent);
    var objects = canvas.getObjects();
    for (var i = objects.length - 1; i >= 0; i--) {
      var object = objects[i];
       //判断该对象是否在鼠标点击处
       if (canvas.containsPoint(event, object)) {
         //选中该对象
         canvas.setActiveObject(object);
         //显示菜单
         showContextMenu(event, object);
         continue;
       }
    }

    //阻止系统右键菜单
    event.preventDefault();
    return false;
  }

  //右键菜单项点击
  function showContextMenu(event, object) {
    //定义右键菜单项
    contextMenuItems = {
       "delete": {name: "删除", icon: "delete", data: object},
    };
    //右键菜单显示位置
    var position = {
        x: event.clientX,
        y: event.clientY
    }
    $('#contextmenu-output').contextMenu(position);
  }

  //右键菜单项点击
  function contextMenuClick(key, options) {
    if(key == "delete") {
      //得到对应的object并删除
      var object = contextMenuItems[key].data;
      canvas.remove(object);
    }
  }
</script>
</head>
<body>
    <canvas id="canvas" width="450" height="200"></canvas>
    <div id="contextmenu-output"></div>
</body>
</html>
评论

全部评论(0)

回到顶部