LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

學(xué)習(xí)整理fabric.js自定義選擇控制框樣式和增加控制圖標(biāo)

admin
2023年5月23日 10:25 本文熱度 2912

選擇控制框簡介

我們以前文中的一個(gè)例子作為示例。如下圖,當(dāng)我們點(diǎn)擊一個(gè)畫布中的對(duì)象,對(duì)象周圍就出現(xiàn)了一個(gè)控制框,控制框上一共9個(gè)控制點(diǎn)。

在這里插入圖片描述

控制線

如上圖所示,控制框的范圍由控制線限定。 自定義時(shí),根據(jù)需要,我們一般會(huì)修改控制線的以下屬性

是否顯示
顏色
與框選對(duì)象間的內(nèi)邊距

控制點(diǎn)

如上圖所示,點(diǎn)擊并拖動(dòng)不同的控制點(diǎn),會(huì)產(chǎn)生不同的交互效果。 下面區(qū)分不同的控制點(diǎn)類型分別進(jìn)行介紹:

1、水平縮放控制點(diǎn): 即第一列中間和第三列中間兩個(gè)控制點(diǎn)。點(diǎn)擊并進(jìn)行拖動(dòng),會(huì)改變對(duì)象的水平縮放值(scaleX,初始值為1)

2、豎直縮放控制點(diǎn): 即第二列第二行和第三行兩個(gè)控制點(diǎn)。點(diǎn)擊并進(jìn)行拖動(dòng),會(huì)改變對(duì)象的豎直縮放值(scaleY,初始值為1)

3、等比例縮放控制點(diǎn): 即左上、右上、左下、右下四個(gè)控制點(diǎn)。點(diǎn)擊并進(jìn)行拖動(dòng),會(huì)同時(shí)并等比例改變對(duì)象的scaleX和scaleY兩個(gè)值

4、中心旋轉(zhuǎn)控制點(diǎn): 即第二列最上方的控制點(diǎn)。點(diǎn)擊并進(jìn)行拖動(dòng),會(huì)改變對(duì)象的角度值(angle,初始值為0)

注意

左上的等比例縮放控制點(diǎn)還會(huì)改變對(duì)象的top和left值。
左中的水平縮放控制點(diǎn)還會(huì)改變對(duì)象的left值。
中心旋轉(zhuǎn)控制點(diǎn)還會(huì)改變對(duì)象的top和left值。

自定義控制線樣式

上文中提到,我們一般對(duì)控制線是否顯示、顏色、與框選對(duì)象間的內(nèi)邊距這幾個(gè)屬性進(jìn)行自定義修改。這里用另一個(gè)例子,對(duì)上述屬性逐一進(jìn)行介紹。

如圖所示,其默認(rèn)的控制線樣式如下:

在這里插入圖片描述

與框選對(duì)象間的內(nèi)邊距

fabric.Object.prototype.padding = 10;1

代碼說明

padding即內(nèi)邊距,目前只支持4個(gè)方向的統(tǒng)一設(shè)置,不支持單獨(dú)設(shè)置

結(jié)果
在這里插入圖片描述
是否顯示

我們之前見過的編輯器,其旋轉(zhuǎn)控制點(diǎn)和主體之間一般沒有那條控制線,這里我們對(duì)它進(jìn)行隱藏。

代碼

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

代碼說明

fabric.Object是所有對(duì)象的父類,修改其屬性即可對(duì)它的子類(Rect、Circle…)都生效。
controls包含了Object類的所有控制點(diǎn)的信息。
mtr是middle top rotation的縮寫,即中心旋轉(zhuǎn)控制點(diǎn)。
withConnection即mtr是否和主體有連線,此處設(shè)為false。

結(jié)果

可見,旋轉(zhuǎn)控制點(diǎn)和主體之間的那條連接線沒有了

在這里插入圖片描述

修改控制線顏色

我們將控制線默認(rèn)的淺藍(lán)色改為 #dc143c,一種紅色

代碼

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

效果圖
在這里插入圖片描述

自定義控制點(diǎn)樣式

