| | |
| | | :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> |
| | | |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | |
| | | import * as Cesium from 'cesium' |
| | | import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue' |
| | | import { buildEllipsePositions } from '@/utils/cesium/shapeTools' |
| | |
| | | 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: { |
| | |
| | | type: Array, |
| | | default: () => [], |
| | | }, |
| | | leftCollapsed: { |
| | | rightCollapsed: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | |
| | | 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) |
| | |
| | | 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([ |
| | | { |
| | |
| | | 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) |
| | |
| | | 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 = () => { |
| | |
| | | const basePoints = [ |
| | | [ |
| | | { |
| | | longitude: 114.964975, |
| | | latitude: 27.134855, |
| | | longitude: 114.929475, |
| | | latitude: 27.136575, |
| | | height: 200 |
| | | }, |
| | | { |
| | | longitude: 114.963966, |
| | | latitude: 27.132836, |
| | | longitude: 114.928466, |
| | | latitude: 27.134556, |
| | | height: 200 |
| | | }, |
| | | { |
| | | longitude: 114.963966, |
| | | latitude: 27.132836, |
| | | longitude: 114.928466, |
| | | latitude: 27.134556, |
| | | height: 320 |
| | | }, |
| | | { |
| | | longitude: 114.963974, |
| | | latitude: 27.132677, |
| | | longitude: 114.928474, |
| | | latitude: 27.134397, |
| | | height: 320 |
| | | }, |
| | | { |
| | | longitude: 114.963432, |
| | | latitude: 27.131665, |
| | | longitude: 114.927932, |
| | | latitude: 27.133385, |
| | | height: 320 |
| | | }, |
| | | { |
| | | longitude: 114.962865, |
| | | latitude: 27.130377, |
| | | longitude: 114.927365, |
| | | latitude: 27.132097, |
| | | height: 320 |
| | | }, |
| | | { |
| | | longitude: 114.965318, |
| | | latitude: 27.129925, |
| | | longitude: 114.929818, |
| | | latitude: 27.131645, |
| | | height: 320 |
| | | }, |
| | | { |
| | | longitude: 114.960144, |
| | | latitude: 27.134902, |
| | | 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.925958, |
| | | latitude: 27.096963, |
| | | longitude: 114.931281, |
| | | latitude: 26.827801, |
| | | height: 400 |
| | | }, |
| | | { |
| | | longitude: 114.925836, |
| | | latitude: 27.096102, |
| | | longitude: 114.931159, |
| | | latitude: 26.826940, |
| | | height: 400 |
| | | }, |
| | | { |
| | | longitude: 114.928384, |
| | | latitude: 27.095866, |
| | | longitude: 114.933707, |
| | | latitude: 26.826704, |
| | | height: 400 |
| | | }, |
| | | { |
| | | longitude: 114.929874, |
| | | latitude: 27.096095, |
| | | longitude: 114.935197, |
| | | latitude: 26.826933, |
| | | height: 400 |
| | | }, |
| | | { |
| | | longitude: 114.931048, |
| | | latitude: 27.097666, |
| | | longitude: 114.936371, |
| | | latitude: 26.828504, |
| | | height: 400 |
| | | }, |
| | | ], |
| | |
| | | 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 |
| | |
| | | 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 }) |
| | |
| | | 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() |
| | |
| | | }, |
| | | }) |
| | | 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, |
| | |
| | | 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 (!trimmed) return null |
| | | try { |
| | | return JSON.parse(trimmed) |
| | | } catch (error) {} |
| | | } catch (error) { } |
| | | return null |
| | | } |
| | | |
| | |
| | | .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, |
| | |
| | | width: 40, |
| | | height: 56, |
| | | verticalOrigin: Cesium.VerticalOrigin.BOTTOM, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }) |
| | | }) |
| | | } |
| | |
| | | ) |
| | | |
| | | watch( |
| | | () => props.leftCollapsed, |
| | | () => props.rightCollapsed, |
| | | isCollapsed => { |
| | | if (isCollapsed) showLayerPanel.value = false |
| | | if (!isCollapsed) return |
| | | showLayerPanel.value = false |
| | | showBaseLayerPanel.value = false |
| | | } |
| | | ) |
| | | |
| | |
| | | setDroneVisibility(!showCluster) |
| | | } |
| | | |
| | | const handleMapReady = ({ viewer: mapViewer, publicCesium: mapPublic }) => { |
| | | const handleMapReady = async ({ viewer: mapViewer, publicCesium: mapPublic }) => { |
| | | if (mapReadyHandled) return |
| | | mapReadyHandled = true |
| | | viewer = mapViewer |
| | |
| | | const height = viewer?.camera?.positionCartographic?.height |
| | | const stage = getStageByHeight(height) |
| | | updateStageDisplay(stage) |
| | | await loadCommandPosts() |
| | | renderDeviceEntities(props.allDevices) |
| | | loadPartitions() |
| | | loadAggregation() |
| | | loadCommandPosts() |
| | | renderSimulatedDroneTrack(props.alarmDrones) |
| | | initDeviceClickHandler() |
| | | } |
| | |
| | | updateStageDisplay(stage) |
| | | } |
| | | |
| | | const handleClickOutside = event => { |
| | | const handleLayerClickOutside = event => { |
| | | if (!showLayerPanel.value) return |
| | | const target = event.target |
| | | if (layerWrapRef.value?.contains(target)) return |
| | |
| | | } |
| | | |
| | | 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() |
| | |
| | | cockpitPrimitiveLayer = null |
| | | viewer = null |
| | | publicCesium = null |
| | | }) |
| | | |
| | | const getMap = () => { |
| | | return mapRef.value?.getMap() |
| | | } |
| | | |
| | | // 暴露给父组件调用 |
| | | const flyTo = (options) => { |
| | | mapRef.value?.flyToPoint(options) |
| | | } |
| | | |
| | | defineExpose({ |
| | | getMap, |
| | | flyTo |
| | | }) |
| | | </script> |
| | | |
| | |
| | | |
| | | .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); |
| | | } |
| | | } |
| | | |
| | |
| | | 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; |
| | |
| | | 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> |