# 对象

  • fabric.Circle 圆
  • fabric.Ellipse 椭圆
  • fabric.Line 直线
  • fabric.Polygon 多边形
  • fabric.Polyline 线
  • fabric.Rect 矩形
  • fabric.Triangle 三角形

# 方法

  • add(object) 添加
  • insertAt(object,index) 添加
  • remove(object) 移除
  • forEachObject 循环遍历
  • getObjects() 获取所有对象
  • item(int) 获取子项
  • isEmpty() 判断是否空画板
  • size() 画板元素个数
  • contains(object) 查询是否包含某个元素
  • fabric.util.cos
  • fabric.util.sin
  • fabric.util.drawDashedLine 绘制虚线
  • getWidth() setWidth()
  • getHeight()
  • clear() 清空
  • renderAll() 重绘
  • requestRenderAll() 请求重新渲染
  • rendercanvas() 重绘画板
  • getCenter().top/left 获取中心坐标
  • toDatalessJSON() 画板信息序列化成最小的json
  • toJSON() 画板信息序列化成json
  • moveTo(object,index) 移动
  • dispose() 释放
  • setCursor() 设置手势图标
  • getSelectionContext()获取选中的context
  • getSelectionElement()获取选中的元素
  • getActiveObject() 获取选中的对象
  • getActiveObjects() 获取选中的多个对象
  • discardActiveObject()取消当前选中对象
  • isType() 图片的类型
  • setColor(color) = canvas.set("full","");
  • rotate() 设置旋转角度
  • setCoords() 设置坐标

# 事件

  • object:added
  • object:removed
  • object:modified
  • object:rotating
  • object:scaling
  • object:moving
  • object:selected 这个方法v2已经废弃,使用selection:created替代,多选不会触发
  • before:selection:cleared
  • selection:cleared
  • selection:updated
  • selection:created
  • path:created
  • mouse:down
  • mouse:move
  • mouse:up
  • mouse:over
  • mouse:out
  • mouse:dblclick

# 常用属性

  • canvas.isDrawingMode = true; 可以自由绘制
  • canvas.selectable = false; 控件不能被选择,不会被操作
  • canvas.selection = true; 画板显示选中
  • canvas.skipTargetFind = true; 整个画板元素不能被选中
  • canvas.freeDrawingBrush.color = "#E34F51" 设置自由绘画笔的颜色
  • freeDrawingBrush.width 自由绘笔触宽度
  • canvas.setZoom(2); 设置画板缩放比例

# IText的方法

  • selectAll() 选择全部
  • getSelectedText() 获取选中的文本
  • exitEditing() 退出编辑模式

# 绘制直线

var line = new fabric.Line([10, 10, 100, 100], {
fill: 'green',
stroke: 'green', //笔触颜色
strokeWidth: 2,//笔触宽度
});
canvas.add(line);

# 绘制虚线

var line = new fabric.Line([10, 10, 100, 100], {
fill: 'green',
stroke: 'green',
strokeDashArray:[3,1] 
});
canvas.add(line);

//strokeDashArray[a,b] =》 每隔a个像素空b个像素。

# 绘制矩形

var rect = new fabric.Rect({
   left:100,//距离画布左侧的距离,单位是像素
   top:100,//距离画布上边的距离
   fill:'red',//填充的颜色
   width:30,//方形的宽度
  height:30//方形的高度
});
canvas.add(rect);

# 图片操作

  • oImg.hasControls = false; 只能移动不能(编辑)操作
  • oImg.hasBorders = false; 去掉边框,可以正常操作
  • hasRotatingPoint = false; 不能被旋转
  • hasRotatingPoint 控制旋转点不可见
  • scaleToHeight(value, absolute) 缩放图片高度到value scaleToWidth(value, absolute) 缩放图片宽度到value
