微信小程序中用canvas将文字转成图片,文字自动换行
阅读 (298) 2020-10-30 10:09:30
onReady: function () {
wx.showLoading({
title: '生成图片中...',
})
var that = this
const ctx = wx.createCanvasContext('canvas')
ctx.setFillStyle("#999") // 颜色
ctx.font = 'normal 18px sans-serif' //
const text = "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。\nPHP 是免费的,并且使用非常广泛。同时,对于像微软 ASP 这样的竞争者来说,PHP 无疑是另一种高效率的选项。"
const textX = 0
const textY = 23
const lineHeight = 23
const MAX_WIDTH = 360
var rowLength = this.drawText(ctx, text, textX, textY, lineHeight, MAX_WIDTH)
var canvasHeight = rowLength * lineHeight
this.setData({
canvasWidth: MAX_WIDTH,
canvasHeight: canvasHeight
})
// 这里绘图渲染完后回调中再加上延时,最后再生成图片
ctx.draw(true, function() {
setTimeout(() => {
// 保存文案图片
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: MAX_WIDTH,
height: canvasHeight,
destWidth: MAX_WIDTH * 2,
destHeight: canvasHeight * 2,
canvasId: 'canvas',
success: function (res) {
console.log('res.tempFilePath', res.tempFilePath)
},
fail: function (err) {
Util.toastLongText('生成失败,请稍后重试')
}
})
}, 300)
})
},
/**
* params
* @ctx 画布对象
* @text 需要绘制的文本字符
* @startX 第一行文本的起始X坐标
* @startY 第一行文本的起始Y坐标
* @lineHeight 文本行高
* @MAX_WIDTH 单行文字最大宽度,超过临界值自动换行
* return rowLength 返回绘制文本的行数
**/
drawText: function (ctx, text, startX, startY, lineHeight, MAX_WIDTH) {
let lineArr = text.split("\n") // 拆分出内容本身的行
let rowArr = [] // 用来存储每一行的数据
for (let i = 0; i < lineArr.length; i++) { // 先遍历内容本身的换行
const lineStr = lineArr[i].split('')
var rowStrArr = [] // 每一行的文字数组
for (let j = 0; j < lineStr.length; j++) { // 再遍历每一行文字
const currentStr = lineStr[j]
rowStrArr.push(currentStr)
const rowStr = rowStrArr.join('')
// 判断当前文字宽度是否超出宽度,超出后换一行继续遍历
if (this.measureText(rowStr, 18) > MAX_WIDTH) { // 在微信小程序现在的版本(v2.13.2)中,小程序的canvas还不支持measureText,这个方法重写了一个
rowStrArr.pop() // 删除最后一个
rowArr.push(rowStrArr.join('')) // 完成一行
rowStrArr = [currentStr]
continue
}
// 最后一个字母 直接添加到一行
if (j === lineStr.length - 1) {
rowArr.push(rowStr) // 完成一行
}
}
rowArr.push('')
}
for (let i = 0; i < rowArr.length; i++) {
ctx.fillText(rowArr[i], startX, startY + i * lineHeight)
}
console.log('rowArr', rowArr)
return rowArr.length
},
measureText: function (text, fontSize=10) {
text = String(text);
var text = text.split('');
var 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;
}
更新于:2020-10-30 10:20:20