【小程序】Canvas画布实现左对齐、居中显示效果,动态计算字体宽度 measureText

【小程序】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,注意要传入字符串

你可能感兴趣的:(RN/小程序开发知识总结)