溫州泗溪鎮(zhèn)小程序用canvas繪制海報(bào)的做法
閱讀 30040 · 發(fā)布日期 2020-08-24 17:26 · 溫州優(yōu)光網(wǎng)絡(luò)科技有限公司|建站|APP小程序制作|做網(wǎng)站SEO推廣優(yōu)化
【摘要】
2020年第一篇文章,年初忙著復(fù)習(xí)刷題一直沒(méi)空去寫(xiě)東西,書(shū)看的越多感覺(jué)越技不如人,始終徘徊在小菜雞的行列中,最近項(xiàng)目里正好有一個(gè)canvas的業(yè)務(wù),突然又燃起了我一個(gè)UI前端的火種,記下了踩坑和思考。踩坑問(wèn)題1:為什么在canvas上畫(huà)圖片模糊?在canvas上繪制圖片/文字的時(shí)候,我們?cè)O(shè)定canvas:375*667... 【溫州小程序開(kāi)發(fā),溫州微信公眾號(hào),平陽(yáng)做網(wǎng)站,平陽(yáng)網(wǎng)站建設(shè)公司,平陽(yáng)小程序商城制作,昆陽(yáng)萬(wàn)全做網(wǎng)站,鰲江水頭小程序,蕭江騰蛟微信公眾號(hào),山門(mén)順溪南雁海西南麂鳳臥麻步懷溪網(wǎng)絡(luò)網(wǎng)店服務(wù),政采云網(wǎng)店管理服務(wù)】...
2020年第一篇文章,年初忙著復(fù)習(xí)刷題一直沒(méi)空去寫(xiě)東西,書(shū)看的越多感覺(jué)越技不如人,始終徘徊在小菜雞的行列中,最近項(xiàng)目里正好有一個(gè)canvas的業(yè)務(wù),突然又燃起了我一個(gè)UI前端的火種,記下了踩坑和思考。
踩坑問(wèn)題1:為什么在canvas上畫(huà)圖片模糊?在canvas上繪制圖片/文字的時(shí)候,我們?cè)O(shè)定canvas:
375*667的寬高,會(huì)發(fā)現(xiàn)繪制出來(lái)的圖片很模糊,感覺(jué)像是一張分辨率很差的圖片,文字看起來(lái)也會(huì)有疊影。
注意:
物理像素是指手機(jī)屏幕上顯示的最小單元,而設(shè)備獨(dú)立像素(邏輯像素)計(jì)算機(jī)設(shè)備中的一個(gè)點(diǎn),css 中設(shè)置的像素指的就是該像素。
原因:
在前端開(kāi)發(fā)中我們知道一個(gè)屬性叫devicePixelRatio(設(shè)備像素比),該屬性決定了在渲染界面時(shí)會(huì)用幾個(gè)(通常是2個(gè))物理像素來(lái)渲染一個(gè)設(shè)備獨(dú)立像素。
舉個(gè)例,一張100*100像素大小的圖片,在retina屏幕下,會(huì)用2個(gè)像素點(diǎn)去渲染圖片的一個(gè)像素點(diǎn),相當(dāng)于圖片放大了一倍,因此圖片會(huì)變得模糊,這也是1px在retina 屏上變粗的原因。
解決:
將canvas-width和canvas-height都放大2倍,在通過(guò)style將canvas的顯示width,height縮小2 倍.例如:
問(wèn)題2:如何處理px和rpx的轉(zhuǎn)換?rpx是小程序里特有的尺寸單位,可以根據(jù)屏幕的寬度進(jìn)行自適應(yīng),而在iphone6/iphonex上,1rpx等于不同的px。
所以很可能會(huì)導(dǎo)致在不同手機(jī)下,你的canvas展示不一致。
在繪制海報(bào)的之前,我們拿到的設(shè)計(jì)稿一般都是基于iphone6的2倍圖。
而且從上一個(gè)問(wèn)題的解決,我們知道canvas的大小也是2倍的,所以我們可以直接量取2倍圖的設(shè)計(jì)稿直接繪制canvas,而尺寸需要注意一下rpxtoPx./** * * @param {
*}
rpx * @param {
*}
int //是否變成整數(shù) factor => 0.5 //iphone6 pixelRatio => 2 像素比 */ toPx(rpx, int) {
if (int) {
return parseInt(rpx * this.factor * this.pixelRatio) }
return rpx * this.factor * this.pixelRatio }
問(wèn)題3:關(guān)于canvasContext.measureText計(jì)算純數(shù)字的時(shí)候手機(jī)上為0在小程序中提供this.ctx.measureText(text).width去計(jì)算文本的長(zhǎng)度,但是如果你全數(shù)字 的話,你會(huì)發(fā)現(xiàn)該API永遠(yuǎn)都計(jì)算成0.所以,最后采用模擬measureText方法去計(jì)算文本長(zhǎng)度。
measureText(text, fontSize = 10) {
text = String(text) text = text.split('
'
) let width = 0 text.forEach(function(item) {
if (/[a-zA-Z]/.test(item)) {
width += 7 }
else if (/[0-9]/.test(item)) {
width += 5.5 }
else if (/./.test(item)) {
width += 2.7 }
else if (/-/.test(item)) {
width += 3.25 }
else if (/[u4e00-u9fa5]/.test(item)) {
// 中文匹配 width += 10 }
else if (/(|)/.test(item)) {
width += 3.73 }
else if (/s/.test(item)) {
width += 2.5 }
else if (/%/.test(item)) {
width += 8 }
else {
width += 10 }
}
) return width * fontSize / 10 }
問(wèn)題4:如何保證一行字體的居中展示?多行呢?字體的如果過(guò)長(zhǎng),會(huì)超出canvas畫(huà)布,造成繪制難看,這個(gè)時(shí)候我們就應(yīng)該讓超出的部分變成...你可以設(shè)置一個(gè)width并且循環(huán)計(jì)算計(jì)算出文本的寬度,如果超出則利用substring截取后補(bǔ)充...即可。
let fillText='
'
let width = 350 for (let i = 0;
i i++) {
// 將文字轉(zhuǎn)為數(shù)組,一行文字一個(gè)元素 fillText = fillText + text[i] // 判斷截?cái)嗟奈恢? if (this.measureText(fillText, this.toPx(fontSize, true)) >= width) {
if (line === lineNum) {
if (i !== text.length - 1) {
fillText = fillText.substring(0, fillText.length - 1) + '
...'
}
}
if (line textArr.push(fillText) }
fillText = '
'
line++ }
else {
if (line if (i === text.length - 1) {
textArr.push(fillText) }
}
}
}
文字劇中展示計(jì)算公式:
居中在canvas中可以用(canvas的寬度-文字寬度)/2 + x (x為字體的x軸的推移)let w = this.measureText(text, this.toPx(fontSize, true)) this.ctx.fillText(text, this.toPx((this.canvas.width - w) / 2 + x), this.toPx(y + (lineHeight || fontSize) * index))問(wèn)題5:在小程序中如何處理網(wǎng)絡(luò)圖?關(guān)于在小程序里使用網(wǎng)絡(luò)圖片,比如cdn上的圖片,是需要down到微信本地進(jìn)行 LRU 管理,讓后續(xù)繪制同樣圖片時(shí),節(jié)省下載時(shí)間。
所以首先需要你在微信小程序的后臺(tái)配置downloadFile合法域名,其次你可以在canvas繪制之前,最好提前去down圖片,等待圖片下載好了,再開(kāi)始繪制,以避免一些繪制失敗的問(wèn)題。
問(wèn)題6:在 IDE 中可設(shè)置 base64 的圖片數(shù)據(jù)進(jìn)行繪制,但真機(jī)上無(wú)用?先把 base64 轉(zhuǎn)成 Uint8ClampedArray 格式。
然后再通過(guò) wx.canvasPutImageData(OBJECT, this) 繪制到畫(huà)布上,然后把畫(huà)布導(dǎo)出為圖片。
問(wèn)題6:如何畫(huà)一個(gè)圓角圖片?問(wèn)題7:關(guān)于wx.canvasToTempFilePath使用 Canvas 繪圖成功后,直接調(diào)用該方法生成圖片,在IDE上沒(méi)有問(wèn)題,但在真機(jī)上會(huì)出現(xiàn)生成的圖片不完整的情況,可以使用一個(gè)setTimeout來(lái)解決這個(gè)問(wèn)題。
this.ctx.draw(false, () => {
setTimeout(() => {
Taro.canvasToTempFilePath({
canvasId: '
canvasid'
, success: async(res) => {
this.props.onSavePoster(res.tempFilePath)//回調(diào)事件 // 清空畫(huà)布 this.ctx.clearRect(0, 0, canvas_width, canvas_height) }
, fail: (err) => {
console.log(err) }
}
, this.$scope) }
, time) }
)問(wèn)題8:關(guān)于canvasContext.fontfontsize 不能使用小數(shù) 如果設(shè)置 font 中字體大小部分包含小數(shù),則會(huì)導(dǎo)致整個(gè) font 設(shè)置無(wú)效。
問(wèn)題9:安卓下字體渲染錯(cuò)位?這個(gè)問(wèn)題出現(xiàn)在安卓手機(jī)上,ios表現(xiàn)正常。
一開(kāi)始看到這個(gè)問(wèn)題,摸不著頭腦,為什么有的正常居中有的卻往前了很多。
后面發(fā)現(xiàn)是安卓下this.ctx.setTextAlign(textAlign) 默認(rèn)是為center,所以導(dǎo)致了錯(cuò)亂,改成left后就正常了。
問(wèn)題10:繪制一個(gè)折線圖利用canvas繪制一個(gè)簡(jiǎn)單的折線圖,只需要利用lineTo和moveTo倆個(gè)API將點(diǎn)連接即可。
利用createLinearGradient繪制陰影。
思考思考1:用json配置表生成海報(bào)的局限現(xiàn)在的海報(bào)生成只需要按照設(shè)計(jì)稿去量取尺寸就可以,但是量取的過(guò)程還是很繁瑣的,在設(shè)計(jì)稿量不到的地方還需要手動(dòng)微調(diào)一下。
后續(xù)還可以做一個(gè)web端使用拖拽的方式去完成設(shè)計(jì)稿的事情,自動(dòng)生成json應(yīng)用到小程序的海報(bào)上。
思考2:后端生成海報(bào)的局限海報(bào)一開(kāi)始是后端同學(xué)生成的,優(yōu)點(diǎn)是不需要前端繪制時(shí)間,也不需要去踩微信API的坑,接口返回拿到url即可展示,但是在后端生成出來(lái)的效果不佳,畢竟這種工作更加前端一些。
思考3:前端生成海報(bào)的局限前端生成海報(bào)的時(shí)候我發(fā)現(xiàn)耗時(shí)更長(zhǎng),包括圖片的下載本地而且還需要給安卓一個(gè)特意寫(xiě)一個(gè)setTimeout去確保繪制正常。
各種兼容性問(wèn)題、手機(jī)的dpr、安卓和ios等不間斷彩蛋踩到你頭禿~ 哈哈哈哈~彩蛋采用了最新的canvas-2d背景圖確無(wú)法繪制全部?在canvas開(kāi)發(fā)的過(guò)程中,小程序里一直有一束微光提醒我。
我也試了試最新的canvas2d的api,的確同步了web端,寫(xiě)法也更流暢,在開(kāi)發(fā)者工具中看是一切正常,跑在手機(jī)上則,只顯示寬度的一半在各種機(jī)型下測(cè)試也是一樣。
后面改成原始的canvas就又好了。
。
。
具體原因也還沒(méi)有在微信社區(qū)里找到,后續(xù)迭代升級(jí)的時(shí)候再研究阿吧啊吧啊吧。
推薦教程:
《JS教程》以上就是小程序用canvas繪制海報(bào)的做法的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!
微信
分享相關(guān)標(biāo)簽:
微信小程序本文轉(zhuǎn)載于:
掘金社區(qū),如有侵犯,請(qǐng)聯(lián)系[email protected]刪除
上一篇:
小程序內(nèi)容更新提示小紅點(diǎn)如何實(shí)現(xiàn)?
下一篇:
小程序性能優(yōu)化的幾點(diǎn)實(shí)踐技巧相關(guān)文章相關(guān)視頻微信小程序開(kāi)發(fā)BUG經(jīng)驗(yàn)的一些總結(jié)怎么退出微信小程序的登錄?微信小程序能被收藏嗎?Promise實(shí)踐 實(shí)現(xiàn)微信小程序接口封裝小程序用canvas繪制海報(bào)的做法微信小程序開(kāi)發(fā)工具的安裝初識(shí)微信小程序(1)初識(shí)微信小程序(2) [溫州做小程序]
為您推薦
- 百度智能小程序SWAN 視圖基礎(chǔ)數(shù)據(jù)綁定怎么做 2020-08-24
- 百度智能小程序SWAN 視圖是什么? 2020-08-24
- 百度智能小程序啟動(dòng)頁(yè)面的代碼如何設(shè)置 2020-08-24
- 百度智能小程序SWAN 生命周期是什么 2020-08-24
- 百度智能小程序如何配置全局?jǐn)?shù)據(jù) 2020-08-24
- 百度智能小程序?window、tabBar如何優(yōu)化和調(diào)整 2020-08-24
- 百度智能小程序?pages是什么 2020-08-24
- 百度智能小程序配置界面、路徑如何優(yōu)化 2020-08-24