From 7224851bf14cab706d36f695331488941ed4aba6 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Fri, 31 Jul 2026 18:01:05 +0800
Subject: [PATCH] feat:去除dialog滚动条
---
applications/drone-command/src/components/map-container/device-map-container.vue | 539 ++++++++++++++++++++++++++++++++++-------------------------
1 files changed, 308 insertions(+), 231 deletions(-)
diff --git a/applications/drone-command/src/components/map-container/device-map-container.vue b/applications/drone-command/src/components/map-container/device-map-container.vue
index 7d6383c..a84f2e0 100644
--- a/applications/drone-command/src/components/map-container/device-map-container.vue
+++ b/applications/drone-command/src/components/map-container/device-map-container.vue
@@ -5,33 +5,47 @@
:show-admin-boundary="true" :zoom-to-boundary="true" :enable-stage-emit="true"
:cluster-height="CLUSTER_HEIGHT" :detail-height="DETAIL_HEIGHT" @ready="handleMapReady"
@stage-change="handleStageChange" />
- <div v-if="props.showLayerControl" class="layer-control-root" :class="{ collapsed: props.leftCollapsed }">
+ <div v-if="props.showLayerControl" class="layer-control-root" :class="{ collapsed: props.rightCollapsed }">
<div class="layer-control-wrap" ref="layerWrapRef">
- <div class="layer-control" @click="toggleLayerPanel">
+ <div class="layer-control" @click.stop="toggleLayerPanel">
<img :src="layerControlIcon" alt="图层控制" />
</div>
- <div v-if="showLayerPanel" class="layer-panel">
- <div class="panel-title">底图切换</div>
- <div class="base-map-options">
- <div class="base-map-card" :class="{ active: baseLayerKey === 'base-standard' }"
- @click="handleBaseLayerSelect('base-standard')">
- <img class="base-map-thumb standard" :src="dzIcon" alt="">
- <div class="base-map-label">标准地图</div>
- </div>
- <div class="base-map-card" :class="{ active: baseLayerKey === 'base-satellite' }"
- @click="handleBaseLayerSelect('base-satellite')">
- <img class="base-map-thumb satellite" :src="yxIcon" alt="">
- <div class="base-map-label">卫星地图</div>
+ <transition name="layer-panel-slide">
+ <div v-if="showLayerPanel" class="layer-panel">
+ <div class="panel-title">图层管理</div>
+ <div class="panel-content">
+ <el-tree ref="layerTreeRef" class="command-tree map-layer-tree" :data="layerTree"
+ icon="el-icon-arrow-down-bold"
+ show-checkbox default-expand-all node-key="key" :props="layerTreeProps"
+ :default-checked-keys="treeCheckedKeys" @check="handleLayerCheck" />
</div>
</div>
-
- <div class="panel-title">图层管理</div>
- <div class="panel-content">
- <el-tree ref="layerTreeRef" class="command-tree map-layer-tree" :data="layerTree" show-checkbox
- default-expand-all node-key="key" :props="layerTreeProps"
- :default-checked-keys="treeCheckedKeys" @check="handleLayerCheck" />
- </div>
+ </transition>
+ </div>
+ </div>
+ <div v-if="props.showLayerControl" class="base-layer-switch-root" :class="{ collapsed: props.rightCollapsed }">
+ <div class="base-layer-switch-wrap" @mouseenter="showBaseLayerPanel = true"
+ @mouseleave="showBaseLayerPanel = false">
+ <div class="base-layer-trigger">
+ <img class="base-layer-trigger-thumb" :src="currentBaseLayer.icon" :alt="currentBaseLayer.label">
+ <div class="base-layer-trigger-label">{{ currentBaseLayer.shortLabel }}</div>
</div>
+ <transition name="layer-panel-slide">
+ <div v-if="showBaseLayerPanel" class="base-layer-panel">
+ <div class="base-map-options">
+ <div class="base-map-card" :class="{ active: baseLayerKey === 'base-satellite' }"
+ @click="handleBaseLayerSelect('base-satellite')">
+ <img class="base-map-thumb" :src="yxIcon" alt="">
+ <div class="base-map-label">卫星地图</div>
+ </div>
+ <div class="base-map-card" :class="{ active: baseLayerKey === 'base-standard' }"
+ @click="handleBaseLayerSelect('base-standard')">
+ <img class="base-map-thumb" :src="dzIcon" alt="">
+ <div class="base-map-label">标准地图</div>
+ </div>
+ </div>
+ </div>
+ </transition>
</div>
</div>
@@ -45,6 +59,7 @@
</template>
<script setup>
+
import * as Cesium from 'cesium'
import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
import { buildEllipsePositions } from '@/utils/cesium/shapeTools'
@@ -77,6 +92,7 @@
const DETAIL_HEIGHT = 10000
const POLYGON_HEIGHT_M = 0.2
const DRONE_TRACK_DURATION_S = 30 * 60
+const FIXED_DRONE_TRACK_IDS = ['6000000000609', '6000000000608']
const props = defineProps({
allDevices: {
@@ -87,7 +103,7 @@
type: Array,
default: () => [],
},
- leftCollapsed: {
+ rightCollapsed: {
type: Boolean,
default: false,
},
@@ -131,13 +147,14 @@
let favoritePulseElapsed = 0
const favoritePulseEntities = []
const pulseBaseColor = Cesium.Color.fromCssColorString('#FF3B30')
-const PULSE_MIN_RADIUS_M = 2
-const PULSE_MAX_RADIUS_M = 30
+const PULSE_MIN_RADIUS_M = 20
+const PULSE_MAX_RADIUS_M = 80
const PULSE_DURATION_S = 1.4
const detailVisible = ref(true)
const clusterVisible = ref(false)
const countyCenterMap = new Map()
const showLayerPanel = ref(false)
+const showBaseLayerPanel = ref(false)
const layerWrapRef = ref(null)
const layerTreeRef = ref(null)
const selectedDevice = ref(null)
@@ -152,6 +169,11 @@
const baseLayerKeys = ['base-standard', 'base-satellite']
const defaultCheckedKeys = ['ja-terrain', 'admin', 'city-base']
const baseLayerKey = ref('base-satellite')
+const baseLayerMeta = {
+ 'base-standard': { icon: dzIcon, label: '标准地图', shortLabel: '标准' },
+ 'base-satellite': { icon: yxIcon, label: '卫星地图', shortLabel: '影像' },
+}
+const currentBaseLayer = computed(() => baseLayerMeta[baseLayerKey.value] || baseLayerMeta['base-satellite'])
const treeCheckedKeys = ref([...defaultCheckedKeys])
const layerTree = ref([
{
@@ -216,93 +238,17 @@
return canvas
}
-class PulseSphereMaterialProperty {
- constructor(color, speed = 1.2, bands = 3.0, softness = 0.18) {
- this._definitionChanged = new Cesium.Event()
- this.color = color
- this.speed = speed
- this.bands = bands
- this.softness = softness
- }
- get isConstant() {
- return true
- }
- get definitionChanged() {
- return this._definitionChanged
- }
- getType() {
- return 'PulseSphereMaterial'
- }
- getValue(_time, result = {}) {
- result.color = this.color
- result.time = (performance.now() / 1000) * this.speed
- result.bands = this.bands
- result.softness = this.softness
- return result
- }
- equals(other) {
- return (
- other instanceof PulseSphereMaterialProperty &&
- Cesium.Color.equals(this.color, other.color) &&
- this.speed === other.speed &&
- this.bands === other.bands &&
- this.softness === other.softness
- )
- }
-}
-
-let pulseSphereMaterial = null
-const getPulseSphereMaterial = () => {
- if (pulseSphereMaterial) return pulseSphereMaterial
- Cesium.Material._materialCache.addMaterial('PulseSphereMaterial', {
- fabric: {
- type: 'PulseSphereMaterial',
- uniforms: {
- color: pulseBaseColor.withAlpha(0.45),
- time: 0,
- bands: 3.0,
- softness: 0.18,
- },
- source: `
- czm_material czm_getMaterial(czm_materialInput materialInput)
- {
- czm_material material = czm_getDefaultMaterial(materialInput);
- vec3 normalEC = normalize(materialInput.normalEC);
- vec3 viewEC = normalize(-materialInput.positionToEyeEC);
- float ndv = max(dot(normalEC, viewEC), 0.0);
- float fresnel = pow(1.0 - ndv, 1.6);
- float wave = sin((ndv * bands + time) * 6.2831853);
- float ring = smoothstep(-softness, softness, wave);
- float alpha = (ring * 0.6 + fresnel * 0.4) * color.a;
- material.diffuse = color.rgb;
- material.alpha = alpha;
- return material;
- }
- `,
- },
- translucent: () => true,
- })
- pulseSphereMaterial = new PulseSphereMaterialProperty(pulseBaseColor.withAlpha(0.45), 1.1, 3.2, 0.22)
- return pulseSphereMaterial
-}
-
const createFavoritePulseEntity = (billboard) => {
if (!viewer || !billboard) return
- const material = getPulseSphereMaterial()
const pulse = {
- material,
offset: Math.random() * PULSE_DURATION_S,
entity: null,
}
- const getPulseRadius3D = () => {
- const radius = getPulseRadius(pulse)
- return new Cesium.Cartesian3(radius, radius, radius)
- }
pulse.entity = viewer.entities.add({
position: new Cesium.CallbackProperty(() => getBillboardPosition(billboard), false),
- ellipsoid: {
- radii: new Cesium.CallbackProperty(() => getPulseRadius3D(), false),
- material,
+ point: {
+ pixelSize: new Cesium.CallbackProperty(() => getPulseRadius(pulse), false),
+ color: pulseBaseColor.withAlpha(0.4),
},
})
favoritePulseEntities.push(pulse)
@@ -378,10 +324,10 @@
if (deviceRingOutlinePrimitives.length) {
deviceRingOutlinePrimitives.forEach(primitive => cockpitPrimitiveLayer.add(primitive))
}
+ if (commandPostBillboardCollection) cockpitPrimitiveLayer.add(commandPostBillboardCollection)
+ if (deviceBillboardCollection) cockpitPrimitiveLayer.add(deviceBillboardCollection)
if (droneTrackPolylineCollection) cockpitPrimitiveLayer.add(droneTrackPolylineCollection)
if (droneTrackBillboardCollection) cockpitPrimitiveLayer.add(droneTrackBillboardCollection)
- if (deviceBillboardCollection) cockpitPrimitiveLayer.add(deviceBillboardCollection)
- if (commandPostBillboardCollection) cockpitPrimitiveLayer.add(commandPostBillboardCollection)
}
const clearDeviceEntities = () => {
@@ -525,82 +471,92 @@
const basePoints = [
[
{
- longitude: 114.963191,
- latitude: 27.136716,
- height: 120
+ longitude: 114.929475,
+ latitude: 27.136575,
+ height: 200
},
{
- longitude: 114.957308,
- latitude: 27.138452,
- height: 120
+ longitude: 114.928466,
+ latitude: 27.134556,
+ height: 200
},
{
- longitude: 114.952,
- latitude: 27.136317,
- height: 120
+ longitude: 114.928466,
+ latitude: 27.134556,
+ height: 320
},
{
- longitude: 114.949293,
- latitude: 27.133864,
- height: 120
+ longitude: 114.928474,
+ latitude: 27.134397,
+ height: 320
},
{
- longitude: 114.944666,
- latitude: 27.130526,
- height: 120
+ longitude: 114.927932,
+ latitude: 27.133385,
+ height: 320
},
{
- longitude: 114.945909,
- latitude: 27.127845,
- height: 120
+ longitude: 114.927365,
+ latitude: 27.132097,
+ height: 320
},
{
- longitude: 114.962974,
- latitude: 27.136242,
+ longitude: 114.929818,
+ latitude: 27.131645,
+ height: 320
+ },
+ {
+ longitude: 114.924644,
+ latitude: 27.136622,
height: 120
},
],
[
{
- longitude: 114.931063,
- latitude: 27.095052,
+ longitude: 114.936386,
+ latitude: 26.825890,
height: 120
},
{
- longitude: 114.928653,
- latitude: 27.096307,
+ longitude: 114.933976,
+ latitude: 26.827145,
height: 120
},
{
- longitude: 114.925958,
- latitude: 27.096963,
+ longitude: 114.931281,
+ latitude: 26.827801,
height: 120
},
{
- longitude: 114.925836,
- latitude: 27.096102,
- height: 120
+ longitude: 114.931281,
+ latitude: 26.827801,
+ height: 400
},
{
- longitude: 114.928384,
- latitude: 27.095866,
- height: 120
+ longitude: 114.931159,
+ latitude: 26.826940,
+ height: 400
},
{
- longitude: 114.929874,
- latitude: 27.096095,
- height: 120
+ longitude: 114.933707,
+ latitude: 26.826704,
+ height: 400
},
{
- longitude: 114.931048,
- latitude: 27.097666,
- height: 120
+ longitude: 114.935197,
+ latitude: 26.826933,
+ height: 400
},
- ]
+ {
+ longitude: 114.936371,
+ latitude: 26.828504,
+ height: 400
+ },
+ ],
]
- return basePoints[center.trackIndex]
+ return basePoints[center.trackIndex] || basePoints[1]
}
@@ -667,7 +623,9 @@
const setupDroneTrackClock = () => {
if (!viewer) return
- const startTime = Cesium.JulianDate.now()
+ const now = new Date()
+ const noon = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 12, 0, 0, 0)
+ const startTime = Cesium.JulianDate.fromDate(noon)
const stopTime = Cesium.JulianDate.addSeconds(startTime, DRONE_TRACK_DURATION_S, new Cesium.JulianDate())
viewer.clock.startTime = startTime
viewer.clock.stopTime = stopTime
@@ -692,11 +650,11 @@
const pos = isEntityPosition
? getBillboardPosition(track.billboard)
: Cesium.Cartesian3.lerp(
- track.positions[seg],
- track.positions[seg + 1],
- ratio,
- new Cesium.Cartesian3()
- )
+ track.positions[seg],
+ track.positions[seg + 1],
+ ratio,
+ new Cesium.Cartesian3()
+ )
if (!pos) return
if (!isEntityPosition) {
track.billboard.position = pos
@@ -782,7 +740,9 @@
droneTrackPolylineCollection.show = detailVisible.value
droneTrackRuntime = []
const baseTrackColor = Cesium.Color.fromCssColorString('red')
- ; (list || []).forEach((item, trackIndex) => {
+ ; (FIXED_DRONE_TRACK_IDS || []).forEach((trackId, trackIndex) => {
+ const item = (list || []).find(entry => String(entry?.id) === String(trackId))
+ if (!item) return
const position = getDevicePosition(item)
if (!position) return
const points = buildSimulatedTrackPoints({ ...position, height: item.flightHeightM, trackIndex })
@@ -806,7 +766,7 @@
width: 3,
material: trackMaterial,
})
- const droneId = `drone-alarm-${item?.alarmRecordId ?? item?.id ?? trackIndex}`
+ const droneId = `drone-alarm-${trackId}`
const startTime = viewer.clock.startTime
const stopTime = viewer.clock.stopTime
const positionProperty = new Cesium.SampledPositionProperty()
@@ -841,7 +801,7 @@
},
})
const speedMs = Math.round(Cesium.Cartesian3.distance(positions[0], positions[1]) / segmentDuration)
- dronePickMap.set(droneId, {
+ dronePickMap.set(droneId, {
data: {
...item,
flightHeightM: item.flightHeightM ?? points[0].height,
@@ -892,32 +852,27 @@
const entityId = `online-device-${item.id ?? index}-${index}`
const rangeMeters = getDeviceRange(item)
devicePositions.push({ lng: position.longitude, lat: position.latitude })
- const billboard = deviceBillboardCollection.add({
- position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0),
- image: isOnline ? equipmentIcon : offlineEquipmentIcon,
- width: 40,
- height: 56,
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
- })
- billboard.id = entityId
- devicePickMap.set(entityId, { data: item, billboard })
- deviceEntries.push({ position, rangeMeters, billboard, isOnline })
+ deviceEntries.push({ position, rangeMeters, isOnline, entityId, data: item })
})
- if (selectedTargetType.value === 'device' && selectedDeviceBillboard && !devicePickMap.has(selectedDeviceBillboard.id)) {
- closePopup()
- }
if (deviceEntries.length) {
const heights = await getPointPositionsHeight(devicePositions, viewer)
deviceEntries.forEach((entry, index) => {
const height = Number(heights?.[index]?.ASL)
const centerHeight = Number.isFinite(height) ? height : 0
- if (entry.billboard) {
- entry.billboard.position = Cesium.Cartesian3.fromDegrees(
+ const billboard = deviceBillboardCollection.add({
+ position: Cesium.Cartesian3.fromDegrees(
entry.position.longitude,
entry.position.latitude,
centerHeight
- )
- }
+ ),
+ image: entry.isOnline ? equipmentIcon : offlineEquipmentIcon,
+ width: 40,
+ height: 56,
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
+ })
+ billboard.id = entry.entityId
+ devicePickMap.set(entry.entityId, { data: entry.data, billboard })
if (!entry.isOnline) return
if (!Number.isFinite(entry.rangeMeters) || entry.rangeMeters <= 0) return
const primitive = createDeviceRangePrimitiveWithHeight(entry.position, entry.rangeMeters, centerHeight)
@@ -926,6 +881,9 @@
addCockpitPrimitive(primitive)
deviceRingFillPrimitives.push(primitive)
})
+ }
+ if (selectedTargetType.value === 'device' && selectedDeviceBillboard && !devicePickMap.has(selectedDeviceBillboard.id)) {
+ closePopup()
}
reorderCockpitPrimitives()
}
@@ -1040,7 +998,7 @@
if (!trimmed) return null
try {
return JSON.parse(trimmed)
- } catch (error) {}
+ } catch (error) { }
return null
}
@@ -1093,7 +1051,7 @@
.filter(radius => Number.isFinite(radius) && radius > 0)
radii.forEach((radius, levelIndex) => {
const positions = buildEllipsePositions(centerCartesian, radius, radius)
- const style = BUFFER_LEVEL_STYLES[levelIndex] || BUFFER_LEVEL_STYLES[BUFFER_LEVEL_STYLES.length - 1]
+ const style = BUFFER_LEVEL_STYLES[levelIndex] || BUFFER_LEVEL_STYLES[BUFFER_LEVEL_STYLES.length - 1]
if (positions.length >= 3) {
shapes.push({
positions,
@@ -1273,22 +1231,38 @@
const handleDroneSignal = () => emit('droneSignal', selectedDevice.value)
const handleDroneCounter = () => emit('droneCounter', selectedDevice.value)
-const renderCommandPosts = list => {
+const renderCommandPosts = async list => {
if (!viewer) return
ensureCommandPostCollection()
commandPostBillboardCollection.removeAll()
commandPostBillboardCollection.show = detailVisible.value
+ const entries = []
+ const positions = []
; (list || []).forEach((item, index) => {
const position = getDevicePosition(item)
if (!position) return
+ entries.push({ position, index })
+ positions.push({ lng: position.longitude, lat: position.latitude })
+ })
+ if (positions.length) {
+ const heights = await getPointPositionsHeight(positions, viewer)
+ entries.forEach((entry, idx) => {
+ const height = Number(heights?.[idx]?.ASL)
+ const centerHeight = Number.isFinite(height) ? height : 0
commandPostBillboardCollection.add({
- position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0),
+ position: Cesium.Cartesian3.fromDegrees(
+ entry.position.longitude,
+ entry.position.latitude,
+ centerHeight
+ ),
image: commandPostIcon,
width: 40,
height: 56,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
})
})
+ }
reorderCockpitPrimitives()
}
@@ -1308,9 +1282,9 @@
const res = await newDefenseSceneManageList({
time: dayjs().format('YYYY-MM-DD HH:mm:ss')
})
- renderCommandPosts(res?.data?.data ?? [])
+ await renderCommandPosts(res?.data?.data ?? [])
} catch (error) {
- renderCommandPosts([])
+ await renderCommandPosts([])
}
}
@@ -1337,9 +1311,11 @@
)
watch(
- () => props.leftCollapsed,
+ () => props.rightCollapsed,
isCollapsed => {
- if (isCollapsed) showLayerPanel.value = false
+ if (!isCollapsed) return
+ showLayerPanel.value = false
+ showBaseLayerPanel.value = false
}
)
@@ -1378,7 +1354,7 @@
setDroneVisibility(!showCluster)
}
-const handleMapReady = ({ viewer: mapViewer, publicCesium: mapPublic }) => {
+const handleMapReady = async ({ viewer: mapViewer, publicCesium: mapPublic }) => {
if (mapReadyHandled) return
mapReadyHandled = true
viewer = mapViewer
@@ -1388,10 +1364,10 @@
const height = viewer?.camera?.positionCartographic?.height
const stage = getStageByHeight(height)
updateStageDisplay(stage)
+ await loadCommandPosts()
renderDeviceEntities(props.allDevices)
loadPartitions()
loadAggregation()
- loadCommandPosts()
renderSimulatedDroneTrack(props.alarmDrones)
initDeviceClickHandler()
}
@@ -1400,7 +1376,7 @@
updateStageDisplay(stage)
}
-const handleClickOutside = event => {
+const handleLayerClickOutside = event => {
if (!showLayerPanel.value) return
const target = event.target
if (layerWrapRef.value?.contains(target)) return
@@ -1408,13 +1384,13 @@
}
onMounted(() => {
- document.addEventListener('click', handleClickOutside)
+ document.addEventListener('click', handleLayerClickOutside)
const map = mapRef.value?.getMap()
if (map?.viewer) handleMapReady(map)
})
onBeforeUnmount(() => {
- document.removeEventListener('click', handleClickOutside)
+ document.removeEventListener('click', handleLayerClickOutside)
clearDeviceEntities()
clearPartitionEntities()
clearAggregationEntities()
@@ -1428,6 +1404,20 @@
cockpitPrimitiveLayer = null
viewer = null
publicCesium = null
+})
+
+const getMap = () => {
+ return mapRef.value?.getMap()
+}
+
+// 暴露给父组件调用
+const flyTo = (options) => {
+ mapRef.value?.flyToPoint(options)
+}
+
+defineExpose({
+ getMap,
+ flyTo
})
</script>
@@ -1448,14 +1438,14 @@
.layer-control-root {
position: absolute;
- left: 337px;
- bottom: 22px;
- z-index: 9;
+ right: 337px;
+ top: 95px;
+ z-index: 11;
transition: transform 0.3s ease-in-out;
pointer-events: none;
&.collapsed {
- transform: translateX(-317px);
+ transform: translateX(317px);
}
}
@@ -1482,12 +1472,13 @@
display: flex;
flex-direction: column;
position: absolute;
- left: 66px;
- bottom: 0;
+ right: 66px;
+ top: 0;
width: 160px;
max-height: 442px;
background: #191932;
border-radius: 8px 8px 8px 8px;
+ z-index: 99;
.panel-title {
padding: 0 16px;
@@ -1510,50 +1501,136 @@
overflow: auto;
}
- .base-map-title {
- margin-bottom: 8px;
- font-size: 12px;
- color: #ffffff;
- font-weight: 600;
- }
+}
- .base-map-options {
- padding: 16px;
- display: grid;
- grid-template-columns: repeat(2, minmax(0, 1fr));
- gap: 8px;
- }
+.base-layer-switch-root {
+ position: absolute;
+ right: 337px;
+ bottom: 78px;
+ z-index: 11;
+ transition: transform 0.3s ease-in-out;
+ pointer-events: none;
- .base-map-card {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 6px;
+ &.collapsed {
+ transform: translateX(317px);
+ }
+}
+
+.base-layer-switch-wrap {
+ position: relative;
+ pointer-events: auto;
+}
+
+.base-layer-trigger {
+ width: 55px;
+ padding: 8px 0;
+ border-radius: 8px;
+ background: #191932;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 6px;
+ cursor: pointer;
+}
+
+.base-layer-trigger-thumb {
+ width: 36px;
+ height: 36px;
+ border-radius: 6px;
+ display: block;
+ // border: 2px solid #fff;
+ background-size: cover;
+ background-position: center;
+ box-sizing: border-box;
+}
+
+.base-layer-trigger-label {
+ margin-top: 8px;
+ font-size: 12px;
+ line-height: 1;
+ color: #ffffff;
+ font-weight: 700;
+}
+
+.base-layer-panel {
+ position: absolute;
+ right: calc(100% + 10px);
+ bottom: 0;
+ margin-bottom: 0;
+ width: 160px;
+ background: #191932;
+ border-radius: 8px;
+ z-index: 99;
+
+ &::after {
+ content: '';
+ position: absolute;
+ right: -10px;
+ top: 0;
+ width: 10px;
+ height: 100%;
+ background: transparent;
+ }
+}
+
+.base-map-options {
+ padding: 8px;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 8px;
+}
+
+.base-map-card {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ border-radius: 6px;
+ color: #d8e6ff;
+ font-size: 12px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ .base-map-thumb {
+ width: 36px;
+ height: 36px;
border-radius: 6px;
- color: #d8e6ff;
- font-size: 12px;
- cursor: pointer;
- transition: all 0.2s ease;
-
- .base-map-thumb {
- width: 46px;
- height: 46px;
- border-radius: 4px;
- background-size: cover;
- background-position: center;
- box-sizing: border-box;
- }
-
- &.active {
- .base-map-thumb {
- border: 2px solid #2ea8ff;
- }
-
- .base-map-label {
- color: #2ea8ff;
- }
- }
+ // border: 2px solid #fff;
+ background-size: cover;
+ background-position: center;
+ box-sizing: border-box;
}
+
+ .base-map-label {
+ margin-top: 8px;
+ font-size: 12px;
+ line-height: 1;
+ color: #ffffff;
+ font-weight: 700;
+ }
+
+
+ // &.active {
+ // .base-map-thumb {
+ // border: 2px solid #2ea8ff;
+ // }
+
+ // .base-map-label {
+ // color: #2ea8ff;
+ // }
+ // }
+}
+
+.layer-panel-slide-enter-active,
+.layer-panel-slide-leave-active {
+ transition: transform 0.24s ease, opacity 0.24s ease;
+ transform-origin: right center;
+}
+
+.layer-panel-slide-enter-from,
+.layer-panel-slide-leave-to {
+ transform: translateX(24px);
+ opacity: 0;
}
</style>
--
Gitblit v1.9.3