canvas绘制文字段落一

工作中一个场景需要用canvas绘制多段文字,尝试了“\r\n”,结果没用。没法投机取巧了,老实写逻辑吧。更多复杂情况(首行缩进、段间距等等的)等需要时再实现吧。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    canvas {
      border: 1px solid #000;
    }
  </style>
</head>

<body>
  <canvas id="mycanvas" width="240" height="630"></canvas>
  <script>
    let canvas = document.getElementById("mycanvas")
    let ctx = canvas.getContext("2d")
    ctx.font = "20px sans-serif"
    ctx.fillStyle = "#E992B9"
    ctx.textBaseline = "top"
    let rows = 0
    const LINEHEIGHT = 20
    const LINEWIDTH = canvas.width - 40
    let str = "这几天心里颇不宁静。今晚在院子里坐着乘凉,忽然想起日日走过的荷塘,在这满月的光里,总该另有一番样子吧。"
    /**
      @method drawTextParagraph
      @params {string} str 要绘制的字符串
      @params {number} rows 从第多少行开始绘制
      @params {number} lineHeight 每行的行高
      @params {number} lineWidth 每行的宽度
      @params {number} offsetX 行的左侧偏移
      @return {number} 返回该段落渲染了多少行
    */
    const drawTextParagraph = (str, rows = 0, lineHeight, lineWidth, offsetX = 0) => {
      let line= 0
      let delta = 1
      while(ctx.measureText(str).width > lineWidth){
        let lineStr = str.substring(0, delta)
        if(ctx.measureText(lineStr).width <= lineWidth){
          delta ++
          continue
        }
        // 当字符串宽度大于允许行宽且delta大于1时,说明两个或两个以上的字符才会大于允许行宽
        // 这时需要往回退一个字符,如果delta就是1的话,那就不退了
        if(delta > 1){
          delta --
          lineStr = str.substring(0, delta)
        }
        ctx.fillText(lineStr, offsetX, (rows + line) * lineHeight)
        str = str.substring(delta)  // 把渲染过得字符串去掉,保留剩余的字符串
        line ++  // 行数加1
        delta = 1 // 索引重置为1
      }
      // 经过上面的处理,str可能有剩于内容,或者被切成了空字符串。如果有剩余就再绘制一下
      if(str) {
        ctx.fillText(str, offsetX, (rows + line) * lineHeight)
        line ++
      }
      return line
    }
    rows += drawTextParagraph(str, rows, LINEHEIGHT, LINEWIDTH, 20)
    rows += drawTextParagraph(str, rows, LINEHEIGHT, LINEWIDTH, 20)
    rows += drawTextParagraph(str, rows, LINEHEIGHT, LINEWIDTH, 20)
    console.log(rows)
  </script>
</body>

</html>
 
转载请注明出处。
posted @ 2021-04-25 17:07  套路深  阅读(357)  评论(0编辑  收藏  举报