本文简介

点赞 + 关注 + 珍藏 = 学会了


应用 fabric.js 创立进去的画布默认是不能拖拽挪动的。

不过咱们能够利用一些小技巧让画布具备被拖拽的能力,fabric.js 官网也提供了一个 demo ,但文档上并没有具体的解说拖拽画布的实现原理。

本文就粗略剖析一下这个原理。



原理解析

鼠标拖拽的原理其实很简略,次要就3步:

  1. 鼠标点击元素
  2. 挪动鼠标
  3. 松开鼠标

在鼠标挪动时,获取鼠标以后地位,而后批改被拖拽元素的地位。

当松开鼠标时,也要获取松手那刻鼠标所在位置,而后设置元素的地位。


先看看官网给出的例子再逐渐剖析

<canvas id="c" width="500" height="500" style="border: 1px solid #ccc;"></canvas><script src="../js/fabric.js"></script><script>  // 创立画布  let canvas = new fabric.Canvas('c', {    allowTouchScrolling: true  })  // 矩形  const rect = new fabric.Rect({    width: 100,    height: 100,    left: 10,    top: 10,    fill: 'pink'  })  // 三角形  const triangle = new fabric.Triangle({    top: 100,    left: 100,    width: 80, // 底边长度    height: 100, // 底边到对角的间隔    fill: 'blue'  })  // 将矩形和三角形增加到画布中  canvas.add(rect, triangle)  // 按下鼠标事件  canvas.on('mouse:down', function (opt) {    var evt = opt.e;    if (evt.altKey === true) {      this.isDragging = true      this.lastPosX = evt.clientX      this.lastPosY = evt.clientY    }  })  // 挪动鼠标事件  canvas.on('mouse:move', function (opt) {    if (this.isDragging) {      var e = opt.e;      var vpt = this.viewportTransform;      vpt[4] += e.clientX - this.lastPosX      vpt[5] += e.clientY - this.lastPosY      this.requestRenderAll()      this.lastPosX = e.clientX      this.lastPosY = e.clientY    }  })  // 松开鼠标事件  canvas.on('mouse:up', function (opt) {    this.setViewportTransform(this.viewportTransform)    this.isDragging = false  })</script>

拖拽画布的代码来自官网案例。我删减了局部元素。

从下面的代码能够看出,次要事件是 mouse:downmouse:movemouse:up


按下鼠标时

canvas.on('mouse:down', function (opt) {  var evt = opt.e;  if (evt.altKey === true) {    this.isDragging = true    this.lastPosX = evt.clientX    this.lastPosY = evt.clientY  }})

通过 mouse:down 事件,设置了按住 alt 键时再按下鼠标左键,能力触发拖拽事件(开始)。

自定义3个属性:

  • isDragging: 拖拽状态,true 示意可拖拽
  • lastPosX: 画布上一个x坐标
  • lastPosY: 画布上一个y坐标


为什么要记录 lastPosXlastPosY 呢?

把鼠标点击时,鼠标所在的地位记录下来。之后挪动时,再通过鼠标新呈现的地位和点击时的地位比照,就能计算出鼠标挪动了多少间隔,而后再调整画布挪动的间隔即可。


挪动鼠标时

canvas.on('mouse:move', function (opt) {  if (this.isDragging) {    var e = opt.e;    var vpt = this.viewportTransform;    vpt[4] += e.clientX - this.lastPosX    vpt[5] += e.clientY - this.lastPosY    this.requestRenderAll()    this.lastPosX = e.clientX    this.lastPosY = e.clientY  }})

通过 mouse:move 能够监听鼠标的挪动。

此时就要通过 isDragging 判断是否进入拖拽状态。


viewportTransformfabric.js 在画布上的一个属性。

官网文档是这样介绍的:

The transformation (a Canvas 2D API transform matrix) which focuses the viewport


下面的代码,批改了 viewportTransform 下标为 45 的元素。

  • viewportTransform[4]: 程度位移(x轴)
  • viewportTransform[5]: 垂直位移(y轴)


e.clientX - this.lastPosX 就是鼠标挪动的x轴方向的间隔,e.clientY - this.lastPosY 能够计算出鼠标挪动的y轴方向的间隔。

如果想理解 viewportTransform 每个元素代表什么,能够看看 《Fabric.js 变换视窗》


requestRenderAll() 是在每次挪动完画布就刷新一下。


刷新完画布,就把上一个点(x和y坐标)改成最新的:this.lastPosX = e.clientXthis.lastPosY = e.clientY ,给下次挪动鼠标时提供一个参考值,不便计算。


松开鼠标时

canvas.on('mouse:up', function (opt) {  this.setViewportTransform(this.viewportTransform)  this.isDragging = false})

应用 setViewportTransform 设置画布的视图。

并退出拖拽模式:isDragging = false


以上就是在 fabric.js 中拖拽画布的办法。



代码仓库

⭐拖拽挪动画布



举荐浏览

《Fabric.js 从入门到_ _ _ _》

《Fabric.js 管制元素层级》

《Fabric.js 自定义选框款式》

《Fabric.js 元素核心缩放》


还要批改:如果想理解 viewportTransform 每个元素代表什么,能够看看 《Fabric.js 变换视窗》


点赞 + 关注 + 珍藏 = 学会了
代码仓库