Cesium Canvas 文字点教程
Canvas 文字点 ·Canvas Text Billboards· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么用Canvas 2D动态生成文字纹理devicePixelRatio × dpr高清屏清晰文字纹理作为Billboard.image批量贴到城市坐标效果说明加载 city.json每个城市名渲染成彩色 canvas再以 billboard 形式钉在对应经纬度。核心概念createCanvasText 工厂function createCanvasText(params) {const { dpr, fontSize, maxWidth } { dpr: 1, maxWidth: 100, fontSize: 20, ...params }; const ratio window.devicePixelRatio * dpr; canvas.width maxWidth * ratio; canvas.height fontSize * ratio; ctx.scale(ratio, ratio); // 返回 (opts) canvas.toDataURL() 或 canvas 本身 }每次调用updateCanvasText({ text: key, color })重绘并返回 image 源。为何不用 Label| Label | Canvas Billboard | |-------|------------------| | 字体样式有限 | 任意 CSS 字体、描边、背景 | | 每 Entity 开销 | Collection 合批 | | 适合少量 | 适合上百城市名 |实现步骤fetch city.json →{ 城市名: [lon, lat] }createCanvasText({ dpr: 1.4 })得 update 函数BillboardCollection循环 addimage: updateCanvasText({ text, color })flyTo中国上空总览代码要点import * as Cesium from cesiumconst box document.getElementById(box)const viewer new Cesium.Viewer(box, {animation: false,//是否创建动画小器件左下角仪表baseLayerPicker: false,//是否显示图层选择器右上角图层选择按钮baseLayer: Cesium.ImageryLayer.fromProviderAsync(Cesium.ArcGisMapServerImageryProvider.fromUrl(https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer)),fullscreenButton: false,//是否显示全屏按钮右下角全屏选择按钮timeline: false,//是否显示时间轴infoBox: false,//是否显示信息框})viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(116.46, 39.92, 8000000) }) // 设置相机位置const citys await fetch(https://z2586300277.github.io/three-editor/dist/files/other/city.json).then(res res.json()) // 获取城市数据const updateCanvasText createCanvasText({ dpr: 1.4 }) // 创建canvasconst billboards new Cesium.BillboardCollection() // 创建合集viewer.scene.primitives.add(billboards) // 添加图层const getColor () # Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, 0) // 随机颜色for (const key in citys) {const [longitude, latitude] citys[key]billboards.add({position: Cesium.Cartesian3.fromDegrees(longitude, latitude),image: updateCanvasText({ text: key, color: getColor() }),scale: 0.5 }) }// 创建canvas文字方法 function createCanvasText(params) {const defaultParams { dpr: 1, maxWidth: 100, fontSize: 20, color: white, fontFamily: serif, align: center, border: false, ...params } // 默认参数const { dpr, border, maxWidth, fontSize, align } defaultParamsconst devicePixelRatio window.devicePixelRatio * dpr// 准备 cnvas const canvas document.createElement(canvas)canvas.width maxWidth * devicePixelRatiocanvas.height fontSize * devicePixelRatio// 获取 2d 上下文 const ctx canvas.getContext(2d)ctx.imageSmoothingQuality highctx.scale(devicePixelRatio, devicePixelRatio)// 创建边框 function createBorder() {ctx.strokeStyle #fff// 创建宽度为10px的边框 ctx.lineWidth 1 * devicePixelRatio;ctx.strokeRect(ctx.lineWidth / 2,ctx.lineWidth / 2,canvas.width / devicePixelRatio - ctx.lineWidth,canvas.height / devicePixelRatio - ctx.lineWidth)}// 创建文字 const createText ({ text, color, fontSize, fontFamily }) {// 参数设定 ctx.fillStyle color || defaultParams.colorctx.font fontSize || defaultParams.fontSize px fontFamily || defaultParams.fontFamily// 文本长度计算 let textMaxNum 0let totalWidth 0for (let i 0; i text.length; i) {const metrics ctx.measureText(text[i])totalWidth metrics.width;if (totalWidth maxWidth) breaktextMaxNum}text text.slice(0, textMaxNum)// 文字 绘制 const metrics ctx.measureText(text) // 文本尺寸const actualHeight metrics.actualBoundingBoxAscent metrics.actualBoundingBoxDescent // 实际文字高度const textFillHeight (canvas.height / devicePixelRatio - actualHeight) / 2 metrics.actualBoundingBoxAscentlet textLeftOffset 0if (align center) textLeftOffset (canvas.width / devicePixelRatio - metrics.width) / 2ctx.fillText(text, textLeftOffset, textFillHeight, canvas.width / devicePixelRatio)}return (parameters) {ctx.clearRect(0, 0, canvas.width, canvas.height) // 清空 canvas 文字if (border) createBorder() // 创建边框createText(parameters) // 创建文字return canvas.toDataURL()}}完整源码GitHub小结本文提供Canvas 文字点完整 Cesium.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Cesium.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库