最近接手開發(fā)了一個小程序項目,里面有一個分享封面圖功能,做的過程中遇到了一些問題,特此記錄
因為目前在小程序中是沒有截屏功能的,如果我們需要生成一張完整的封面圖做分享,前端最方便的方案大概就是使用canvas了,利用canvas的圖片導(dǎo)出功能,可以很方便的生成一張完整的圖出來,下面就記錄一下過程中遇到的問題

主界面

生成的圖
rpx轉(zhuǎn)px
因為canvas中是沒有rpx這個單位的,所以當(dāng)我們在繪制的過程中,先要把rpx轉(zhuǎn)為px
rpxToPx(rpx) {
let px = Math.ceil(rpx / 750 * windowWidth) // windowWidth可以在全局變量中先存儲
return px
}
繪制單行文字
這里一共用到了小程序里面的兩個api,和一個屬性
ctx.setFillStyle: 設(shè)置字體顏色 ctx.setFillStyle(color)
ctx.font: 設(shè)置字體屬性 normal weight 16px sans-serif
ctx.fillText繪制字體 這個api需要注意的是,x和y的坐標(biāo)是定在文字的左下角的,我們一般畫圖的x和y都是左上角。當(dāng)我們畫文字時,y的坐標(biāo)就需要加上文字的行高 ctx.fillText(text, x, y + text.lineHeight)
繪制多行文字
當(dāng)我們?nèi)绻枰L制的文字過長,但是canvas里面又沒有自動換行的功能,這時就需要我們手動計算每行文字的顯示長度,然后進行截取,這里用到了一個api
measureText: 它可以測量文本尺寸信息,返回當(dāng)前文字的寬度
width = ctx.measureText(str).width
然后我們進行累加,當(dāng)中寬度超出最大寬度的時候,就進行截取,然后重新計算寬度,示例代碼
let lastSubStrIndex = 0
let lineHeight = item.lineHeight
let initHeight = item.y
for(let i = 0; i < str.length; i++){
lineWidth += ctx.measureText(str[i]).width
if(lineWidth > maxWidth){
ctx.fillText(str.substring(lastSubStrIndex, i), item.x, initHeight)
initHeight += lineHeight
lastSubStrIndex = i
lineWidth = 0
}
if (i == str.length - 1) {//繪制剩余部分
ctx.fillText(str.substring(lastSubStrIndex, i + 1), item.x, initHeight)
}
}
圓角矩形
drawRect(ctx,obj){
let x = obj.x // x坐標(biāo)
let y = obj.y // y坐標(biāo)
let w = obj.w // 寬度
let h = obj.h // 高度
let r = obj.r // 半徑
ctx.beginPath();
ctx.setFillStyle('#fff');
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.lineTo(x + w, y + r);
ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
ctx.lineTo(x + w, y + h - r);
ctx.lineTo(x + w - r, y + h);
ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
ctx.lineTo(x + r, y + h);
ctx.lineTo(x, y + h - r);
繪圖
在小程序中,我們?nèi)绻氚丫W(wǎng)絡(luò)圖片繪制到canvas中,事先需要先把圖片緩存下來,可以使用getImageInfo先把圖片緩存下來
wx.getImageInfo({
src: imgUrl,
success: (res) => {
imgUrl = res.path
}
})
保存圖片
function savePicToAlbum(tempFilePath,callback) {
let that = this;
wx.getSetting({
success(res) {
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
wx.saveImageToPhotosAlbum({
filePath: tempFilePath,
success(res) {
wx.showToast({
title: '保存成功'
});
callback && callback()
}
})
},
fail() {
// 用戶拒絕授權(quán),打開設(shè)置頁面
wx.openSetting({
success: function (data) {
console.log("openSetting: success");
},
fail: function (data) {
console.log("openSetting: fail");
}
});
}
})
} else {
wx.saveImageToPhotosAlbum({
filePath: tempFilePath,
success(res) {
wx.showToast({
title: '保存成功',
});
},
fail(res) {
console.log(res);
}
})
}
},
fail(res) {
console.log(res);
}
})
}
最后推薦一個小程序里面的圖片裁剪組件we-cropper