近期公司項目中有一個定制卡封面需求,是將幾張圖片融合成一張,并可以切換卡片橫豎版的效果,最終需求如圖:
這個需求乍一聽起來并沒有什么問題,只要看下小程序畫布API就可以,但是實際上遇到的問題我花費兩個晚上才基本解決,而且還有一個至今無法解決的問題也希望大家給出寶貴建議!
知道大家不喜歡墨跡,我先上完整代碼,如果大家著急需要,直接過去拿代碼就可以了,里面注釋很豐富!如果可以希望大家給文章點個贊,碼農不易感謝支持!
GitHub - BaoYuHan/applet-canvas-image: 微信小程序使用canvas圖片合成案例及相關踩坑處理
如果各位同學感興趣,那可以往下看我的思路流程和踩坑記錄、注意事項……
思路流程圖:
坑:canvas的隱藏問題:
對于切換橫豎屏時隱藏相應的canvas這個實現,首先大家想到的肯定是wx:if,但是很遺憾,并不好使,網上查閱相關資料后發現可以添加一個父盒子寬高0+overflow:hidden,模擬器完美運行,跑到真機上還是無效。最后發現大家都是用了一個終極辦法,那就是送他離開千里之外~的position:fixed+left:10000px讓canvas在不該用戶看到的時候滾出屏幕
注意點1:用戶操作:用一張能鋪滿canvas的圖片合成,后再次點擊選擇圖片,用一張不能鋪滿canvas的圖片合成
我這里的圖片裁剪,模擬的是aspectFill模式,保證短邊完全顯示,長邊裁剪,可能會出現圖片不能鋪滿屏幕的情況,這時候如果用戶復現上述操作,沒鋪滿的剩余空間會顯示上次繪制的內容,體驗很不好。所以要在用戶選擇圖片成功后,注意是成功,調用ctx.draw()使用填充色繪制一遍,即清空canvas
注意點2:不需要處理圖片裁剪以及不使用網絡圖片的同學可以不用wx.getImageInfo
我的代碼中使用了wx.getImageInfo用于獲取圖片信息來裁剪圖片,不需要的同學可以直接在用戶選擇圖片后就開始繪制,但是注意小程序中canvas.drawImage不能使用網絡圖片,網絡圖片要通過 getImageInfo / downloadFile 先下載到本地并獲取路徑后才能繪制
注意點3:繪制圓角后,再繪制文字前注意設置填充色
我們這里繪制圓角的原理是將畫布裁剪四個弧形角,后面的內容都在這個圓角矩形中繪制,繪制圓角矩形時使用了ctx.setFillStyle('transparent'),防止圖片出現圓弧有溢出顏色的情況,所以圓角矩形繪制完后注意恢復填充色,否則文字無法繪制了。
注意點4:wx.canvasToTempFilePath獲取失敗問題
1:fail回調:官網文檔說明:在?draw()?回調里調用該方法才能保證圖片導出成功。
2. 以往的寫法需要在執行?wx.canvasToTempFilePath之前開啟一個一秒的計時器,因為生成canvas是異步的而且還需要耗費時間。但是在我開發中我發現去掉了也是沒有問題的,可能是官方補充了這里的邏輯?
未實現問題:wx.previewImage 預覽合成的圖片,點擊發送給朋友或保存圖片,圖片圓角剩余部分是黑色的,如果有能解決的小伙伴歡迎評論!
感謝文章:
1.圖片裁剪:微信小程序 畫布drawImage實現圖片截取 - Favour丶in - 博客園
2.圖片圓角:canvas圖片圓角處理