強大的Canvas開源庫Fabric.js簡介與開發(fā)指南
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
什么是Fabric.js?Fabric.js 是一個強大且簡單的Javascript HTML5 Canvas庫。 官網(wǎng)地址:http://fabricjs.com/ 為什么要使用Fabric.js?Canvas提供一個好的畫布能力, 但是Api不夠友好。繪制簡單圖形其實還可以, 不過做一些復雜的圖形繪制, 編寫一些復雜的效果,就不是那么方便了。Fabric.js就是為此而開發(fā),它主要用對象的方式去編寫代碼。 Fabric.js能做的事情
它提供了靈活豐富的Api和可配置化參數(shù)輕松實現(xiàn)復雜的效果,該開源庫已被許多開發(fā)者用于項目實踐中,廣受好評。 下載趨勢圖 項目開發(fā)實戰(zhàn)這里基于React框架為基礎,介紹Fabric.js開發(fā)實戰(zhàn)實例。 1、安裝Fabric.jsnpm install fabric --save 或 yarn add fabric 官網(wǎng)還支持按需模塊定制構建,在你需要的特性模塊前面勾選,然后一鍵構建。這樣可以使得你整體的代碼量減少。2、引入Fabric.jsimport {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的基準參考位置為自身中心點 * 默認 對象采用相對自身中心點旋轉(zhuǎn),即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) {} }//對象旋轉(zhuǎn)完成事件處理 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)容轉(zhuǎn)換成圖片保存到后臺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ù)類型轉(zhuǎn)換 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元素拖動旋轉(zhuǎn)操作,另一個元素跟著同樣變,但是反過來就不行 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 該文章在 2023/5/23 15:50:13 編輯過 |
關鍵字查詢
相關文章
正在查詢... |