canvas文字超出自动换行,并计算canvas高度(使用measureText)

 

超出自动换行:

function drawWrappedText(ctx, text, x, y, maxWidth, lineHeight) {
      let words = text.split(' ');
      let line = '';
      for (let i = 0; i < words.length; i++) {
        let testLine = line + words[i] + ' ';
        let metrics = ctx.measureText(testLine);
        let testWidth = metrics.width;
        if (testWidth > maxWidth && i > 0) {
          ctx.fillText(line, x, y);
          line = words[i] + ' ';
          y += lineHeight;
        } else {
          line = testLine;
        }
      }
      ctx.fillText(line, x, y);
    }

计算换行后的高度:

function calculateTextHeight(ctx, text, maxWidth, lineHeight) {
      let words = text.split(' ');
      let line = '';
      let lineCount = 1;

      for (let i = 0; i < words.length; i++) {
        let testLine = line + words[i] + ' ';
        let metrics = ctx.measureText(testLine);
        let testWidth = metrics.width;
        if (testWidth > maxWidth && i > 0) {
          line = words[i] + ' ';
          lineCount++;
        } else {
          line = testLine;
        }
      }
      return lineCount * lineHeight;
    }

完整样例:

 const drawMap = (
    sprite,
    material,
    name,
    imageUrl,
    width = 1430,
    height = 586) => {
    //绘制canvas
    let canvas = document.createElement('canvas');
    let c = canvas.getContext('2d');
    let nameHeight = height
    canvas.width = width;//默认宽度maxWith
    canvas.height = height;//默认高度
    // 矩形区域填充背景
    c.beginPath();
    let bg = new Image();
    bg.src = bottomBack;
    bg.onload = function () {
      c.font = '140px PingFangSC-Regular';
      const lineHeight = 150;
      //计算换行后的高度
      nameHeight = calculateTextHeight(c, name, canvas.width - 210, lineHeight);
      const lastHeight = Math.max(height, 130 + nameHeight + 300)
      canvas.width = width;
      canvas.height = lastHeight;
        
      //渲染背景图大小(获取高度后渲染)
      c.drawImage(bg, 0, 0, 1430, lastHeight);

      c.beginPath();
      c.textAlign = 'start'
      c.textBaseline = 'top';
      c.fillStyle = '#ffffff';
      c.font = '140px PingFangSC-Regular';
      //渲染自动换行的文本
      drawWrappedText(c, name, 210, 130, canvas.width - 210, lineHeight);
      // c.fillText(name, 210, 130);
      //渲染正常文本
      c.beginPath();
      c.font = '120px PingFangSC-Regular';
      c.textAlign = 'start'
      c.textBaseline = 'top';
      c.fillStyle = '#FA883A';
      c.fillText(`数据中心`, 210, 130 + nameHeight + 50);
        
      material.map = new THREE.CanvasTexture(canvas, { pixelRatio: 10 })
      material.needsUpdate = true
      material.opacity = 1;
      sprite.scale.set(143, lastHeight / 10 || 58.6, 1);

    };
 }

 

posted @   SimoonJia  阅读(140)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示