LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

学习整理fabric.js自定义选择控制框样式和增加控制图标

admin
2023年5月23日 10:25 本文热度 1965

选择控制框简介

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

在这里插入图片描述

控制线

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

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

控制点

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

1、水平缩放控制点: 即第一列中间和第三列中间两个控制点。点击并进行拖动,会改变对象的水平缩放值(scaleX,初始值为1)

2、竖直缩放控制点: 即第二列第二行和第三行两个控制点。点击并进行拖动,会改变对象的竖直缩放值(scaleY,初始值为1)

3、等比例缩放控制点: 即左上、右上、左下、右下四个控制点。点击并进行拖动,会同时并等比例改变对象的scaleX和scaleY两个值

4、中心旋转控制点: 即第二列最上方的控制点。点击并进行拖动,会改变对象的角度值(angle,初始值为0)

注意

左上的等比例缩放控制点还会改变对象的top和left值。
左中的水平缩放控制点还会改变对象的left值。
中心旋转控制点还会改变对象的top和left值。

自定义控制线样式

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

如图所示,其默认的控制线样式如下:

在这里插入图片描述

与框选对象间的内边距

fabric.Object.prototype.padding = 10;1

代码说明

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

结果
在这里插入图片描述
是否显示

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

代码

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

代码说明

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

结果

可见,旋转控制点和主体之间的那条连接线没有了

在这里插入图片描述

修改控制线颜色

我们将控制线默认的浅蓝色改为 #dc143c,一种红色

代码

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

效果图
在这里插入图片描述

自定义控制点样式

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

代码

// 修改控制点的形状,默认为`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";


自定义控制点贴图

在这里插入图片描述

/*控制选中边框 旋转图标 start*/


// 渲染图标的方法

function 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 = "../img/xuanzhuan.png";

const callback = (image, isError) => {

    if (!isError) {

        fabric.Object.prototype.controls.ml = new fabric.Control({

            x: 0,

            y: -0.5,

            offsetY: -20,

            cursorStyle: 'pointer',

            actionHandler: fabric.controlsUtils.rotationWithSnapping,

            cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,

            // 渲染图标

            render: renderIcon(image._element, 0),

            // 设置控制点大小

            cornerSize: 30

        });

    }

};

fabric.Image.fromURL(iconURL, callback);


/*控制选中边框 旋转图标 stop*/


在这里插入图片描述

添加自定义控制点

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

首先看一下实现效果:

在这里插入图片描述
代码

/*控制选中边框 增加自对应图标 start*/



// 从画布中删除当前选中的对象

function deleteObject() {

    // 获取画布当前选中的对象

    let activeObject = canvas.getActiveObject();

    if (activeObject) {

        canvas.remove(activeObject);

        canvas.renderAll();

    }

}


// 垃圾桶图标的下载链接

const deleteIconURL = "../img/delete.png";

const deletecallback = (img, isError) => {

    console.log(img);

    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: () => deleteObject(),

            //渲染图标

            render: renderIcon(img._element, 0),

            cornerSize: 39

        });

    }

};

fabric.Image.fromURL(deleteIconURL, deletecallback);


/*控制选中边框 增加自对应图标 stop*/


注意

renderIcon 方法在上边定义过了,可以直接调用

所有代码

在这里插入图片描述

效果图

在这里插入图片描述

index.html

<!DOCTYPE HTML>

<html>

<head>

    <meta charset="utf-8">

    <title>Fabric.js 上传图片保存</title>

    <script src="../fabric5.2.1.js"></script>

    <style>

        div#container {

            padding: 30px;

            font-family: 'verdana', lucida;

        }

        input {

            background-color: #ccc;

            padding: 0;

            width: 300px;

            color: #777;

        }

        #lnkDownload {

            display: block;

            padding: 0;

            margin-top: 10px;

            text-decoration: none;

        }

    </style>

</head>

<body>

<div id="container">

    <canvas id="imageCanvas" width="300" height="300"></canvas>

    <a id="lnkDownload" href="#">

        <button> 保存图片</button>

    </a>

</div>

<script src="script.js"></script>

</body>

</html>


script.js

