基于canvas 或 svg绘制并生成base64 用于cesium billboard 渲染 替代label

原因

  1. cesium 的label样式不太好修改

canvas 生成

function labelContent(showData) {
    const myConvas = document.createElement("canvas");
    const scale = 1;
    //获取2d的上线文开始设置相关属性
    myConvas.width = 150
    myConvas.height = 65;
    let context = myConvas.getContext('2d')
   roundRect(context, 0, 0, myConvas.width, myConvas.height, 15, "#0081DE")

    //填充文字

    let fontSize = 14 * scale
    context.font = fontSize + "px 'Microsoft Yahei'";
    context.fillStyle = "#ffffff";
    const drawStartX = 15;
    const drawStartY = 19;
    context.fillText(showData.cityName, drawStartX, drawStartY);
    context.fillText(showData.projectNum, drawStartX, drawStartY + 18);
    context.fillText(showData.budget, drawStartX, drawStartY + 35);
    context.imageSmoothingEnabled = true;
    return myConvas.toDataURL('image/png');

  }
 function roundRect(ctx, x, y, width, height, radius, bgColor) {
    // 开始绘制
    ctx.beginPath();
    ctx.moveTo(x + radius, y);

    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);

    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);

    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);

    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.fillStyle = bgColor;

    ctx.closePath();
    ctx.fill();

  }

svg生成

  function labelSvg(showData) {
    const svgStr = `
    <svg width="150" height="65" xmlns="http://www.w3.org/2000/svg">  
      <!-- 创建一个带有圆角的矩形作为背景 -->  
      <rect x="0" y="0" rx="15" ry="15" width="150" height="65" style="fill:#0081DE;stroke:black;stroke-width:0;"/>  
  
      <!-- 在矩形中填充文字 -->  
      <text x="15" y="15" fill="white" font-family="Microsoft Yahei" font-size="15"  text-align="center" alignment-baseline="middle">  
        ${showData.cityName}  
      </text> 
      <text x="15" y="35" fill="white" font-family="Microsoft Yahei" font-size="15"  text-align="center" alignment-baseline="middle">  
        ${showData.projectNum}  
      </text> 
      <text x="15" y="54" fill="white" font-family="Microsoft Yahei" font-size="15"  text-align="center" alignment-baseline="middle">  
        ${showData.budget}  
      </text>  
    </svg>
    `
    return svgToImg(svgStr)
  }
  function svgToImg(svgStr) {
    const blob = new Blob([svgStr], { type: 'image/svg+xml;charset=utf-8' });

    // 创建一个 FileReader 对象来读取 Blob  
    const reader = new FileReader();
    reader.readAsDataURL(blob);
    // 当 FileReader 完成读取时,它会触发 'load' 事件  
    return new Promise((resolve) => {
      reader.onloadend = function () {
        resolve(reader.result)
      };
    })

  }

使用

    const img = await this.labelSvg(data)
    let newEntity = new Cesium.Entity({
      position: Cesium.Cartesian3.fromDegrees(data.x, data.y),
      billboard: {
        image: img,
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(1000000.0, 900000000.0),
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
      }

    })

 

  

posted @ 2024-04-09 13:54  小七要走  阅读(470)  评论(0编辑  收藏  举报