From d4f27f3857a3c056a16f4127ad9744a1a9799d03 Mon Sep 17 00:00:00 2001 From: fukunee Date: Sat, 19 Sep 2026 01:47:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=87=E8=AE=B0=E6=94=B9=E4=B8=BA=E6=95=B4?= =?UTF-8?q?=E5=BC=A0=E4=BE=BF=E7=AD=BE=E5=9B=BE=EF=BC=88=E9=BB=84=E5=BA=95?= =?UTF-8?q?=E9=BB=91=E5=AD=97=E5=90=88=E6=88=90=E4=B8=BA=E4=B8=80=E5=BC=A0?= =?UTF-8?q?=20Billboard=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scene/CesiumGlobe.js | 68 +++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/scene/CesiumGlobe.js b/src/scene/CesiumGlobe.js index b7bad7b..4460874 100644 --- a/src/scene/CesiumGlobe.js +++ b/src/scene/CesiumGlobe.js @@ -36,19 +36,26 @@ function sphericalAreaKm2(polys) { return area * R * R; } -// 生成圆角黑色背景 canvas(尺寸按文字实际测量宽度) -function makeRoundedBg(text, fontSize) { - const padX = 12, padY = 7, radius = 10; +// 生成便签 canvas:黄色圆角底 + 黑色加粗文字(整张图,背景与文字完美对齐) +function makeStickyNote(text, fontSize) { + const padX = 14, padY = 8, radius = 8, S = 2; // S: 2x 超采样,文字更清晰 + const font = `bold ${fontSize}px "Noto Serif SC", "Songti SC", "STSong", "SimSun", Georgia, serif`; const m = document.createElement('canvas'); const mctx = m.getContext('2d'); - mctx.font = `bold ${fontSize}px "Noto Serif SC", "Songti SC", "STSong", "SimSun", Georgia, serif`; + mctx.font = font; const textW = mctx.measureText(text).width; const w = Math.max(1, Math.ceil(textW + padX * 2)); const h = Math.ceil(fontSize + padY * 2); const c = document.createElement('canvas'); - c.width = w; - c.height = h; + c.width = w * S; + c.height = h * S; const ctx = c.getContext('2d'); + ctx.scale(S, S); + + // 黄色圆角底 + 阴影 + ctx.shadowColor = 'rgba(0, 0, 0, 0.20)'; + ctx.shadowBlur = 5; + ctx.shadowOffsetY = 2; ctx.beginPath(); ctx.moveTo(radius, 0); ctx.arcTo(w, 0, w, h, radius); @@ -56,12 +63,20 @@ function makeRoundedBg(text, fontSize) { ctx.arcTo(0, h, 0, 0, radius); ctx.arcTo(0, 0, w, 0, radius); ctx.closePath(); - ctx.shadowColor = 'rgba(0, 0, 0, 0.18)'; - ctx.shadowBlur = 4; - ctx.shadowOffsetY = 1; ctx.fillStyle = '#FFF9A6'; ctx.fill(); - return { canvas: c, textW }; + + // 黑色加粗文字(无阴影) + ctx.shadowColor = 'transparent'; + ctx.shadowBlur = 0; + ctx.shadowOffsetY = 0; + ctx.fillStyle = '#14100d'; + ctx.font = font; + ctx.textBaseline = 'middle'; + ctx.textAlign = 'center'; + ctx.fillText(text, w / 2, h / 2 + 1); + + return { canvas: c, scale: 1 / S }; } export class CesiumGlobe { @@ -172,7 +187,6 @@ export class CesiumGlobe { _buildMarkers() { const viewer = this.viewer; const gold = Cesium.Color.fromCssColorString('#e0c46a'); - const ivory = Cesium.Color.fromCssColorString('#e8d9b4'); const ink = Cesium.Color.fromCssColorString('#14100d'); ENTRIES.forEach((entry, i) => { @@ -187,39 +201,27 @@ export class CesiumGlobe { disableDepthTestDistance: Number.POSITIVE_INFINITY, distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1e7), }, - label: { - text: entry.name, - font: 'bold 19px "Noto Serif SC", "Songti SC", "STSong", "SimSun", Georgia, serif', - fillColor: ink, - style: Cesium.LabelStyle.FILL, - horizontalOrigin: Cesium.HorizontalOrigin.LEFT, - verticalOrigin: Cesium.VerticalOrigin.CENTER, - pixelOffset: new Cesium.Cartesian2(10, 0), - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - disableDepthTestDistance: Number.POSITIVE_INFINITY, - distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1e7), - show: true, - }, }); entity.entryIndex = i; - // 选中时显示的圆角黑色背景 - const bg = makeRoundedBg(entry.name, 19); - const bgEntity = viewer.entities.add({ + // 便签:黄底黑字(整张图,贴到圆点右侧) + const note = makeStickyNote(entry.name, 19); + const noteEntity = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(entry.lng, entry.lat), billboard: { - image: bg.canvas, - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + image: note.canvas, + scale: note.scale, + horizontalOrigin: Cesium.HorizontalOrigin.LEFT, verticalOrigin: Cesium.VerticalOrigin.CENTER, - pixelOffset: new Cesium.Cartesian2(10 + bg.textW / 2, 0), + pixelOffset: new Cesium.Cartesian2(12, 0), heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, disableDepthTestDistance: Number.POSITIVE_INFINITY, - show: true, + distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1e7), }, }); - this.markers.push({ entity, bg: bgEntity, index: i }); + this.markers.push({ entity, index: i }); }); } @@ -381,7 +383,7 @@ export class CesiumGlobe { setSelected(index) { this.selected = index; if (!this.viewer) return; - this.markers.forEach(({ entity, bg, index: i }) => { + this.markers.forEach(({ entity, index: i }) => { const on = i === index; entity.point.outlineWidth = on ? 3 : 1; // 选中加粗黑圈,不放大 });