记录fabricjs实际使用中的一些操作

10065次阅读 913人点赞 作者: WuBin 发布时间: 2024-04-12 14:50:10
扫码到手机查看

常用技巧

以下所有案例中,均默认我已经创建了画布对象如下:

<canvas id="box"></canvas>

const fabricCanvas = new fabric.Canvas('box', {
            width: 1000,
            height: 600,
            backgroundColor: '#fff'
});

遍历画布中所有对象

// 遍历原始画布上的所有对象
fabricCanvas.forEachObject(function(obj) {
            
});
等价于
fabricCanvas.getObjects().forEach(function(obj) {
       
});

fabricCanvas.getObjects() 是获取画布中所有元素

如果要获取当前选择的焦点元素

fabricCanvas.getActiveObject()

克隆画布中的某一个元素

fabricCanvas.forEachObject(function(obj) {
            // 克隆对象
            const clone = fabric.util.object.clone(obj);
            // 修改克隆对象的大小为原始大小的2倍
            clone.scale(scale);
});

上面的方法简单,但是在复制画布元素上有bug,会让复制的元素莫名关联原来的元素

这是官方案例http://fabricjs.com/copypaste

// 使用一个全局变量存储复制的元素,注意clone是一个异步方法!
let _clipboard = null;

function Copy() {
	// clone what are you copying since you
	// may want copy and paste on different moment.
	// and you do not want the changes happened
	// later to reflect on the copy.
	canvas.getActiveObject().clone(function(cloned) {
		_clipboard = cloned;
	});
}

function Paste() {
	// clone again, so you can do multiple copies.
	_clipboard.clone(function(clonedObj) {
		canvas.discardActiveObject();
		clonedObj.set({
			left: clonedObj.left + 10,
			top: clonedObj.top + 10,
			evented: true,
		});
		if (clonedObj.type === 'activeSelection') {
			// active selection needs a reference to the canvas.
			clonedObj.canvas = canvas;
			clonedObj.forEachObject(function(obj) {
				canvas.add(obj);
			});
			// this should solve the unselectability
			clonedObj.setCoords();
		} else {
			canvas.add(clonedObj);
		}
		_clipboard.top += 10;
		_clipboard.left += 10;
		canvas.setActiveObject(clonedObj);
		canvas.requestRenderAll();
	});
}

其中关于的说明:https://imangodoc.com/ZLJI7A50.html

ActiveSelection类型 是 Fabric.js中的一种选择器类型,是指在canvas中选定多个对象时,选中的所有对象组成的组选对象。例如,在canvas上选中了若干个矩形或文本对象,就会创建一个ActiveSelection 对象。

将某一元素插入到指定位置

fabricCanvas.insertAt(cloneObject, index);

将画布导出为2倍图

首先声明,下面这个函数有bug,会导致生成的2倍图中的元素位置偏移!

// 导出2倍大小的图片
    function exportAt2x(canvas) {
        const originalWidth = canvas.width;
        const originalHeight = canvas.height;
        const scale = 2;

        // 设置画布的新尺寸
        canvas.setWidth(originalWidth * scale, { cssOnly: true });
        canvas.setHeight(originalHeight * scale, { cssOnly: true });

        // 将所有对象缩放到新尺寸
        canvas.getObjects().forEach(function(obj) {
            obj.set('scaleX', obj.get('scaleX') * scale);
            obj.set('scaleY', obj.get('scaleY') * scale);
            obj.setCoords();
        });

        // 渲染画布以应用缩放
        canvas.renderAll();

        // 导出为图片
        const resultUrl = canvas.toDataURL({
            format: 'png',
            // 根据需要设置导出图片的质量
            quality: 2,
            width: canvas.width * scale,
            height: canvas.height * scale,
            left: 0,
            top: 0,
        });

        console.log(resultUrl)

        // 重置画布大小并缩放对象
        canvas.setWidth(originalWidth, { cssOnly: true });
        canvas.setHeight(originalHeight, { cssOnly: true });
        canvas.getObjects().forEach(function(obj) {
            obj.set('scaleX', obj.get('scaleX') / scale);
            obj.set('scaleY', obj.get('scaleY') / scale);
            obj.setCoords();
        });
        canvas.renderAll();

        return resultUrl;
}

实际项目中,根据我使用的fabric.js-5.3.0版本发现,如果要将最终画布导出为2x图,只需要一个配置项即可:

final = fabricCanvas.toDataURL({
              format: 'png',
              // 根据需要设置导出图片的质量
              quality: 2,
             // 设置scale为2
             multiplier: 2
});

在输出2倍图的同时,画布上元素位置还不会发生偏移!

调整画布中图层顺序

假设有下面3个元素

const canvas = fabricCanvas = new fabric.Canvas('canvas-box');

  // 橙色矩形
  rect = new fabric.Rect({
    top: 30,
    left: 30,
    fill: 'orange',
    width: 200,
    height: 100
  })

  // 粉红色圆形
  circle = new fabric.Circle({
    top: 50,
    left: 60,
    fill: 'hotpink',
    radius: 50
  })

  // 蓝色三角形
  triangle = new fabric.Triangle({
    top: 80,
    left: 30,
    width: 80,
    height: 100,
    fill: 'blue'
  })

  canvas.add(rect, circle, triangle)

可以看到画面中出现了矩形、圆形 和 三角形。由canvas.add(rect, circle, triangle)方法按顺序将它们添加到画布里。可以清晰看到三个图形的层级关系。

获取当前焦点元素的层级

const currentObject = fabricCanvas.getActiveObject();
const allObjects = fabricCanvas.getObjects();
// 获取当前焦点元素的层级
const index = allObjects.indexOf(currentObject);

移至顶层

此时橙色的矩形位于最底层,如果需要将其移动到最顶层,可以使用bringToFront()方法。

canvas.bringToFront(rect)
// 或者
// rect.bringToFront()

如果你是通过canvas来操作的话,需要传入一个备操作的对象。本例传入的是矩形对象。

你也可以使用rect.bringToFront()让元素操作自身。

移至底层

使用sendToBack方法可以将元素移至最底层。

canvas.sendToBack(triangle)
// 或者
// triangle.sendToBack()

往上一层

让元素往上移动一层,可以使用bringForward方法。

canvas.bringForward(rect)
// 或者
// rect.bringForward()

往下一层

能往上移一层,也可以往下移一层。使用的方法是sendBackwards

canvas.sendBackwards(triangle)
// 或者
// triangle.sendBackwards()

自定义层级

如果你需要直接设置图层层级,可以使用moveTo方法。

如果在canvas中使用moveTo方法,需要传入2个参数,第一个参数是要操作的对象,第二个参数是层级。

也可以直接在元素上使用moveTo方法,这样就只需传入1个层级参数就行。

canvas.moveTo(triangle, 10)
// 或者
triangle.moveTo(10)

可以参考 链接里的例子:https://k21vin.gitee.io/front-end-data-visualization/#/fabric/fabric-basic/fabric-moveTo

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:fabricjs
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    9352次阅读 603人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    4072次阅读 302人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    14279次阅读 934人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    13219次阅读 462人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    11801次阅读 943人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    15974次阅读 1273人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    15018次阅读 1223人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    29429次阅读 2309人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    25377次阅读 1954人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录