前端圖形學(xué)實(shí)戰(zhàn): 從零實(shí)現(xiàn)編輯器的圖層管理面板和實(shí)時(shí)縮略圖(vue3 + vite版)_獨(dú)家
hello, 大家好, 我是徐小夕, 今天又到了我們的博學(xué)時(shí)間。
本文是 100+前端幾何學(xué)應(yīng)用案例 專欄的第四篇文章, 之前和大家分享了如何從零實(shí)現(xiàn)幾何畫(huà)板以及幾何畫(huà)板的撤銷重做功能:
(資料圖片僅供參考)
今天繼續(xù)和大家分享一下幾何畫(huà)板的圖層管理和實(shí)時(shí)縮略圖的實(shí)現(xiàn)。
demo演示按照筆者的寫(xiě)作習(xí)慣, 這里先和大家演示一下實(shí)現(xiàn)的效果:
可以看到通過(guò)操作圖層面板我們可以輕松的切換到某一個(gè)元素并對(duì)元素進(jìn)行編輯, 同時(shí)在每次操作之后右下角的縮略圖會(huì)實(shí)時(shí)展示畫(huà)布最新的變動(dòng)。
源碼地址: https://gitee.com/lowcode-china/euryd
接下來(lái)就讓我們接著之前的內(nèi)容, 來(lái)實(shí)現(xiàn)我們的圖層管理面板和實(shí)時(shí)縮略圖。
技術(shù)實(shí)現(xiàn)接下來(lái)我還是用大家最最熟悉的 vue3 + ts 來(lái)實(shí)現(xiàn), 其他框架實(shí)現(xiàn)原理類似, 感興趣的朋友也可以舉一反三, 自行實(shí)現(xiàn)。
圖層管理面板主要是為了更方便管理和操作畫(huà)布中的元素, 比如 PhotoShop 里的圖層管理:
或者 H5-Dooring 頁(yè)面制作平臺(tái)的圖層面板:
我們可以從這些編輯器中總結(jié)出圖層管理的幾個(gè)主要功能:
定位或切換元素顯示隱藏元素編輯元素(如刪除)批量操作(如多選批量刪除元素等)調(diào)整元素位置(順序)所以說(shuō)我們?cè)谠O(shè)計(jì)圖層面板的時(shí)候也可以考慮以上幾個(gè)點(diǎn), 接下來(lái)我就來(lái)構(gòu)建一下圖層面板, 并實(shí)現(xiàn)切換元素,刪除指定元素 的功能。
1. 構(gòu)建圖層面板由于圖層面板的元素和畫(huà)布實(shí)際的元素?cái)?shù)據(jù)是一一對(duì)應(yīng)的, 所以我們可以直接用 canvasBox 來(lái)渲染圖層列表, 這里回顧一下 canvasBox 的數(shù)據(jù)結(jié)構(gòu):
typeshapeType="rect"|"circle"|"line";interfaceIBaseShapeProp{type:shapeType;key:string;style:any;}constcanvasBox=ref<{[keyinshapeType]:IBaseShapeProp[]}>({rect:[],circle:[],line:[],});
其中每個(gè)元素都包含如下三個(gè)關(guān)鍵屬性:
key 元素的唯一idtype 元素的類型(矩形, 圓形, 線等)style 元素的樣式這樣我們就可以利用 key 來(lái)輕松的定位元素, 如果畫(huà)布中元素很多(比如復(fù)雜的設(shè)計(jì)稿), 我們還可以給圖層面板添加搜索和分類功能, 方便我們更高效的定位元素。
一個(gè)簡(jiǎn)單實(shí)現(xiàn)的案例如下:
圖層管理
{{ item.key }} 刪除
css樣式如下:
.layerWrap{position:absolute;left:60px;margin-top:-20px;padding-top:10px;padding-bottom:10px;width:160px;background:#fff;box-shadow:0010pxrgba(0,0,0,0.1);color:#888;.layerItem{&:hover{background-color:rgba(110,38,236,0.1);}span:last-child{margin-left:20px;}}}
這里分享一下具體實(shí)現(xiàn)效果:
由于我們應(yīng)用是用vue3的組合式函數(shù)寫(xiě)的, 上圖中涉及到的切換元素和刪除元素的方法也很簡(jiǎn)單, 具體如下:
import { ref } from "vue";const curSelect = ref("");const canvasBox = ref<{ [key in shapeType]: IBaseShapeProp[] }>({ rect: [], circle: [], line: [],});// 選擇元素const handleSelected = (key: string) => { curSelect.value = key;};// 刪除元素const handleDelItem = (key: string) => { canvasBox.value.rect = canvasBox.value.rect.filter((v) => v.key !== key);};
所以說(shuō)圖層管理的本質(zhì)是基于已有的圖元進(jìn)行數(shù)據(jù)結(jié)構(gòu)層面的操作。
當(dāng)然大家也可以擴(kuò)展我們的畫(huà)板應(yīng)用, 讓它支持多選, 搜索, 排列順序等功能。
實(shí)時(shí)縮略圖的實(shí)現(xiàn)我們之前也許看過(guò)一些網(wǎng)站在瀏覽頁(yè)面的時(shí)候會(huì)出現(xiàn)小的縮略圖, 可以實(shí)時(shí)展示當(dāng)前頁(yè)面的情況, 比如:
這里就簡(jiǎn)單和大家分享一下實(shí)現(xiàn)方案。
因?yàn)槲覀冊(cè)诋?huà)布中的每一次操作都會(huì)被記錄在 recordManager (記錄管理器, 也就是上篇文章介紹的撤銷重做的歷史快照集合)中, 我們只需要在每次操作后基于當(dāng)前 dom 生成一張圖片即可(畫(huà)布如果是canvas實(shí)現(xiàn)的, miniMap實(shí)現(xiàn)起來(lái)會(huì)更簡(jiǎn)單)。
所以說(shuō)我們現(xiàn)在的問(wèn)題就變成了如何基于 dom 生成圖片快照的問(wèn)題了, 當(dāng)然這里也有解決方案, 核心思路就是將 dom 轉(zhuǎn)換成 xml 結(jié)構(gòu),然后放在
通過(guò)以上方式我們就可以原生實(shí)現(xiàn)將 dom 轉(zhuǎn)換為圖片。當(dāng)然市面上也有比較成熟的方案, 比如:
html2canvasdom2image那這里我就用 dom2image 帶大家一起實(shí)現(xiàn)一下 miniMap。
首先我們?cè)趘ite 工程中安裝該庫(kù):
yarnadddom-to-image
具體實(shí)現(xiàn):
constpushRecordFn=(state:{[keyinshapeType]:IBaseShapeProp[]},prevState:{[keyinshapeType]:IBaseShapeProp[]})=>{//生成mini縮略圖片domtoimage.toPng(boardDom?.value?.boardDom).then(function(dataUrl:string){miniImg.value=dataUrl;}).catch(function(error:Error){console.error("腳本錯(cuò)誤!",error);});const{snapshots,maxLimit,curIndex}=recordManager.value;//如果兩個(gè)狀態(tài)相同,則不推入歷史記錄if(!diff(state,snapshots[curIndex])){return;}//如果在撤銷的過(guò)程中重新執(zhí)行了新的操作,則覆蓋上一個(gè)狀態(tài)if(snapshots.length-1!==curIndex){snapshots.splice(curIndex+1,snapshots.length);}//超過(guò)了最大限制記錄if(snapshots.length>=maxLimit){snapshots.shift();}recordManager.value.snapshots.push(cloneDeep(state));recordManager.value.curIndex=recordManager.value.snapshots.length-1;};
pushRecordFn 函數(shù)就是我們之前在實(shí)現(xiàn)撤銷重做功能的快照記錄函數(shù), 如果大家對(duì)撤銷重做功能感興趣的可以參考我的文章:
前端圖形學(xué)實(shí)戰(zhàn): 100行代碼實(shí)現(xiàn)幾何畫(huà)板的撤銷重做等功能(vue3 + vite版)
好了, 以上就實(shí)現(xiàn)了我們的miniMap 縮略圖功能, 演示如下:
后面會(huì)繼續(xù)圍繞圖形可視化來(lái)實(shí)現(xiàn)更多有意思的應(yīng)用, 比如滑動(dòng)驗(yàn)證碼, 圖形編輯器, 可視化圖表等, 如果大家感興趣, 可以參考我的github: https://gitee.com/lowcode-china/euryd
如果文章對(duì)你有幫助, 歡迎點(diǎn)贊評(píng)論, 讓我們一起探索真正的前端技術(shù)。
如果想學(xué)習(xí)更多H5游戲,webpack,node,gulp,css3,javascript,nodeJS,canvas數(shù)據(jù)可視化等前端知識(shí)和實(shí)戰(zhàn),歡迎在《趣談前端》加入我們的技術(shù)群一起學(xué)習(xí)討論,共同探索前端的邊界。
從零搭建全??梢暬笃林谱髌脚_(tái)V6.Dooring
從零設(shè)計(jì)可視化大屏搭建引擎
Dooring可視化搭建平臺(tái)數(shù)據(jù)源設(shè)計(jì)剖析
可視化搭建的一些思考和實(shí)踐
基于Koa + React + TS從零開(kāi)發(fā)全棧文檔編輯器(進(jìn)階實(shí)戰(zhàn)
點(diǎn)個(gè)在看你最好看
關(guān)鍵詞: 圖層面板 數(shù)據(jù)結(jié)構(gòu) 感興趣的
相關(guān)閱讀
-
前端圖形學(xué)實(shí)戰(zhàn): 從零實(shí)現(xiàn)編輯器的圖層...
前言hello,大家好,我是徐小夕,今天又到了我們的博學(xué)時(shí)間。本文是100... -
我的一次 dumi 實(shí)戰(zhàn)!-焦點(diǎn)速訊
大家好,我是Chocolate。上周因?yàn)樘?,在b站就只發(fā)了一個(gè)視頻,本... -
前端如何主導(dǎo)ddd架構(gòu)落地(上)_全球百事通
這是一個(gè)兼具技術(shù)和劇情的故事。首先,我其實(shí)是一個(gè)全棧我當(dāng)初給我... -
Rule of 40,可能誤導(dǎo)了SaaS行業(yè)_世界獨(dú)家
一位投資人跟我說(shuō),他不太看好一個(gè)創(chuàng)業(yè)團(tuán)隊(duì),理由是他們竟然連Ruleo... -
快消息!顯卡價(jià)格水漲船高卻供不應(yīng)求,...
自從RTX?30系碰上虛擬幣市場(chǎng)大熱,顯卡價(jià)格就一飛沖天。即使今年迎... -
環(huán)球今頭條!2022年11月的一些思考!
一分鐘的思考抵得過(guò)一小時(shí)的嘮叨。人類一思考,上帝就發(fā)笑。為了上...