基于canvas 或 svg绘制并生成base64 用于cesium billboard 渲染 替代label
原因
- 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, } })