基于fabricjs的标注工具搭建

784 阅读2分钟

这几个月做了标注工具的项目,之前没有对canvas任何使用,网上对fabricjs的框架呼声很高,所以本文大致总结下项目中遇到的问题。技术栈 vue3 + vite

1.如何让canvas自适应

 <div id="canvas-box">
  <canvas :id="'canvas' + randomNumber" style="display: block; width: 100%; height: 100%"></canvas>
 </div>

让cavas-box为flex布局,每次页面加载时,先获得div的宽高,在将canvas的宽高

      canvasBox = document.getElementById('canvas-box')
      canvasSize.canvasWidth = canvasBox.clientWidth || canvasBox.offsetWidth
      canvasSize.canvasHeight = canvasBox.clientHeight || canvasBox.offsetHeight
      document.getElementById('canvas' + randomNumber.value).width = canvasSize.canvasWidth
      document.getElementById('canvas' + randomNumber.value).height =canvasSize.canvasHeight

这里我给canvas加了随机数 是因为,在生产环境将fabric封装成组件 进行切换时候 页面刷新初次没有问题,但是多次下fabric会出现少绘制一层canvas,我在官网提了issuse,但是一直没时间解决,加了随机数就好,可能是vue认为这两个dom一样吧。而在开发环境一切正常,如果你也是封装组件动态打开的话,可以留意一下这个问题。

2.如何画布放大

//监听鼠标滚轮事件
  const canvasMouseWheel = (opt) => {
    const delta = opt.e.deltaY // 滚轮,向上滚一下是 -100,向下滚一下是 100
    let zoom = canvas.getZoom() // 获取画布当前缩放值
    zoom *= 0.999 ** delta
    if (zoom > 20) zoom = 20
    if (zoom < 0.01) zoom = 0.01
    canvas.zoomToPoint(
      {
        x: opt.e.offsetX,
        y: opt.e.offsetY
      },
      zoom
    )
    opt.e.preventDefault()
    opt.e.stopPropagation()
  }

3.如何画布拖拽

//监听鼠标按下事件
  const canvasMouseDown = (e) => {
  //这里spaceKeyState.value指的是空格键
    if (spaceKeyState.value) {
      canvas.discardActiveObject().renderAll()
      canvas.isDragging = true
      canvas.lastPosX = e.e.clientX
      canvas.lastPosY = e.e.clientY
      canvas.selection = false // 移动时不出现框选样式
    }
  }

4.如何往画布画矩形 可以利用fabric.rect,这种方法最省事,不用考虑坐标偏移,放大放小问题(之前用path坑的好惨) 很简单

const rect = new fabric.Rect({
          top: 距离画布顶,
          left: 距离画布左面,
          width: 矩形宽 
          height: 矩形高
          fill: 颜色,
        })
        // 将矩形添加到画布上
        canvas.add(rect)
        
   //canvas.getPointer(e) 获取鼠标按下和松开的坐标 知道矩形大小    

5.限制矩形在图像内画 这个也很简单 在绘制结束的时候判断图像的四个点是否在图像内,取canva背景图的最大值,让背景图的left和top等于绘制矩形的,让绘制矩形的宽高<let+自身的高

未完待续。。。