基于fabricjs搭建canvas画布 - 图片基础操作
图片基础操作
前面我们在画布中上传了图片, 作为一个工具我们需要能够对上传的元素进行一些基本的操作,比如针对图片进行缩放、拖动、旋转、框选、合并图层、解散图层等。
fabric对元素的拖动、旋转以及框选本身提供了相关功能,这里我们就不做说明了。 接下来我们依次来实现图片的缩放、框选、合并图层、解散图层。
缩放
前面画布缩放的时候我们针对canvas的mouse:wheel进行了监听,并在里面实现了画布的缩放。这里我们依旧在该监听内来实现元素的缩放。 前面介绍了canvas事件会在回调里返回event对象,所以我们基于event.target(这里和dom是一样的)来判断鼠标下是否有元素
canvas.on("mouse:wheel", (opt) => {
const { target } = opt;
let delta = opt.e.deltaY; // 滚轮向上滚一下是 -100,向下滚一下是 100
if (target && target.type === 'image') {
// 获取缩放前的信息数据
const height = target.getScaledHeight();
const width = target.getScaledWidth();
const zoomVal = target.getTotalObjectScaling();
const { scaleX, scaleY } = zoomVal;
let X = 0.9999 ** delta;
if (X > max) X = max;
if (X < min) X = min;
const Y = X;
// 设置缩放大小
target.scaleToWidth(width * X, true);
target.scaleToHeight(height * Y, true);
canvas.requestRenderAll();
}
})
元素的缩放与画布不同,需要分别针对元素的width、height进行缩放设置。同时调用canvas.requestRenderAll();
来刷新画布元素
合并/解散图层
图层合并的功能我们基于分组来实现, 这块都有相关的api,唯一需要注意的是新分组创建是通过对元素的拷贝来创建分组内的元素,原有的元素需要手动删除
合并图层实现
/**
*新建分组
*
* @param {Object} canvas 当前画布对象
* @param {Object} opts 组配置参数
* @return {Object} 返回的group对象
*/
create(canvas, opts) {
// 判断当前有没有选中元素,如果没有就不执行任何操作
if (!canvas.getActiveObject()) {
return;
}
const activeObject = canvas.getActiveObject();
const { top, left } = activeObject;
const group = new fabric.Group(activeObject._objects, {
top,
left,
});
activeObject._objects.forEach((element) => {
canvas.remove(element);
});
canvas.add(group);
canvas.requestRenderAll();
return group;
}
解散图层实现
/**
* 解散分组
*
* @param {Object} canvas 画布对象
* @return {Object} 返回的group对象
*/
dispersed(canvas) {
// 判断当前有没有选中元素,如果没有就不执行任何操作
if (!canvas.getActiveObject()) {
return;
}
// 判断当前是否选中组,如果不是,就不执行任何操作, 此处需要考虑多选
if (canvas.getActiveObject().type !== "group") {
return;
}
// 先获取当前选中的对象,然后打散
canvas.getActiveObject().toActiveSelection();
}