这篇博文是《HTML5画布框架fabricjs学习笔记》系列博文的第三篇——自定义选择控制框样式,主要的内容有:
1. 如何修改控制框中的控制点、控制线的样式
2. 如何使用贴图覆盖默认的控制点样式
3. 如何添加自定义的控制点(如删除、锁定等)
框架介绍、引入及索引部分见《HTML5画布框架fabricjs学习笔记(一)——引入》
我们以前文中的一个例子作为示例。如下图,当我们点击一个画布中的对象,对象周围就出现了一个控制框,控制框上一共9个控制点。
如上图所示,控制框的范围由控制线限定。 自定义时,根据需要,我们一般会修改控制线的以下属性:
如上图所示,点击并拖动不同的控制点,会产生不同的交互效果。 下面区分不同的控制点类型分别进行介绍:
scaleX,初始值为1
)scaleY,初始值为1
)scaleX
和scaleY
两个值angle
,初始值为0)注意:
- 左上的等比例缩放控制点还会改变对象的
top
和left
值。- 左中的水平缩放控制点还会改变对象的
left
值。- 中心旋转控制点还会改变对象的
top
和left
值。
这些在后续做一些例如撤销
、重做
等业务逻辑时,需要特别进行考虑和编码实现。
上文中提到,我们一般对控制线是否显示
、颜色
、与框选对象间的内边距
这几个属性进行自定义修改。这里用另一个例子,对上述属性逐一进行介绍。
如图所示,一个黄色的矩形,其默认的控制线样式如下:
接下来我们对他的控制线样式进行修改。
我们将内边距设置为10px
fabric.Object.prototype.padding = 10;
padding
即内边距,目前只支持4个方向的统一设置,不支持单独设置
现在换回黄脸表情,我们之前见过的编辑器,其旋转控制点和主体之间一般没有那条控制线,这里我们对它进行隐藏。
fabric.Object.prototype.controls.mtr.withConnection = false;
fabric.Object
是所有对象的父类,修改其属性即可对它的子类(Rect
、Circle
…)都生效。controls
包含了Object
类的所有控制点的信息。mtr
是middle top rotation
的缩写,即中心旋转控制点。withConnection
即mtr
是否和主体有连线,此处设为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
声明的是一个控制点对象,其包含以下属性:
x
和y
:表示控制点距离对象中心点的位置,坐标轴横轴左负右正,纵轴上负下正。cursorStyle
:光标移动到控制点上时的样式。可选的值有w/e/s/n-resize
、pointer
等,即东西南北方向的箭头、手的图标等。actionHandler
:用户拖动该控制点时的动作处理器,这里使用默认的scalingX
,即水平方向缩放处理器。以此类推,可选的控制器还有scalingY
、scalingEqually
(同时缩放X和Y)、rotationWithSnapping
(旋转)等。
更多可选值见 源码 第
7421
行
render
:渲染方法,调用现成的方法即可。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等参数一般引用框架里现成的,具体可以参考源码,也可以留言讨论。