HTML5画布框架fabricjs学习笔记(三)——自定义选择控制框样式

前言

这篇博文是《HTML5画布框架fabricjs学习笔记》系列博文的第三篇——自定义选择控制框样式,主要的内容有:

1. 如何修改控制框中的控制点、控制线的样式
2. 如何使用贴图覆盖默认的控制点样式
3. 如何添加自定义的控制点(如删除、锁定等)

框架介绍、引入及索引部分见《HTML5画布框架fabricjs学习笔记(一)——引入》


什么是选择控制框?

我们以前文中的一个例子作为示例。如下图,当我们点击一个画布中的对象,对象周围就出现了一个控制框,控制框上一共9个控制点。
请添加图片描述

控制线

如上图所示,控制框的范围由控制线限定。 自定义时,根据需要,我们一般会修改控制线的以下属性:

  • 是否显示
  • 颜色
  • 与框选对象间的内边距

控制点

如上图所示,点击并拖动不同的控制点,会产生不同的交互效果。 下面区分不同的控制点类型分别进行介绍:

  • 水平缩放控制点:第一列中间第三列中间两个控制点。点击并进行拖动,会改变对象的水平缩放值(scaleX,初始值为1
  • 竖直缩放控制点:第二列第二行和第三行两个控制点。点击并进行拖动,会改变对象的竖直缩放值(scaleY,初始值为1
  • 等比例缩放控制点:左上、右上、左下、右下四个控制点。点击并进行拖动,会同时并等比例改变对象的scaleXscaleY两个值
  • 中心旋转控制点:第二列最上方的控制点。点击并进行拖动,会改变对象的角度值(angle,初始值为0)

注意:

  1. 左上的等比例缩放控制点还会改变对象的topleft值。
  2. 左中的水平缩放控制点还会改变对象的left值。
  3. 中心旋转控制点还会改变对象的topleft值。

这些在后续做一些例如撤销重做等业务逻辑时,需要特别进行考虑和编码实现。


自定义控制线样式

上文中提到,我们一般对控制线是否显示颜色与框选对象间的内边距这几个属性进行自定义修改。这里用另一个例子,对上述属性逐一进行介绍。

如图所示,一个黄色的矩形,其默认的控制线样式如下:
请添加图片描述
接下来我们对他的控制线样式进行修改。

与框选对象间的内边距

我们将内边距设置为10px

代码

	fabric.Object.prototype.padding = 10;

代码说明

padding即内边距,目前只支持4个方向的统一设置,不支持单独设置

结果

请添加图片描述

是否显示

现在换回黄脸表情,我们之前见过的编辑器,其旋转控制点和主体之间一般没有那条控制线,这里我们对它进行隐藏。

代码

	fabric.Object.prototype.controls.mtr.withConnection = false;

代码说明

  1. fabric.Object是所有对象的父类,修改其属性即可对它的子类(RectCircle…)都生效。
  2. controls包含了Object类的所有控制点的信息。
  3. mtrmiddle top rotation的缩写,即中心旋转控制点。
  4. withConnectionmtr是否和主体有连线,此处设为false

结果

可见,旋转控制点和主体之间的那条连接线没有了
请添加图片描述

颜色

我们将控制线默认的浅蓝色改为dodgerblue,一种深蓝色

代码

	fabric.Object.prototype.borderColor = 'dodgerblue';

代码说明

borderColor即控制线的颜色,支持英文单词rgb格式rgba格式16进制格式

结果

请添加图片描述


自定义控制点样式

对于控制点,我们可以自定义修改其形状、大小、边框颜色、填充颜色等属性。这里对于各个属性不再一一介绍,我们用一个综合的例子对它们进行演示。

代码

	// 修改控制点的形状,默认为`rect`矩形,可选的值还有`circle`圆形
    fabric.Object.prototype.cornerStyle = "circle";
    // 修改控制点的填充色为白色
    fabric.Object.prototype.cornerColor = "white";
    // 修改控制点的大小为10px
    fabric.Object.prototype.cornerSize = 10;
    // 设置控制点不透明,即可以盖住其下的控制线
    fabric.Object.prototype.transparentCorners = false;
    // 修改控制点的边框颜色为`gray`灰色
    fabric.Object.prototype.cornerStrokeColor = "gray";
    
    // 单独修改旋转控制点距离主体的纵向距离为-20px
    fabric.Object.prototype.controls.mtr.offsetY = -20;
    // 单独修改旋转控制点,光标移动到该点上时的样式为`pointer`,一个手的形状
    fabric.Object.prototype.controls.mtr.cursorStyle = "pointer";

结果

请添加图片描述


自定义控制点贴图

例设我们要将中心旋转控制点样式改为如下的贴图:
请添加图片描述

代码

	// 渲染图标的方法
	static renderIcon(image, initialAngle) {
    
    
	      return function (ctx, left, top, styleOverride, fabricObject) {
    
    
	          let size = this.cornerSize;
	          ctx.save();
	          ctx.translate(left, top);
	          ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle + initialAngle));
	          ctx.drawImage(image, -size / 2, -size / 2, size, size);
	          ctx.restore();
	      }
	}
    
    // 图标的下载链接省略
	const iconURL = "...";
    const callback = (image, isError) => {
    
    
      if (!isError) {
    
    
        fabric.Object.prototype.controls.mtr = new fabric.Control({
    
    
            x: 0,
            y: -0.5,
            offsetY: -20,
            cursorStyle: 'pointer',
            actionHandler: fabric.controlsUtils.rotationWithSnapping,
            cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,
            // 渲染图标
            render: this.renderIcon(image._element, 0),
            // 设置控制点大小
            cornerSize: 30
        });
      }
    };
    fabric.Image.fromURL(iconURL, callback);

