摘要:海報(bào)生成示例最近智酷君在做小程序生成海報(bào)的項(xiàng)目中遇到一些棘手的問題,在網(wǎng)上查閱了各種資料,也踩扁了各種坑,智酷君希望把這些填坑經(jīng)驗(yàn)整理一下分享出來,避免后來的兄弟重復(fù)掉坑。
海報(bào)生成示例
最近智酷君在做[小程序]canvas生成海報(bào)的項(xiàng)目中遇到一些棘手的問題,在網(wǎng)上查閱了各種資料,也踩扁了各種坑,智酷君希望把這些“填坑”經(jīng)驗(yàn)整理一下分享出來,避免后來的兄弟重復(fù)“掉坑”。
原型圖
這是一個大致的原型圖,下面來看下如何制作這個海報(bào),以及整體的思路。
海報(bào)生成流程
### [代碼片段]Canvas生成海報(bào)實(shí)戰(zhàn)demo
demo的微信路徑:https://developers.weixin.qq....
demo的ID:Q74OU3m57c9x
如果你裝了IDE工具,可以直接訪問上面的demo路徑
通過代碼片段將demo的ID輸入進(jìn)去也可添加:
下面分享下主要的代碼內(nèi)容和“填坑現(xiàn)場”:一、添加字體
https://developers.weixin.qq.com/miniprogram/dev/api/canvas/font.html
canvasContext.font = value //示例 ctx.font = `normal bold 20px sans-serif`//設(shè)置字體大小,默認(rèn)10 ctx.setTextAlign("left"); ctx.setTextBaseline("top"); ctx.fillText("《智酷方程式》專注研究和分享前端技術(shù)", 50, 15, 250)//繪制文本
符合 CSS font 語法的 DOMString 字符串,至少需要提供字體大小和字體族名。默認(rèn)值為 10px sans-serif
文字過長在canvas下?lián)Q行問題處理(最多兩行,超過“...”代替)ctx.setTextAlign("left"); ctx.setFillStyle("#000");//文字顏色:默認(rèn)黑色 ctx.font = `normal bold 18px sans-serif`//設(shè)置字體大小,默認(rèn)10 let canvasTitleArray = canvasTitle.split(""); let firstTitle = ""; //第一行字 let secondTitle = ""; //第二行字 for (let i = 0; i < canvasTitleArray.length; i++) { let element = canvasTitleArray[i]; let firstWidth = ctx.measureText(firstTitle).width; //console.log(ctx.measureText(firstTitle).width); if (firstWidth > 260) { let secondWidth = ctx.measureText(secondTitle).width; //第二行字?jǐn)?shù)超過,變?yōu)?.. if (secondWidth > 260) { secondTitle += "..."; break; } else { secondTitle += element; } } else { firstTitle += element; } } //第一行文字 ctx.fillText(firstTitle, 20, 278, 280)//繪制文本 //第二行問題 if (secondTitle) { ctx.fillText(secondTitle, 20, 300, 280)//繪制文本 }
通過 ctx.measureText 這個方法可以判斷文字的寬度,然后進(jìn)行切割。
(一行字允許寬度為280時,判斷需要寫小點(diǎn),比如260)
let mainImg = "https://demo.com/url.jpg"; wx.getImageInfo({ src: mainImg,//服務(wù)器返回的圖片地址 success: function (res) { //處理圖片縱橫比例過大或者過小的問題?。?! let h = res.height; let w = res.width; let setHeight = 280, //默認(rèn)源圖截取的區(qū)域 setWidth = 220; //默認(rèn)源圖截取的區(qū)域 if (w / h > 1.5) { setHeight = h; setWidth = parseInt(280 / 220 * h); } else if (w / h < 1) { setWidth = w; setHeight = parseInt(220 / 280 * w); } else { setHeight = h; setWidth = w; }; console.log(setWidth, setHeight) ctx.drawImage(res.path, 0, 0, setWidth, setHeight, 20, 50, 280, 220); ctx.draw(true); }, fail: function (res) { //失敗回調(diào) } });
在開發(fā)過程中如果封面圖無法按照約定的比例(280x220)給到:
那么我們就需要處理默認(rèn)封面圖過大或者過小的問題,大致思路是:代碼中通過比較縱橫比(280/220=1.27)正比例放大或者縮小原圖,然后從左上切割,竟可能保證過高的圖是寬度100%,過寬的圖是高度100%。
在canvas中draw圖片,必須是一個(相對)本地路徑,我們可以通過將圖片保存在本地后生成的臨時路徑。
微信官方提供兩個API:
wx.downloadFile(OBJECT)和wx.getImageInfo(OBJECT)。都需先配置download域名才能生效。
ctx.save(); //保存畫圖板 ctx.beginPath()//開始創(chuàng)建一個路徑 ctx.arc(35, 25, 15, 0, 2 * Math.PI, false)//畫一個圓形裁剪區(qū)域 ctx.clip()//裁剪 ctx.closePath(); ctx.drawImage(headImageLocal, 20, 10, 30, 30); ctx.draw(true); ctx.restore()//恢復(fù)之前保存的繪圖上下文
使用圖形上下文的不帶參數(shù)的clip()方法來實(shí)現(xiàn)Canvas的圖像裁剪功能。該方法使用路徑來對Canvas話不設(shè)置一個裁剪區(qū)域。因此,必須先創(chuàng)建好路徑。創(chuàng)建完整后,調(diào)用clip()方法來設(shè)置裁剪區(qū)域。
需要注意的是裁剪是對畫布進(jìn)行的,裁切后的畫布不能恢復(fù)到原來的大小,也就是說畫布是越切越小的,要想保證最后仍然能在canvas最初定義的大小下繪圖需要注意save()和restore()。畫布是先裁切完了再進(jìn)行繪圖。并不一定非要是圖片,路徑也可以放進(jìn)去~
ctx.setFillStyle("#fff"); ctx.fillRect(0, 0, 320, 500); //第一個填充矩形 wx.downloadFile({ url: headUri, success(res) { ctx.beginPath() ctx.arc(50, 50, 25, 0, 2 * Math.PI) ctx.clip() ctx.drawImage(res.tempFilePath, 25, 25); //第二個填充圖片 ctx.draw() ctx.restore() ctx.setFillStyle("#fff"); ctx.fillRect(0, 0, 320, 500); ctx.draw(true) ctx.restore() } })
clip裁切這個功能,如果有超過一張圖片/背景疊加,則裁切效果失效。
錯誤參考:http://html51.com/info-38753-1/
wx.canvasToTempFilePath({ fileType: "jpg", canvasId: "customCanvas", success: (res) => { console.log(res.tempFilePath) //為canvas的虛擬地址 } }) res: { errMsg: "canvasToTempFilePath:ok", tempFilePath: "http://tmp/wx02935bb29080a7b4.o6zAJswFAuZuKQ5NZfPr….cGnD1a02PlVC0b3284be3a41d08986c2477579a5fd8e.jpg" }
這里需要把canvas里面的內(nèi)容,導(dǎo)出成一個臨時地址才能保存在相冊,比如:
http://tmp/wx02935bb29080a7b4...
wx.getSetting({ success(res) { console.log(res) if (!res.authSetting["scope.writePhotosAlbum"]) { //判斷權(quán)限 wx.authorize({ //獲取權(quán)限 scope: "scope.writePhotosAlbum", success() { console.log("授權(quán)成功") //轉(zhuǎn)化路徑 self.saveImg(); } }) } else { self.saveImg(); } } })
判斷是否有訪問相冊的權(quán)限,如果沒有,則請求權(quán)限。
六、保存到用戶手機(jī)本地相冊wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: function (data) { wx.showToast({ title: "保存到系統(tǒng)相冊成功", icon: "success", duration: 2000 }) }, fail: function (err) { console.log(err); if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") { console.log("當(dāng)初用戶拒絕,再次發(fā)起授權(quán)") wx.openSetting({ success(settingdata) { console.log(settingdata) if (settingdata.authSetting["scope.writePhotosAlbum"]) { console.log("獲取權(quán)限成功,給出再次點(diǎn)擊圖片保存到相冊的提示。") } else { console.log("獲取權(quán)限失敗,給出不給權(quán)限就無法正常使用的提示") } } }) } else { wx.showToast({ title: "保存失敗", icon: "none" }); } }, complete(res) { console.log(res); } })
保存到本地需要一定的時間,需要加一個loading的狀態(tài)。
七、關(guān)于組件中引用canvaslet ctx = wx.createCanvasContext("posterCanvas",this); //需要加this
在components中canvas無法選中的問題:
在components自定義組件下,當(dāng)前組件實(shí)例的this,表示在這個自定義組件下查找擁有 canvas-id 的
如果有什么疑問或者糾錯可以在下面給智酷君留言。
如果智酷君的分享能夠幫助到你,或者想持續(xù)獲得最新的全棧攻略
可以在segmentfault關(guān)注我,或在VX搜索“ Geek_Club ”或者“ 智酷方程式 ”
掃描關(guān)注公眾號
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/109772.html
摘要:組件模板與組件數(shù)據(jù)結(jié)合后生成的節(jié)點(diǎn)樹,將被插入到組件的引用位置上。事件用于子組件向父組件傳遞數(shù)據(jù),可以傳遞任意數(shù)據(jù)。官方文檔往期回顧填坑手冊小程序生成海報(bào)一拆彈時刻小程序生成海報(bào)二 showImg(https://user-gold-cdn.xitu.io/2019/6/19/16b6e94bcde767a1?w=1069&h=652&f=jpeg&s=120912); 小程序目錄結(jié)構(gòu)...
摘要:發(fā)帖的功能只要理清思路,其實(shí)并不復(fù)雜,利用機(jī)器做內(nèi)容審查是關(guān)鍵,直接關(guān)系到小程序的整體安全。內(nèi)容檢查重點(diǎn)由于內(nèi)容安全對于小程序運(yùn)營至關(guān)重要,稍有不慎就容易導(dǎo)致小程序被封,所以在這塊的校驗(yàn)除了常規(guī)人工檢查外,我們還可以用到微信的內(nèi)容安全。 showImg(https://segmentfault.com/img/remote/1460000019955210?w=658&h=440); ...
摘要:往期回顧打怪升級小程序評論回復(fù)和發(fā)貼功能實(shí)戰(zhàn)二填坑手冊小程序生成海報(bào)一拆彈時刻小程序生成海報(bào)二填坑手冊小程序目錄結(jié)構(gòu)和組件使用心得 showImg(https://segmentfault.com/img/remote/1460000019733090?w=818&h=516); 在學(xué)習(xí)成長的過程中,常常會遇到一些自己從未接觸的事物,這就好比是打怪升級,每次打倒一只怪,都會獲得經(jīng)驗(yàn),讓...
摘要:注意如果用戶一開始沒有微信授權(quán),生成海報(bào)時又必須要用戶頭像不能使用默認(rèn)的話,那就只能老老實(shí)實(shí)走之前的流程了。組件名稱終端類型微信版本觸發(fā)方法關(guān)于的調(diào)用方法相冊權(quán)限需要你提供保存相冊權(quán)限獲取相冊權(quán)限成功,給出再次點(diǎn)擊圖片保存到相冊的提示。 showImg(https://segmentfault.com/img/bVbs5V8?w=343&h=517);海報(bào)生成示例 海報(bào)生成速度緩慢...
摘要:全屏蒙版彈窗遮不住的層級還是很高的,當(dāng)出現(xiàn)全屏蒙版彈窗時,是無法蓋住的,可以調(diào)用微信的,不過需要注意兼容低版本在類設(shè)置的顏色并沒有變化。 從6月份開始到現(xiàn)在,寫小程序?qū)⒔?個月了開發(fā)時給自己埋了不少坑~給大家分享下我的填坑經(jīng)驗(yàn)~~ 開發(fā)部分 1.小程序的組件修改不能觸發(fā)頁面刷新?需要在父級文件上保存下才會觸發(fā)(使用wepy開發(fā)) 2.接口請求出現(xiàn)的問題?記得勾選調(diào)試開發(fā)工具上 不校驗(yàn)...
閱讀 2742·2021-11-17 17:01
閱讀 2122·2021-09-28 09:35
閱讀 3642·2021-09-01 11:04
閱讀 923·2020-06-22 14:41
閱讀 3011·2019-08-30 15:55
閱讀 2630·2019-08-30 15:43
閱讀 2365·2019-08-26 13:54
閱讀 2543·2019-08-26 13:48