canvas操作插件fabric.js使用方法詳解
fabric.js是一個(gè)很好用的 canvas 操作插件,下面整理了一些平時(shí)項(xiàng)目中用到的知識(shí)點(diǎn):
//1: 獲得畫(huà)布上的所有對(duì)象:
var items = canvas.getObjects();
//2: 設(shè)置畫(huà)布上的某個(gè)對(duì)象為活動(dòng)對(duì)象。
canvas.setActiveObject(items[i]);
//3:獲得畫(huà)布上的活動(dòng)對(duì)象
canvas.getActiveObject()
//4:取消畫(huà)布中的所有對(duì)象的選中狀態(tài)。
canvas.discardActiveObject();
//5: 設(shè)置畫(huà)布中的對(duì)象的某個(gè)屬性值,比如第 0 個(gè)對(duì)象的 id
var items = canvas.getObjects();
tems[0].id ="items_id0" 或 items[0].set("id","items_id0")
//6:獲得畫(huà)布中對(duì)象的某個(gè)屬性,比如 第0 個(gè)對(duì)象的 id
var items = canvas.getObjects();
items[0].id;
//或
items[0].get("id");
//7: 重新渲染一遍畫(huà)布,當(dāng)畫(huà)布中的對(duì)象有變更,在最后顯示的時(shí)候,需要執(zhí)行一次該操作
canvas.renderAll()
//8: 清除畫(huà)布中所有對(duì)象:
canvas.clear();
//9:清除畫(huà)布中的活動(dòng)對(duì)象:
var t = canvas.getActiveObject();
t && canvas.remove(t);
//10: 設(shè)置活動(dòng)對(duì)象在畫(huà)布中的層級(jí)
var t = canvas.getActiveObject();
canvas.sendBackwards(t) //向下跳一層
canvas.sendToBack(t) //向下跳底層:
canvas.bringForward(t) //向上跳一層:
canvas.bringToFront(t) //向上跳頂層:
//或者:
t.sendBackwards();
t.sendToBack();
t.bringForward();
t.bringToFront();
//10:加載圖片時(shí)圖片縮放到指定的大小。
fabric.Image.fromURL(image_src, function(oImg) {
oImg.set({
left:tmp_left,
top:tmp_top,
centeredScaling:true,
cornerSize: 7,
cornerColor: "#9cb8ee",
transparentCorners: false,
});
oImg.scaleToWidth(image_width);
oImg.scaleToHeight(image_height);
canvas.add(oImg).setActiveObject(oImg);
});
//11:當(dāng)選擇畫(huà)布中的對(duì)象時(shí),該對(duì)象不出現(xiàn)在頂層。
canvas.preserveObjectStacking = true;
// 12:為畫(huà)布通過(guò)URL方式添加背景圖片
var bg_url = "http://www.xxxx.com/...../bg.png"
fabric.Image.fromURL( bg_url , function(oImg) {
oImg.set({
width: canvas_obj.width,
height: canvas_obj.height,
originX: 'left',
originY: 'top'
});
canvas_obj.setBackgroundImage(oImg, canvas_obj.renderAll.bind(canvas_obj));
});
//13: originx: originy:代表坐標(biāo)系。

