【小程序】Canvas画布实现左对齐、居中显示效果,动态计算字体宽度 measureText
Canvas 画布提供的API,需要提供x,y坐标来绘制text或者,view。
要实现 左对齐、居中显示的效果,可以利用Canvas提供的measureText来量取text的宽度,动态进行布局。参考代码如下:
//绘制价格信息,支持相对布局方式
function drawPrice(ctx, priceInfo, posterContent, posterWidth) {
if (!priceInfo || !priceInfo.content) {
return
}
let originX = priceInfo.content.x
let originY = priceInfo.content.y
let maxWidth = priceInfo.content.width
//左对齐方式
if (priceInfo.content.align == 'left') {
let startX = originX
//绘制货币符号
if (posterContent.priceUnitSymbol && priceInfo.prefix) {
startX += priceInfo.prefix.x
let startY = originY + priceInfo.prefix.y
ctx.setTextAlign(priceInfo.prefix.align)
ctx.setFontSize(priceInfo.prefix.font)
ctx.setFillStyle(priceInfo.prefix.color)
ctx.fillText(posterContent.priceUnitSymbol, startX, startY)
startX += ctx.measureText(posterContent.priceUnitSymbol).width
}
//绘制价格
if (posterContent.price && priceInfo.price) {
startX += priceInfo.price.x
let startY = originY + priceInfo.price.y
ctx.setTextAlign(priceInfo.price.align)
ctx.setFontSize(priceInfo.price.font)
ctx.setFillStyle(priceInfo.price.color)
ctx.fillText(posterContent.price, startX, startY,maxWidth)
if (priceInfo.price.bold) {
ctx.fillText(posterContent.price, startX + 0.5, startY)
ctx.fillText(posterContent.price, startX - 0.5, startY)
ctx.fillText(posterContent.price, startX, startY + 0.5)
ctx.fillText(posterContent.price, startX, startY - 0.5)
}
let priceWidth = ctx.measureText(posterContent.price + '').width //适配8P
startX += priceWidth
}
//绘制价格单位如"元/起"
if (posterContent.priceUnit && priceInfo.end) {
startX += priceInfo.end.x
let startY = originY + priceInfo.end.y
ctx.setTextAlign(priceInfo.end.align)
ctx.setFontSize(priceInfo.end.font)
ctx.setFillStyle(priceInfo.end.color)
ctx.fillText(posterContent.priceUnit, startX, startY)
}
}
// 居中对齐
else if (priceInfo.content.align == 'center') {
//计算总字符的宽度
let totalFontWidth = 0
let prefixWidth = 0
let priceWidth = 0
let endWidth = 0
if (posterContent.priceUnitSymbol && priceInfo.prefix) {
ctx.setFontSize(priceInfo.prefix.font)
prefixWidth = ctx.measureText(posterContent.priceUnitSymbol).width
totalFontWidth += prefixWidth
}
if (posterContent.price && priceInfo.price) {
ctx.setFontSize(priceInfo.price.font)
priceWidth = ctx.measureText(posterContent.price + '').width
totalFontWidth += priceWidth
}
if (posterContent.priceUnit && priceInfo.end) {
ctx.setFontSize(priceInfo.end.font)
endWidth = ctx.measureText(posterContent.priceUnit).width
totalFontWidth += endWidth
}
totalFontWidth = totalFontWidth + priceInfo.price.x + priceInfo.end.x
let startX = (posterWidth - totalFontWidth) / 2
// 非居屏幕中间对齐
if (priceInfo.content.width != -1) {
startX = priceInfo.content.x + (priceInfo.content.width - totalFontWidth) / 2
}
//绘制货币符号
if (posterContent.priceUnitSymbol && priceInfo.prefix) {
let startY = originY + priceInfo.prefix.y
ctx.setTextAlign(priceInfo.prefix.align)
ctx.setFontSize(priceInfo.prefix.font)
ctx.setFillStyle(priceInfo.prefix.color)
ctx.fillText(posterContent.priceUnitSymbol, startX, startY)
startX += prefixWidth
}
//绘制价格
if (posterContent.price && priceInfo.price) {
startX += priceInfo.price.x
let startY = originY + priceInfo.price.y
ctx.setTextAlign(priceInfo.price.align)
ctx.setFontSize(priceInfo.price.font)
ctx.setFillStyle(priceInfo.price.color)
ctx.fillText(posterContent.price, startX, startY,maxWidth)
if (priceInfo.price.bold) {
ctx.fillText(posterContent.price, startX + 0.5, startY)
ctx.fillText(posterContent.price, startX - 0.5, startY)
ctx.fillText(posterContent.price, startX, startY + 0.5)
ctx.fillText(posterContent.price, startX, startY - 0.5)
}
startX += priceWidth
}
//绘制价格单位如"元/起"
if (posterContent.priceUnit && priceInfo.end) {
startX += priceInfo.end.x
let startY = originY + priceInfo.end.y
ctx.setTextAlign(priceInfo.end.align)
ctx.setFontSize(priceInfo.end.font)
ctx.setFillStyle(priceInfo.end.color)
ctx.fillText(posterContent.priceUnit, startX, startY)
}
}
}
注意:
let priceWidth = ctx.measureText(posterContent.price + ‘’).width //适配8P
在iPhone上,如果量取的内容为数字,则会返回width 为0,注意要传入字符串