fabric.Image.fromURL("img.jpg", function (oImg) {
    img.scaleToHeight(400, false);  //缩放图片的高度到400
    img.scaleToWidth(400, false);   //缩放图片的宽度到400
    canvas.add(oImg);
    oImg.hasControls = oImg.hasBorders = false;
});

# 右键菜单

# 实现原理

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

# 实现步骤

  • 默认情况下,鼠标左键点击对象即可选择中该对象。这里增加个右键选中功能,即通过右键同样可以选中对象
  • Fabric.js 的 Canvas 有个 mouse:down 事件,通过它我们可以监听到鼠标按下的行为。不过该事件只对鼠标左键其作用,如果是右键按下则不会触发该事件。 而 Canvas 上又无法直接监听 contextmenu 事件,所以想要实现右键点击响应就需要换种方式实现

这里我们使用一个专门的第三方菜单组件(contextMenu)来实现,在上面的右键点击响应中将菜单弹出即可。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        canvas {
            border: 1px dashed black;
        }
    </style>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.contextMenu.min.css">
    <script src="https://cdn.bootcss.com/fabric.js/4.0.0-beta.5/fabric.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.contextMenu.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.ui.position.js"></script>
    <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 },
                "add": { name: "新增", icon: "add", 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);
            }else if(key = "add"){
                var rect3 = new fabric.Rect({ top: 50, left: 350, width: 70, height: 70, fill: 'red' });
                canvas.add(rect3);
                canvas.renderAll();
            }
        }
    </script>
</head>

<body>
    <canvas id="canvas" width="450" height="200"></canvas>
    <div id="contextmenu-output"></div>
</body>

</html>

# vue中的使用

  • 引入 fabric.js
npm install fabric --save
  • main.js 导入
import { fabric } from 'fabric'
Vue.use(fabric);
  • vue 页面实现
<template>
  <div>
    <div class="manager_detail">
      <canvas id="canvas" width="1720" height="1050"></canvas>
    </div>
  </div>
</template>
<script>
export default {
  components: {
  },
  watch: {},
  data() {
    return {
      panning: false
    };
  },
  methods: {
    initCanvas() {
      // 1. 实例化canvas 画布
      var canvas = new fabric.Canvas("canvas");
      // 2. 设置背景图片作为底图(这里导入图片使用require,不要 使用 '../../' 方式)
      // canvas.width / 4764  (4764 是我底图图片宽度)
      // canvas.height / 3367 (3367 是我底图图片宽度)
      canvas.setBackgroundImage(
        require("../../assets/images/map.png"),
        canvas.renderAll.bind(canvas),
        {
          scaleX: canvas.width / 4764,
          scaleY: canvas.height / 3367
        }
      );

      //鼠标按下事件
      canvas.on("mouse:down", function(e) {
        this.panning = true;
        canvas.selection = false;
      });
      //鼠标抬起事件
      canvas.on("mouse:up", function(e) {
        this.panning = false;
        canvas.selection = true;
      });
      // 移动画布事件
      canvas.on("mouse:move", function(e) {
        if (this.panning && e && e.e) {
          var delta = new fabric.Point(e.e.movementX, e.e.movementY);
          canvas.relativePan(delta);
        }
      });
      // 鼠标滚动画布放大缩小
      canvas.on("mouse:wheel", function(e) {
        var zoom = (event.deltaY > 0 ? -0.1 : 0.1) + _that.canvas.getZoom();
        zoom = Math.max(0.1, zoom); //最小为原来的1/10
        zoom = Math.min(3, zoom); //最大是原来的3倍
        var zoomPoint = new fabric.Point(event.pageX, event.pageY);
        _that.canvas.zoomToPoint(zoomPoint, zoom);
      });
    }
  },
  created() {
  },
  mounted() {
    this.initCanvas();
  }
};
</script>
<style scoped>
.manager_detail {
  width: 100%;
  height: calc(100vh - 112px);
  overflow: hidden;
}
</style>

注意

图片使用require,不要 使用 '../../' 方式,否则图片加载不进去