狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

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

強大的Canvas開源庫Fabric.js簡介與開發(fā)指南

admin
2023年5月23日 15:50 本文熱度 2815


什么是Fabric.js

Fabric.js 是一個強大且簡單的Javascript HTML5 Canvas庫。

官網(wǎng)地址:http://fabricjs.com/?

為什么要使用Fabric.js?

Canvas提供一個好的畫布能力, 但是Api不夠友好。繪制簡單圖形其實還可以, 不過做一些復雜的圖形繪制, 編寫一些復雜的效果,就不是那么方便了。Fabric.js就是為此而開發(fā),它主要用對象的方式去編寫代碼。

Fabric.js能做的事情

  • 在Canvas上創(chuàng)建、填充圖形(包括圖片、文字、規(guī)則圖形和復雜路徑組成圖形)。

  • 給圖形填充漸變顏色。

  • 組合圖形(包括組合圖形、圖形文字、圖片等)。

  • 設置圖形動畫及用戶交互。

  • 生成JSON、SVG數(shù)據(jù)等。

  • 生成Canvas對象自帶拖拉拽功能。

它提供了靈活豐富的Api和可配置化參數(shù)輕松實現(xiàn)復雜的效果,該開源庫已被許多開發(fā)者用于項目實踐中,廣受好評。

下載趨勢圖


項目開發(fā)實戰(zhàn)

這里基于React框架為基礎,介紹Fabric.js開發(fā)實戰(zhàn)實例。

1、安裝Fabric.js

npm install fabric --save

yarn add fabric

官網(wǎng)還支持按需模塊定制構建,在你需要的特性模塊前面勾選,然后一鍵構建。這樣可以使得你整體的代碼量減少。


2、引入Fabric.js
import {fabric} from 'fabric';
3、initCanvas 畫布初始化

//創(chuàng)建畫布

let canvasObj = new fabric.Canvas('snackCanvas');

//設置畫布背景色

canvasObj.setBackgroundColor('#d5d5d5');

//設置畫布寬度

canvasObj.setWidth(this.state.canvasWidth);

//設置畫布高度

canvasObj.setHeight(this.state.canvasHeight);

//標識畫布中元素選中時,是否還按原有的層級位置展示

canvasObj.preserveObjectStacking = true;/**

* 設置元素選中框的樣式

*/

//邊角節(jié)點背景透明 false

fabric.Object.prototype.transparentCorners = false;

//邊角節(jié)點大小

fabric.Object.prototype.cornerSize = 6;

//邊框顏色

fabric.Object.prototype.borderColor = 'rgba(83,152,248,1)';

//角節(jié)點內(nèi)部顏色

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

//角節(jié)點邊框顏色

fabric.Object.prototype.cornerStrokeColor = 'rgba(83,152,248,1)';/**

* 設置對象位置Left/Top的基準參考位置為自身中心點

* 默認 對象采用相對自身中心點旋轉,即centeredRotation=true

*/

fabric.Object.prototype.originX = 'center';

fabric.Object.prototype.originY = 'center';this.editor = canvasObj;

4、畫布事件監(jiān)聽

//元素點擊選中事件處理