對(duì)于控制點(diǎn),我們可以自定義修改其形狀、大小、邊框顏色、填充顏色等屬性。這里對(duì)于各個(gè)屬性不再一一介紹,我們用一個(gè)綜合的例子對(duì)它們進(jìn)行演示。

代碼

// 修改控制點(diǎn)的形狀,默認(rèn)為`rect`矩形,可選的值還有`circle`圓形

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

// 修改控制點(diǎn)的填充色為白色

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

// 修改控制點(diǎn)的大小為10px

fabric.Object.prototype.cornerSize = 10;

// 設(shè)置控制點(diǎn)不透明,即可以蓋住其下的控制線

fabric.Object.prototype.transparentCorners = false;

// 修改控制點(diǎn)的邊框顏色為`gray`灰色

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

    

// 單獨(dú)修改旋轉(zhuǎn)控制點(diǎn)距離主體的縱向距離為-20px

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

// 單獨(dú)修改旋轉(zhuǎn)控制點(diǎn),光標(biāo)移動(dòng)到該點(diǎn)上時(shí)的樣式為`pointer`,一個(gè)手的形狀

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


自定義控制點(diǎn)貼圖

在這里插入圖片描述

/*控制選中邊框 旋轉(zhuǎn)圖標(biāo) start*/


// 渲染圖標(biāo)的方法

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();

    };

}


// 圖標(biāo)的下載鏈接省略

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,

            // 渲染圖標(biāo)

            render: renderIcon(image._element, 0),

            // 設(shè)置控制點(diǎn)大小

            cornerSize: 30

        });

    }

};

fabric.Image.fromURL(iconURL, callback);


/*控制選中邊框 旋轉(zhuǎn)圖標(biāo) stop*/


在這里插入圖片描述

添加自定義控制點(diǎn)

有的時(shí)候,我們可能不滿足于默認(rèn)提供的9個(gè)控制點(diǎn),想要自己添加一些控制點(diǎn)上去,比如用于刪除對(duì)象的控制點(diǎn)。這個(gè)小節(jié),我們使用一個(gè)垃圾桶圖標(biāo)來實(shí)現(xiàn)它。

首先看一下實(shí)現(xiàn)效果:

在這里插入圖片描述
代碼

/*控制選中邊框 增加自對(duì)應(yīng)圖標(biāo) start*/



// 從畫布中刪除當(dāng)前選中的對(duì)象

function deleteObject() {

    // 獲取畫布當(dāng)前選中的對(duì)象

    let activeObject = canvas.getActiveObject();

    if (activeObject) {

        canvas.remove(activeObject);

        canvas.renderAll();

    }

}


// 垃圾桶圖標(biāo)的下載鏈接

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

const deletecallback = (img, isError) => {

    console.log(img);

    if (!isError) {

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

            // x和y設(shè)置該控制點(diǎn)和第二列中間的控制點(diǎn)重合

            x: 0,

            y: -0.5,

            // offsetX和offsetY設(shè)置該控制點(diǎn)在水平和豎直兩個(gè)方向上

            // 偏移的距離(單位px)

            offsetX: 28,

            offsetY: -20,

            // 光標(biāo)移動(dòng)到該控制點(diǎn)時(shí)變?yōu)橐粋€(gè)手的圖標(biāo)

            cursorStyle: 'pointer',

            // 自定義的值,可忽略

            actionName: "delete",

            // 設(shè)置當(dāng)點(diǎn)擊了該控制點(diǎn),鼠標(biāo)彈起是執(zhí)行的動(dòng)作處理方法

            mouseUpHandler: () => deleteObject(),

            //渲染圖標(biāo)

            render: renderIcon(img._element, 0),

            cornerSize: 39

        });

    }

};

fabric.Image.fromURL(deleteIconURL, deletecallback);


/*控制選中邊框 增加自對(duì)應(yīng)圖標(biāo) stop*/


注意

renderIcon 方法在上邊定義過了,可以直接調(diào)用

所有代碼

在這里插入圖片描述

效果圖

在這里插入圖片描述

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是否應(yīng)該包含默認(rèn)值,如果設(shè)置為false,則優(yōu)先于對(duì)象值

    perPixelTargetFind: true, //這一句說明選中的時(shí)候以圖形的實(shí)際大小來選擇而不是以邊框來選擇

    hasBorders: false,

});