//14: 畫(huà)布對(duì)象居中設(shè)置:
var t = canvas.getActiveObject();
t.center(); //全部居中
t.centerH(); //水平居中
t.centerV(); //垂直居中
t.setCoords(); //注:必須設(shè)coords以上設(shè)置才會(huì)有效。
//15: 當(dāng)對(duì)象移動(dòng)時(shí) 限制對(duì)象的 不超出畫(huà)布
// canvas moving limit
function objectMoving(e){
var obj = e.target;
if(obj.currentHeight > obj.canvas.height || obj.currentWidth > obj.canvas.width){
return;
}
obj.setCoords();
// top-left corner
if(obj.getBoundingRect().top < 0 || obj.getBoundingRect().left < 0){
obj.top = Math.max(obj.top, obj.top-obj.getBoundingRect().top);
obj.left = Math.max(obj.left, obj.left-obj.getBoundingRect().left);
}
// bot-right corner
if(obj.getBoundingRect().top+obj.getBoundingRect().height > obj.canvas.height
|| obj.getBoundingRect().left+obj.getBoundingRect().width > obj.canvas.width){
obj.top = Math.min(obj.top, obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top);
obj.left = Math.min(obj.left, obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left);
}
}
//16:當(dāng)畫(huà)布對(duì)象放大時(shí)限制其操出邊界:
//注意當(dāng)創(chuàng)建對(duì)象到畫(huà)布上時(shí)必須先加上:
obj.saveState();
//在對(duì)象修改時(shí)方法里就可以調(diào)用了。
function objectModified (e) {
let obj = e.target;
let boundingRect = obj.getBoundingRect(true);
if (boundingRect.left < 0
|| boundingRect.top < 0
|| boundingRect.left + boundingRect.width > obj.canvas.getWidth()
|| boundingRect.top + boundingRect.height > obj.canvas.getHeight()) {
obj.top = obj._stateProperties.top;
obj.left = obj._stateProperties.left;
obj.angle = obj._stateProperties.angle;
obj.scaleX = obj._stateProperties.scaleX;
obj.scaleY = obj._stateProperties.scaleY;
obj.setCoords();
obj.saveState();
}else{
obj.saveState();
}
}
//17:當(dāng)生成json對(duì)象時(shí),背景圖片顯示出來(lái)。
fabric.Image.fromURL( bgImg, function(oImg) {
oImg.set({
width: 400,
height:400,
left:0,
top:0,
originX: 'left',
originY: 'top',
opacity:0
});
//當(dāng)toObject方法時(shí)顯示背景圖片。
oImg.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
opacity:1
});
};
})(oImg.toObject);
canvas_obj.setBackgroundImage(oImg, canvas_obj.renderAll.bind(canvas_obj));
}, { crossOrigin: 'Anonymous' });
//18:創(chuàng)建蒙版層
//獲取蒙版位置屬性(非必要):
var maskLayerTop = parseInt($(this).attr("data-top"));
var maskLayerLeft = parseInt($(this).attr("data-left"));
var maskLayerWidth = parseInt($(this).attr("data-width"));
var maskLayerHeight = parseInt($(this).attr("data-height"));
//創(chuàng)建蒙版
var clipMask = new fabric.Rect({
originX: 'left',
originY: 'top',
left: maskLayerLeft,
top: maskLayerTop,
width: maskLayerWidth,
height: maskLayerHeight,
fill: 'rgba(0,0,0,0)',
strokeWidth:0,
selectable: false
});
clipMask.set({
clipFor: 'pug'
});
canvas_obj.add(clipMask);
function degToRad(degrees) {
return degrees * (Math.PI / 180);
}
function findByClipName(name){
return _(canvas_obj.getObjects()).where({
clipFor: name
}).first()
}
canvas_obj.clipByName = function(ctx) {
this.setCoords();
var clipObj = findByClipName(this.clipName);
var scaleXTo1 = (1 / this.scaleX);
var scaleYTo1 = (1 / this.scaleY);
var skewXReverse = - this.skewX;
var skewYReverse = - this.skewY;
ctx.save();
var ctxLeft = -( this.width / 2 ) + clipObj.strokeWidth;
var ctxTop = -( this.height / 2 ) + clipObj.strokeWidth;
var ctxWidth = clipObj.width - clipObj.strokeWidth;
var ctxHeight = clipObj.height - clipObj.strokeWidth;
ctx.translate( ctxLeft, ctxTop );
ctx.scale(scaleXTo1, scaleYTo1);
ctx.transform(1, skewXReverse, skewYReverse, 1, 0, 0);
ctx.rotate(degToRad(this.angle * -1));
ctx.beginPath();
ctx.rect(
clipObj.left - this.oCoords.tl.x,
clipObj.top - this.oCoords.tl.y,
clipObj.width,
clipObj.height
);
ctx.closePath();
ctx.restore();
}
//調(diào)用的地方:
//文字層設(shè)置蒙版
var t = new fabric.Text("Your Text", {
id: first_level+"-text-input"+unique_id,
cornerSize: 7,
cornerColor: "#9cb8ee",
transparentCorners: false,
textAlign:"center",
clipName: 'pug',
clipTo: function(ctx) {
return _.bind(tmp_canvas_obj.clipByName, t)(ctx)
}
});
// 圖片層設(shè)置蒙版:
// add the forntimage to the canvas
fabric.Image.fromURL(image_src, function(oImg) {
oImg.set({
id:first_level+"-image-input"+unique_id,
left:tmp_left,
top:tmp_top,
centeredScaling:true,
cornerSize: 7,
cornerColor: "#9cb8ee",
transparentCorners: false,
clipName: 'pug',
clipTo: function(ctx) {
return _.bind(tmp_canvas_obj.clipByName, oImg)(ctx)
}
});
//19:生成的圖片縮放到指定的尺寸。
oImg.scaleToWidth(image_width);
oImg.scaleToHeight(image_height);
//20:to object 時(shí)添加 id屬性。
oImg.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
id: this.id,
});
};
})(oImg.toObject);
oImg.id = first_level+"-image-input"+unique_id;
oImg.saveState();
tmp_canvas_obj.add(oImg).setActiveObject(oImg);
}, { crossOrigin: 'Anonymous' });
tmp_canvas_obj.renderAll();
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
微信小程序頁(yè)面滑動(dòng)屏幕加載數(shù)據(jù)效果
這篇文章主要為大家詳細(xì)介紹了微信小程序頁(yè)面滑動(dòng)屏幕加載數(shù)據(jù)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
js中的escape及unescape函數(shù)的php實(shí)現(xiàn)代碼
js中的escape及unescape函數(shù)的php實(shí)現(xiàn)代碼...2007-09-09
JS原生數(shù)據(jù)雙向綁定實(shí)現(xiàn)代碼
本文通過(guò)實(shí)例代碼給大家介紹了JS原生數(shù)據(jù)雙向綁定問(wèn)題,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-08-08
JS、CSS和HTML實(shí)現(xiàn)注冊(cè)頁(yè)面
這篇文章主要為大家詳細(xì)介紹了JS、CSS和HTML實(shí)現(xiàn)注冊(cè)頁(yè)面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
JavaScript查看代碼運(yùn)行效率console.time()與console.timeEnd()用法
今天小編就為大家分享一篇關(guān)于JavaScript查看代碼運(yùn)行效率console.time()與console.timeEnd()用法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01
JavaScript利用el-table實(shí)現(xiàn)繪制熱度表
這篇文章主要為大家詳細(xì)介紹了JavaScript如何利用el-table實(shí)現(xiàn)繪制熱度表,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03
從數(shù)據(jù)結(jié)構(gòu)的角度分析 for each in 比 for in 快的多
今天仔細(xì)琢磨了會(huì),從數(shù)據(jù)結(jié)構(gòu)的角度分析了下,覺(jué)得for in和for each in效率上有著本質(zhì)的區(qū)別,無(wú)論是JS還是AS2013-07-07