var canvas = new fabric.Canvas('imageCanvas', {

    backgroundColor: 'rgb(240,240,240)',

    includeDefaultValues: false,// 指示toObject/toDatalessObject是否应该包含默认值,如果设置为false,则优先于对象值

    perPixelTargetFind: true, //这一句说明选中的时候以图形的实际大小来选择而不是以边框来选择

    hasBorders: false,

});


canvas.setWidth(500);

canvas.setHeight(500);


/*控制选中边框 start*/

//将内边距设置为10px

fabric.Object.prototype.padding = 10;

// 修改控制点的形状,默认为`rect`矩形,可选的值还有`circle`圆形

fabric.Object.prototype.cornerStyle = "circle";

// 修改控制点的填充色为白色

fabric.Object.prototype.cornerColor = "white";

//将控制线默认的浅蓝色改为 #dc143c,

fabric.Object.prototype.borderColor = '#dc143c';

// 修改控制点的大小为10px

fabric.Object.prototype.cornerSize = 10;

// 设置控制点不透明,即可以盖住其下的控制线

fabric.Object.prototype.transparentCorners = false;

// 修改控制点的边框颜色为`gray`灰色

fabric.Object.prototype.cornerStrokeColor = "blue";

// 单独修改旋转控制点距离主体的纵向距离为-20px

fabric.Object.prototype.controls.mtr.offsetY = -20;

// 单独修改旋转控制点,光标移动到该点上时的样式为`pointer`,一个手的形状

fabric.Object.prototype.controls.mtr.cursorStyle = "pointer";

//旋转控制点和主体之间一般没有那条控制线,这里我们对它进行隐藏。

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

/*控制选中边框 stop*/

/*控制选中边框 旋转图标 start*/


// 渲染图标的方法

function 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 = "../img/xuanzhuan.png";

const callback = (image, isError) => {

    if (!isError) {

        fabric.Object.prototype.controls.ml = new fabric.Control({

            x: 0,

            y: -0.5,

            offsetY: -20,

            cursorStyle: 'pointer',

            actionHandler: fabric.controlsUtils.rotationWithSnapping,

            cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,

            // 渲染图标

            render: renderIcon(image._element, 0),

            // 设置控制点大小

            cornerSize: 30

        });

    }

};

fabric.Image.fromURL(iconURL, callback);


/*控制选中边框 旋转图标 stop*/


/*控制选中边框 增加自对应图标 start*/


// 从画布中删除当前选中的对象

function deleteObject() {

    // 获取画布当前选中的对象

    let activeObject = canvas.getActiveObject();

    if (activeObject) {

        canvas.remove(activeObject);

        canvas.renderAll();

    }

}


// 垃圾桶图标的下载链接

const deleteIconURL = "../img/delete.png";

const deletecallback = (img, isError) => {

    console.log(img);

    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: () => deleteObject(),

            //渲染图标

            render: renderIcon(img._element, 0),

            cornerSize: 39

        });

    }

};

fabric.Image.fromURL(deleteIconURL, deletecallback);


/*控制选中边框 增加自对应图标 stop*/


// 矩形

var rect = new fabric.Rect({

    left: 100,

    top: 100,

    fill: 'orange',

    width: 100,

    height: 100,

})

canvas.add(rect);


// 圆角矩形

var rect2 = new fabric.Rect({

    left: 300,

    top: 100,

    fill: 'yellowgreen',

    width: 100,

    height: 100,

    rx: 20,

    ry: 20

})

canvas.add(rect2);


// 圆形

var circle = new fabric.Circle({

    radius: 50,

    fill: 'green',

    left: 200,

    top: 200,

    controls: false, // 不可编辑

    hasControls: false, // 控件将不显示,并且不能用于操作对象

});


canvas.add(circle);


// 使用 IText,可编辑文本

var text = new fabric.IText(

    '奇葩呀,www.qipa250.com',

    {

        top:300,

        fontSize:14,

        fontFamily: 'Comic Sans'

    }

)

canvas.add(text);


var imageSaver = document.getElementById('lnkDownload');

imageSaver.addEventListener('click', saveImage, false);


function saveImage() {

    console.log('toJSON==', canvas.toJSON());

    console.log('toObject==', canvas.toObject()); // 输出序列化的内容

    this.href = canvas.toDataURL({

        format: 'png',

        quality: 0.8

    });

    this.download = 'canvas.png';

}




该文章在 2023/5/23 10:36:40 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved