前提准备:vue2环境,下载好fabric( npm i fabric --save )
- 初始化一个画布。
// 3. 设置画布参数
const canvas = this.canvas = new fabric.Canvas('c', {
width: '800', // 画布宽度
height: '600', // 画布高度
backgroundColor: '#eee' // 画布背景色
})
- 准备一个圆角矩形和插入一张图片用作参照物
// 圆角矩形
const rect = new fabric.Rect({
top: 300, // 距离容器顶部 300px
left: 300, // 距离容器左侧 300px
fill: 'orange', // 填充 橙色
width: 100, // 宽度 100px
height: 100, // 高度 100px
originX:'left', // 原点
originY:'center', //原点
lockScalingFlip: true, //锁定翻转,及可不可以拉到边的负值
rx: 20, // x轴的半径
ry: 20 // y轴的半径
})
// 将矩形添加到画布中
canvas.add(rect)
// 添加图片 import 或者 require 都行,但 '../../..' 引路径好像不行,在线的没试过
// import logo from '@/assets/logo.png' // 引入图片
fabric.Image.fromURL(logo, oImg => {
oImg.scale(0.5) // 缩放
oImg.set({
left:50,
top:50
})
canvas.add(oImg) // 将图片加入到画布
})
一、 缩放
1、 以原点为中心(左上角),缩放画布
// 监听鼠标滚轮事件
canvas.on('mouse:wheel', opt => {
let delta = opt.e.deltaY // 滚轮向上滚一下是 -100,向下滚一下是 100
let zoom = canvas.getZoom() // 获取画布当前缩放值
// 控制缩放范围在 0.01~20 的区间内
zoom *= 0.999 ** delta
if (zoom > 20) zoom = 20
if (zoom < 0.01) zoom = 0.01
// 设置画布缩放比例
canvas.setZoom(zoom)
})
2、以鼠标指针为中心,缩放画布
// 监听鼠标滚轮事件
canvas.on('mouse:wheel', opt => {
let delta = opt.e.deltaY // 滚轮向上滚一下是 -100,向下滚一下是 100
let zoom = canvas.getZoom() // 获取画布当前缩放值
// 控制缩放范围在 0.01~20 的区间内
zoom *= 0.999 ** delta
if (zoom > 20) zoom = 20
if (zoom < 0.01) zoom = 0.01
canvas.zoomToPoint(
{
x: opt.e.offsetX, // 鼠标x轴坐标
y: opt.e.offsetY // 鼠标y轴坐标
},
zoom // 最后要缩放的值
)
})
- 区别点: setZoom 和 zoomToPoint
3、 点击按钮控制缩放
// html
<button @click="setZoom(0.1)">放大</button>
<button @click="setZoom(-0.1)">缩小</button>
// js
// 点击控制缩放
setZoom(val) {
let zoom = this.canvas.getZoom() + parseFloat(val);
zoom = Math.max(0.2, zoom);
zoom = Math.min(5, zoom);
let backPoint = this.canvas.getCenterPoint();
console.log(backPoint);
this.canvas.zoomToPoint(backPoint, zoom);
},
二、 拖拽
主要步骤:
- 监听画布对象的鼠标按下事件,维护一标志符,记录此刻位置
- 监听画布对象的鼠标移动事件,判断标志符,视图位置发生改变,更新位置
- 监听画布对象的鼠标按起事件,释放一标志符
1、方法一
canvas.on('mouse:down', opt => { // 鼠标按下时触发
let evt = opt.e
canvas.isDragging = true // isDragging 是自定义的,开启移动状态
canvas.lastPosX = evt.clientX // lastPosX 是自定义的
canvas.lastPosY = evt.clientY // lastPosY 是自定义的
})
canvas.on('mouse:move', opt => { // 鼠标移动时触发
console.log('查看e',opt);
if (canvas.isDragging) {
let evt = opt.e
let vpt = canvas.viewportTransform // 聚焦视图的转换
vpt[4] += evt.clientX - canvas.lastPosX
vpt[5] += evt.clientY - canvas.lastPosY
canvas.requestRenderAll() // 重新渲染
canvas.lastPosX = evt.clientX
canvas.lastPosY = evt.clientY
canvas.requestRenderAll() // 重新渲染
}
})
canvas.on('mouse:up', opt => { // 鼠标松开时触发
canvas.setViewportTransform(canvas.viewportTransform) // 设置此画布实例的视口转换
canvas.isDragging = false // 关闭移动状态
})
- 画布中默认可以通过拖拽来选中元素,在画布拖拽时会产生拖拽框。这里可以禁用画布的选中,可通过点击元素选中
canvas.selection = false
2、方法二
canvas.on({
"mouse:down": (e) => {
this.panning = true;
canvas.selection = false;
},
"mouse:up": (e) => {
this.panning = false;
canvas.selection = true;
},
"mouse:move": (e) => {
if (this.panning && e && e.e) {
let delta = new fabric.Point(e.e.movementX, e.e.movementY);// e.e.movementX 移动时画布的横向相对偏移量
canvas.relativePan(delta);
}
})
代码及参考
https://juejin.cn/post/7105046849362329608
https://juejin.cn/post/7143062674954256391
https://blog.csdn.net/qq_38860536/article/details/104719854