代码说明

fabric.Control声明的是一个控制点对象,其包含以下属性:

  1. xy:表示控制点距离对象中心点的位置,坐标轴横轴左负右正,纵轴上负下正。
  2. cursorStyle:光标移动到控制点上时的样式。可选的值有w/e/s/n-resizepointer等,即东西南北方向的箭头、手的图标等。
  3. actionHandler:用户拖动该控制点时的动作处理器,这里使用默认的scalingX,即水平方向缩放处理器。以此类推,可选的控制器还有scalingYscalingEqually(同时缩放X和Y)、rotationWithSnapping(旋转)等。

    更多可选值见 源码7421

  4. render:渲染方法,调用现成的方法即可。
  5. cornerSize:控制点大小,可以控制贴图的大小。

结果

请添加图片描述


添加自定义控制点

有的时候,我们可能不满足于默认提供的9个控制点,想要自己添加一些控制点上去,比如用于删除对象的控制点。这个小节,我们使用一个红色的垃圾桶图标来实现它。

结果

首先看一下实现效果:
请添加图片描述

代码

	// 从画布中删除当前选中的对象
	static deleteObject(canvas) {
    
    
		// 获取画布当前选中的对象
		let activeObject = canvas.getActiveObject();
    	if (activeObject) {
    
    
      		canvas.remove(activeObject);
      		canvas.renderAll();
    	}
  	};

	// 垃圾桶图标的下载链接,省略
	const deleteIconURL = "...";
	
	const callback = (image, isError) => {
    
    
		console.log(image);
		if (!isError) {
    
    
			fabric.Object.prototype.controls.delete = new fabric.Control({
    
    
			    // x和y设置该控制点和第二列中间的控制点重合
				x: 0,
				y: -0.5,
				// offsetX和offsetY设置该控制点在水平和竖直两个方向上
				// 偏移的距离(单位px)
                offsetX: 28,
                offsetY: -20,
                // 光标移动到该控制点时变为一个手的图标
                cursorStyle: 'pointer',
                // 自定义的值,可忽略
                actionName: "delete",
                // 设置当点击了该控制点,鼠标弹起是执行的动作处理方法
                mouseUpHandler: () => this.deleteObject(canvas),
                render: Application.renderIcon(image._element, 0),
                cornerSize: 16
            });
		}
    };
    fabric.Image.fromURL(deleteIconURL, callback);

本节完整代码见CodeSandbox


系列博文

HTML5画布框架fabricjs学习笔记(一)——引入
HTML5画布框架fabricjs学习笔记(二)——图片与背景
HTML5画布框架fabricjs学习笔记(三)——自定义选择控制框样式

(以下博文创作中,敬请期待)
HTML5画布框架fabricjs学习笔记(四)——用户交互(上)


后记

本小节中,我们可以对默认的控制框样式进行自定义的编辑。可以在框架设定内进行选择,也可以替换自己喜欢的贴图样式。我们的目标是做一个美观的在线画布编辑页面。

还需要说明的有:

1. 各个控制点的名字分别为:

  • 左上点:tl(top left)
  • 左中点:ml(middle left)
  • 左下点:bl(bottom left)
  • 中上旋转点:mtr(middle top rotation)
  • 中上点:mt (middle top)
  • 中下点:mb(middle bottom)
  • 右上点:tr(top right)
  • 右中点:mr(middle right)
  • 右下点:br(bottom right)

2. 贴图部分由于找不到一个合适的图片,故找了一个五角星代替(侵删),一般情况下,为了美化,我们的左中、上中、下中、右中四个控制点做成一个圆形条状会很美观,有美工条件的话可以按照上述方法自定义修改。

3. fabric.Control实例化时的actionHandler等参数一般引用框架里现成的,具体可以参考源码,也可以留言讨论。

猜你喜欢

转载自blog.csdn.net/Mr_Megamind/article/details/122293467