javascript他爹說了,當(dāng)初第一個(gè)版本就是花了一個(gè)星期搞出來的。人家是個(gè)lisp愛好者,但是用戶喜歡C語言,所以搞出了這么個(gè)東西。很多現(xiàn)在說是坑的東西,其實(shí)都是他為了趕deadline隨便弄出來的,沒空細(xì)想。
成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、成都外貿(mào)網(wǎng)站建設(shè)、西充網(wǎng)絡(luò)推廣、微信小程序、西充網(wǎng)絡(luò)營銷、西充企業(yè)策劃、西充品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供西充建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:www.cdcxhl.com
后來流行了,想改也晚了。web程序員喜歡說,我們就是要快,哈哈哈哈哈哈,做基礎(chǔ)設(shè)施怎么能求快呢,害人害己啊。
眾所周知,canvas的api繁雜,對(duì)一般的前端er來說不太友好,加上平時(shí)一般也不會(huì)自己手寫canvas,所以一般開發(fā)者對(duì)canvas的涉獵可能并不太深(我看紅寶書的時(shí)候canvas是直接跳過的)。而當(dāng)需要使用canvas開發(fā)一些定制化的需求時(shí),echarts,antv系列,可能就無法滿足了,這個(gè)時(shí)候或許fabric會(huì)是一個(gè)比較好的選擇,fabric提供一種類似面向?qū)ο蟮姆椒▉砭帉慶anvas,比原生稍微方便一些(然鵝官方文檔太難看懂了)
近期的一個(gè)項(xiàng)目中,有這么一個(gè)需求:拖拽縮放元素并且進(jìn)行連線,本來我第一反應(yīng)是用antv/g6去實(shí)現(xiàn)的,但是需要對(duì)拖拽的元素縮放并且拖拽的容器需要放文字和圖表,如果使用g6的話,縮放容器,里面的內(nèi)容改變不太利索(實(shí)際是我對(duì)g6不太熟),另一個(gè)重要的問題是g6元素里面放圖表的話只能放g2(而且需要單獨(dú)安裝插件)并且不支持諸如tooltip等等功能,簡單來說只能用個(gè)閹割版的(示例: )。因此我最初想的是使用 vue-grid-layout ( github 文檔 )進(jìn)行拖拽與縮放,畫線使用canvas。這樣做的好處是第三方組件已經(jīng)把拖拽和縮放功能全都封裝好了,dom元素嵌入echarts和文本縮放也相當(dāng)方便(vue-echarts的autoresize,文本使用flex布局加overflow:auto),當(dāng)然畫線又是一個(gè)大問題,關(guān)鍵點(diǎn)就是線要和拖拽的元素接上,簡而言之就是坐標(biāo)計(jì)算了??紤]到畫布里面還要放圖(拖拽的元素連線到圖上)以及要實(shí)現(xiàn)連線的時(shí)候鼠標(biāo)移動(dòng)需要不停的重繪線,最終在同事的推薦下決定使用fabric.js來實(shí)現(xiàn)canvas部分。然后就發(fā)現(xiàn)這東西用起來一言難盡...
1.官方文檔
就算你英語很好看他的文檔也會(huì)很別扭的,建議直接看 官方DEMO 找自己要的,不懂的百度谷歌,最后把查找文檔作為補(bǔ)充以及檢查是否有新版api和網(wǎng)上的古早文章不同。
2.在vue中使用
目前只能這樣用
3.繪制本地圖片有問題
我嘗試過 fabric.Image.fromURL('xxx/xxx.png',function(){}) 以及 new Image().src 這兩種發(fā)現(xiàn)貌似都不能放本地圖片地址(類似 @/assets/... 這種),可能是我使用的方式不對(duì),最后只剩下一種方法可用了:
這種方法首先需要在頁面上放一個(gè)隱藏的img元素,結(jié)果一開始fabric還讀不到只能通過 onload 事件來獲取,但這樣會(huì)導(dǎo)致畫布重繪時(shí)無法執(zhí)行onload,最后一個(gè)繪制圖片被我寫成這樣了
sendToBack 方法是為了確保在后面畫線的時(shí)候線能在圖的上面一層顯示(貌似fabric是按照先后繪制順序排層級(jí)的,先繪制的層級(jí)最高,于是我們需要將圖的層級(jí)降到最低)
可能是頁面結(jié)構(gòu)太復(fù)雜的緣故,上面的方法有小概率執(zhí)行時(shí)圖片還沒加載好,導(dǎo)致最后畫布里面其它內(nèi)容都出來了結(jié)果最重要的圖沒了,最終我搞出來的解決辦法是,在img標(biāo)簽上直接綁定load事件,執(zhí)行l(wèi)oad時(shí)將組件內(nèi)設(shè)置的狀態(tài)修改,并監(jiān)聽這個(gè)狀態(tài)的變化來執(zhí)行圖片渲染到canvas畫布的過程。
畫圖(畫線除了selectable其它類似,因?yàn)槲业捻?xiàng)目需要選中線)
因?yàn)槲倚枰c(diǎn)擊線的時(shí)候彈出刪除菜單,所以不能在初始化的時(shí)候直接 skipTargetFind: true ,我要做的是去除選中的樣式和大部分功能,保留選中時(shí)能獲取到選中對(duì)象,一旦這個(gè)屬性設(shè)為true則會(huì)取消所有選中樣式和功能,不需要在canvas對(duì)象里面再單獨(dú)配置了。
第二,計(jì)算三次貝塞爾曲線的控制點(diǎn),這里面用了向量運(yùn)算...
網(wǎng)上找的檢測屏幕縮放比例的方法(可以檢測到系統(tǒng)分辨率改變)
然后在初始化fabric對(duì)象時(shí)需要重新計(jì)算寬高(canvasLayout為畫布上一級(jí)的父元素)
pageZoom主要在拖動(dòng)元素時(shí)計(jì)算元素與線的連接點(diǎn)坐標(biāo)用到了,這個(gè)系統(tǒng)里面只要vue-grid-layout元素有改變,我就要重新計(jì)算線的起點(diǎn)并重繪線,通過這種辦法實(shí)現(xiàn)了dom元素和canvas元素的綁定,聽起來很low的樣子,不過最后功能是都實(shí)現(xiàn)了。
參考文章(還有些講fabric的api的文章找不到了...)
fabric視頻教程(我還沒看過,可能有些內(nèi)容存在過時(shí))
在leetcode上刷題的時(shí)候踩的坑,題目是這樣的
簡單思考了一下,用最簡單的雙循環(huán)就可以解決問題,于是習(xí)慣性用forEach遍歷了兩次
結(jié)果發(fā)現(xiàn)函數(shù)返回值是undefined
百度了一下,發(fā)現(xiàn)是因?yàn)閒orEach多次執(zhí)行回調(diào)函數(shù),回調(diào)函數(shù)中使用return沒法直接終止forEach,只能終止單次的回調(diào)。所以return語句在forEach內(nèi)部是無法跳出循環(huán)的。
解決方案:
1.方案一:js針對(duì)數(shù)組操作的另外兩個(gè)方法some()與every()
2.方案二:for/while語句老實(shí)循環(huán)
總結(jié)原因還是對(duì)forEach方法理解不夠到位