canvasObj.on('selection:created', function(options) {

  //console.log('selection:created');

  //console.log(options);

  if (options.target) {

    // TODO

  }

}

//元素選中更新事件處理

canvasObj.on('selection:updated', function(options) {

  //console.log('selection:updated');

  //console.log(options);

  if (options.target) {

    // TODO

  }

}

//元素取消選中事件處理

canvasObj.on('selection:cleared', function(options) {

  //console.log('selection:cleared');

}

//對象移動完畢事件處理

canvasObj.on('object:moved', function(options) {

  //console.log('moved');

  //console.log(options);

  if (options.target) {}

}

//對象旋轉完成事件處理

canvasObj.on('object:rotated', function(options) {

  //console.log('rotated');

  //console.log(options);

  if (options.target) {

    // TODO

  }

}

//對象縮放完成事件處理

canvasObj.on('object:scaled', function(options) {

  //console.log('scaled');

  //console.log(options);

  if (options.target) {}

}

//對文本編輯修改后

canvasObj.on('text:changed', function(options) {

  //console.log('text:changed');

  //console.log(options);

  if (options.target) {}

}

5、畫布拖拽事件處理

/**

* 拖拽事件處理 start

*/

document.addEventListener('dragstart', function(e){

  //拖拽圖片,并傳遞對象

  if(e.target.className == 'img'){

    scope.mouseX = e.offsetX;scope.mouseY = e.offsetY;

    //拖拽數(shù)據(jù)

    let sourceStr = e.target.dataset.source;

    if(sourceStr){scope.dragData = JSON.parse(sourceStr);}

    scope.figureType = e.target.className;

  }

}, false);

document.addEventListener('dragover', function(e){e.preventDefault();}, false);

//拖拽動作

this.dragObj('drop');

dragObj(eventName){

  let scope = this;

  this.editor.on(eventName, function(opt){if((opt.e.target.className).trim() == 'upper-canvas'){scope.dragEvt(eventName, opt);}});

}

dragEvt(eventName, opt){

  let scope = this;

  if(eventName == 'dragover'){opt.e.preventDefault();}else if(eventName == 'drop'){//拖拽結束opt.e.preventDefault();//console.log(this.dragData);////對拖拽數(shù)據(jù)進行業(yè)務處理//}

}

/**

* 拖拽事件處理 end 

*/

6、畫布中的圖片加載

const dragImageUrl = this.dragData.imageUrl;

fabric.Image.fromURL(dragImageUrl, function(image){

  image.set({id: getUUID(),left: imageLeft, top: imageTop,width: nodeWidth,height: nodeHeight,classname: 'img',source: scope.dragData,selectable,hasContorls}).scale(scope.state.canvasScale, scope.state.canvasScale).setCoords();

  //添加到畫布

  scope.editor.add(image);

  //設置當前素材為選中狀態(tài)

  scope.editor.setActiveObject(image);

  //重新渲染

  scope.editor.requestRenderAll();

});

7、畫布中的字體庫加載

//加載字體庫數(shù)據(jù), 默認load()方法 超時時長默認為3秒鐘

loadAndUse(object, fontName, scope) {

  let myfont = new FontFaceObserver(fontName);

  myfont.load(null, 5000).then(function() {

    // when font is loaded, use it.

    if(object){

      object.source.fontFamily = fontName;

      object.set("fontFamily", fontName).setCoords();

      scope.editor.requestRenderAll();

    }

  }).catch(function(e){console.log(e);alert('字體 ' + fontName + ' 加載失敗。');});

}

//字體方法的使用

this.loadAndUse(null, '宋體', this);

8、畫布內(nèi)容轉換成圖片保存到后臺

saveData(){

  ... 省略其他代碼 ...

  let paramData = new FormData();

  let dataUrl = this.editor.toDataURL();

  let blobImage = this.dataURLtoBlob(dataUrl);

  blobImage.contentType = 'application/octet-stream';

  paramData.append("file", blobImage);

  ... 省略其他代碼 ...

}

//數(shù)據(jù)類型轉換

dataURLtoBlob(dataurl){

  let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);

  while(n--){u8arr[n] = bstr.charCodeAt(n);}

  return new Blob([u8arr], {type:'application/octet-stream'});

}

9、畫布Canvas繪制的元素合并為一組

將兩個元素深深地綁定在一起,任何操作同時對兩個有效,這里叫組的概念

const circle = new fabric.Circle({radius: 100,fill: '#eef',scaleY: 0.5,originX: 'center',originY: 'center'});

const text = new fabric.Text('hello world', {fontSize: 30,originX: 'center',originY: 'center'});

const group = new fabric.Group([circle, text], {left: 150,top: 100,angle: -10});

9、Canvas畫布中將兩個元素之間建立BOSS關系

怎么理解就是將一個元素變?yōu)榱硪粋€元素的boss,boss元素拖動旋轉操作,另一個元素跟著同樣變,但是反過來就不行

bindMinionToBoss(canvas: fabric.Canvas, boss: fabric.Group): void {

  const minions = canvas.getObjects().filter((o: any) => o !== boss);const bossTransform = boss.calcTransformMatrix();

  const invertedBossTransform = fabric.util.invertTransform(bossTransform);

  minions.forEach((o: any) => {const desiredTransform = fabric.util.multiplyTransformMatrices(invertedBossTransform,o.calcTransformMatrix());o.relationship = desiredTransform;});

  boss.on("moving", () => {

    minions.forEach((o: any) => {

    if (!o.relationship) return;

    const newTransform = fabric.util.multiplyTransformMatrices(boss.calcTransformMatrix(),o.relationship);const opt = fabric.util.qrDecompose(newTransform);const point = new fabric.Point(opt.translateX, opt.translateY);o.setPositionByOrigin(point, "center", "center");o.set(opt);o.setCoords();

    });

  });

}

其他詳細Api請參見:

http://fabricjs.com/docs/

另外還有很多好玩有趣的功能等著我們?nèi)グl(fā)現(xiàn),可以參照官網(wǎng)的例子:

http://fabricjs.com/demos/

如果使用中出現(xiàn)常見問題,優(yōu)先參考:

http://fabricjs.com/fabric-gotchas


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