本文简介
点赞 关注 收藏 = 学会了
使用 fabric.js
创建出来的画布默认是不能拖拽移动的。
不过我们可以利用一些小技巧让画布具有被拖拽的能力,fabric.js
官网也提供了一个 demo
,但文档上并没有详细的讲解拖拽画布的实现原理。
本文就粗略分析一下这个原理。
原理解析
鼠标拖拽的原理其实很简单,主要就3步:
- 鼠标点击元素
- 移动鼠标
- 松开鼠标
在鼠标移动时,获取鼠标当前位置,然后修改被拖拽元素的位置。
当松开鼠标时,也要获取松手那刻鼠标所在位置,然后设置元素的位置。
先看看官方给出的例子再逐步分析
代码语言:javascript复制<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:down
、mouse:move
、mouse:up
。
按下鼠标时
代码语言:javascript复制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坐标
为什么要记录 lastPosX
和 lastPosY
呢?
把鼠标点击时,鼠标所在的位置记录下来。之后移动时,再通过鼠标新出现的位置和点击时的位置对比,就能计算出鼠标移动了多少距离,然后再调整画布移动的距离即可。
移动鼠标时
代码语言:javascript复制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
判断是否进入拖拽状态。
viewportTransform
是 fabric.js
在画布上的一个属性。
官方文档是这样介绍的:
The transformation (a Canvas 2D API transform matrix) which focuses the viewport
上面的代码,修改了 viewportTransform
下标为 4
和 5
的元素。
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.clientX
和 this.lastPosY = e.clientY
,给下次移动鼠标时提供一个参考值,方便计算。
松开鼠标时
代码语言:javascript复制canvas.on('mouse:up', function (opt) {
this.setViewportTransform(this.viewportTransform)
this.isDragging = false
})
使用 setViewportTransform
设置画布的视图。
并退出拖拽模式:isDragging = false
。
以上就是在 fabric.js
中拖拽画布的方法。
代码仓库
⭐拖拽移动画布