标记改为整张便签图(黄底黑字合成为一张 Billboard)
This commit is contained in:
+35
-33
@@ -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; // 选中加粗黑圈,不放大
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user