canvas.setWidth(500);

canvas.setHeight(500);


/*控制選中邊框 start*/

//將內(nèi)邊距設(shè)置為10px

fabric.Object.prototype.padding = 10;

// 修改控制點(diǎn)的形狀,默認(rèn)為`rect`矩形,可選的值還有`circle`圓形

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

// 修改控制點(diǎn)的填充色為白色

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

//將控制線默認(rèn)的淺藍(lán)色改為 #dc143c,

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

// 修改控制點(diǎn)的大小為10px

fabric.Object.prototype.cornerSize = 10;

// 設(shè)置控制點(diǎn)不透明,即可以蓋住其下的控制線

fabric.Object.prototype.transparentCorners = false;

// 修改控制點(diǎn)的邊框顏色為`gray`灰色

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

// 單獨(dú)修改旋轉(zhuǎn)控制點(diǎn)距離主體的縱向距離為-20px

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

// 單獨(dú)修改旋轉(zhuǎn)控制點(diǎn),光標(biāo)移動(dòng)到該點(diǎn)上時(shí)的樣式為`pointer`,一個(gè)手的形狀

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

//旋轉(zhuǎn)控制點(diǎn)和主體之間一般沒有那條控制線,這里我們對(duì)它進(jìn)行隱藏。

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

/*控制選中邊框 stop*/

/*控制選中邊框 旋轉(zhuǎn)圖標(biāo) start*/


// 渲染圖標(biāo)的方法

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();

    };

}


// 圖標(biāo)的下載鏈接省略

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,

            // 渲染圖標(biāo)

            render: renderIcon(image._element, 0),

            // 設(shè)置控制點(diǎn)大小

            cornerSize: 30

        });

    }

};

fabric.Image.fromURL(iconURL, callback);


/*控制選中邊框 旋轉(zhuǎn)圖標(biāo) stop*/


/*控制選中邊框 增加自對(duì)應(yīng)圖標(biāo) start*/


// 從畫布中刪除當(dāng)前選中的對(duì)象

function deleteObject() {

    // 獲取畫布當(dāng)前選中的對(duì)象

    let activeObject = canvas.getActiveObject();

    if (activeObject) {

        canvas.remove(activeObject);

        canvas.renderAll();

    }

}


// 垃圾桶圖標(biāo)的下載鏈接

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

const deletecallback = (img, isError) => {

    console.log(img);

    if (!isError) {

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

            // x和y設(shè)置該控制點(diǎn)和第二列中間的控制點(diǎn)重合

            x: 0,

            y: -0.5,

            // offsetX和offsetY設(shè)置該控制點(diǎn)在水平和豎直兩個(gè)方向上

            // 偏移的距離(單位px)

            offsetX: 28,

            offsetY: -20,

            // 光標(biāo)移動(dòng)到該控制點(diǎn)時(shí)變?yōu)橐粋€(gè)手的圖標(biāo)

            cursorStyle: 'pointer',

            // 自定義的值,可忽略

            actionName: "delete",

            // 設(shè)置當(dāng)點(diǎn)擊了該控制點(diǎn),鼠標(biāo)彈起是執(zhí)行的動(dòng)作處理方法

            mouseUpHandler: () => deleteObject(),

            //渲染圖標(biāo)

            render: renderIcon(img._element, 0),

            cornerSize: 39

        });

    }

};

fabric.Image.fromURL(deleteIconURL, deletecallback);


/*控制選中邊框 增加自對(duì)應(yīng)圖標(biāo) 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, // 控件將不顯示,并且不能用于操作對(duì)象

});


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()); // 輸出序列化的內(nèi)容

    this.href = canvas.toDataURL({

        format: 'png',

        quality: 0.8

    });

    this.download = 'canvas.png';

}




該文章在 2023/5/23 10:36:40 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
亚洲中文字幕精品有码在线 | 中文字幕日韩一级 | 亚洲第一网站a√在线观看 午夜福利网站你懂得 | 亚洲国产欧美在线人网站 | 在线免费看网站午夜 | 在线播放真实国产乱子伦 |