美化
This commit is contained in:
@@ -102,6 +102,7 @@
|
||||
<div class="map-corner bottom-left"></div>
|
||||
<div class="map-corner bottom-right"></div>
|
||||
<div class="map-radar-glow"></div>
|
||||
<div class="map-3d-stage"></div>
|
||||
<div class="map-title-bar">
|
||||
<span class="map-title-main">全国设备态势</span>
|
||||
<span class="map-title-sub">REAL-TIME DISTRIBUTION</span>
|
||||
@@ -233,6 +234,10 @@
|
||||
let resizeObserver = null
|
||||
const mapInstance = ref(null)
|
||||
const markers = ref([])
|
||||
let buildingsLayer = null
|
||||
|
||||
const default3DCenter = [120.153576, 30.287459]
|
||||
const default3DZoom = 17.6
|
||||
|
||||
const tableData = ref([])
|
||||
|
||||
@@ -391,12 +396,38 @@
|
||||
}))
|
||||
console.log('devices', devices.value)
|
||||
nextTick(() => {
|
||||
if (mapInstance.value) {
|
||||
mapInstance.value.setZoomAndCenter(default3DZoom, getValidDeviceCenter())
|
||||
}
|
||||
addMarkers()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getValidDeviceCenter = () => {
|
||||
const firstValidDevice = devices.value.find((device) => {
|
||||
const longitude = Number(device.gatewayLong)
|
||||
const latitude = Number(device.gatewayLat)
|
||||
return Number.isFinite(longitude) && Number.isFinite(latitude)
|
||||
})
|
||||
|
||||
if (!firstValidDevice) return default3DCenter
|
||||
return [Number(firstValidDevice.gatewayLong), Number(firstValidDevice.gatewayLat)]
|
||||
}
|
||||
|
||||
const add3DBuildingLayer = () => {
|
||||
if (!mapInstance.value || typeof AMap === 'undefined' || !AMap.Buildings) return
|
||||
|
||||
buildingsLayer = new AMap.Buildings({
|
||||
zooms: [3, 20],
|
||||
heightFactor: 1.6,
|
||||
wallColor: 'rgba(42, 169, 255, 0.88)',
|
||||
roofColor: 'rgba(139, 233, 255, 0.78)'
|
||||
})
|
||||
mapInstance.value.add(buildingsLayer)
|
||||
}
|
||||
|
||||
const initMap = () => {
|
||||
if (typeof AMap === 'undefined') {
|
||||
console.error('高德地图API未加载')
|
||||
@@ -406,21 +437,32 @@
|
||||
console.log('开始初始化地图')
|
||||
|
||||
mapInstance.value = new AMap.Map('chinaMap', {
|
||||
zoom: 4.8,
|
||||
center: [105.6, 36.4],
|
||||
mapStyle: 'amap://styles/darkblue',
|
||||
zoom: default3DZoom,
|
||||
zooms: [3, 20],
|
||||
center: getValidDeviceCenter(),
|
||||
mapStyle: 'amap://styles/blue',
|
||||
viewMode: '3D',
|
||||
pitch: 34,
|
||||
rotation: -8,
|
||||
pitch: 68,
|
||||
rotation: -28,
|
||||
terrain: true,
|
||||
pitchEnable: true,
|
||||
rotateEnable: true,
|
||||
dragEnable: true,
|
||||
zoomEnable: true,
|
||||
buildingAnimation: true,
|
||||
showBuildingBlock: true,
|
||||
features: ['bg', 'road', 'building', 'point'],
|
||||
showLabel: false,
|
||||
skyColor: '#020713'
|
||||
})
|
||||
|
||||
add3DBuildingLayer()
|
||||
|
||||
mapInstance.value.on('complete', () => {
|
||||
console.log('地图加载完成')
|
||||
// 地图加载完成后,再尝试添加标记点
|
||||
if (devices.value && devices.value.length > 0) {
|
||||
const center = getValidDeviceCenter()
|
||||
mapInstance.value.setZoomAndCenter(default3DZoom, center)
|
||||
addMarkers()
|
||||
}
|
||||
})
|
||||
@@ -450,8 +492,12 @@
|
||||
testData.forEach((device, index) => {
|
||||
// console.log(`渲染第 ${index} 个点:`, device)
|
||||
|
||||
const longitude = Number(device.gatewayLong)
|
||||
const latitude = Number(device.gatewayLat)
|
||||
if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) return
|
||||
|
||||
const marker = new AMap.Marker({
|
||||
position: [device.gatewayLong, device.gatewayLat],
|
||||
position: [longitude, latitude],
|
||||
content: createMarkerContent(device.status),
|
||||
anchor: 'bottom-center',
|
||||
zIndex: 120
|
||||
@@ -584,53 +630,63 @@
|
||||
|
||||
.device-stat-content {
|
||||
display: flex;
|
||||
// gap: 0.2rem;
|
||||
align-items: center;
|
||||
gap: 0.1rem;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.device-ring-chart {
|
||||
flex: 1;
|
||||
min-height: 1.5rem;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
flex: 0 0 1.58rem;
|
||||
width: 1.58rem;
|
||||
height: 1.58rem;
|
||||
min-width: 1.58rem;
|
||||
min-height: 1.58rem;
|
||||
}
|
||||
|
||||
.device-list {
|
||||
flex: 0.8;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// gap: 0.12rem;
|
||||
justify-content: center;
|
||||
gap: 0.03rem;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.device-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.12rem;
|
||||
font-size: 0.18rem;
|
||||
gap: 0.05rem;
|
||||
min-width: 0;
|
||||
font-size: 0.12rem;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.device-dot {
|
||||
width: 0.1rem;
|
||||
height: 0.1rem;
|
||||
flex: 0 0 auto;
|
||||
width: 0.08rem;
|
||||
height: 0.08rem;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.device-name {
|
||||
color: var(--tech-text);
|
||||
flex: 1;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.device-count {
|
||||
color: var(--tech-text);
|
||||
flex: 0 0 auto;
|
||||
font-weight: bold;
|
||||
font-size: 0.14rem;
|
||||
margin-right: 0.06rem;
|
||||
font-size: 0.12rem;
|
||||
margin-right: 0.01rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -1099,8 +1155,47 @@
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background:
|
||||
radial-gradient(circle at 50% 48%, rgba(0, 212, 255, 0.18), transparent 38%),
|
||||
linear-gradient(180deg, rgba(2, 8, 23, 0.18), rgba(2, 8, 23, 0.55));
|
||||
radial-gradient(ellipse at 50% 64%, rgba(0, 212, 255, 0.3), transparent 45%),
|
||||
linear-gradient(180deg, rgba(8, 47, 73, 0.04), rgba(2, 8, 23, 0.42));
|
||||
perspective: 8rem;
|
||||
}
|
||||
|
||||
.map-container-full .amap-layer,
|
||||
.map-container-full .amap-maps,
|
||||
.map-container-full canvas {
|
||||
filter: brightness(1.22) saturate(1.18) contrast(1.06);
|
||||
}
|
||||
|
||||
.map-container-full::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 8%;
|
||||
right: 8%;
|
||||
bottom: 0.34rem;
|
||||
z-index: 998;
|
||||
height: 2.4rem;
|
||||
pointer-events: none;
|
||||
background:
|
||||
repeating-linear-gradient(90deg, rgba(0, 212, 255, 0.18) 0 1px, transparent 1px 0.38rem),
|
||||
repeating-linear-gradient(0deg, rgba(0, 212, 255, 0.16) 0 1px, transparent 1px 0.38rem),
|
||||
radial-gradient(ellipse at 50% 50%, rgba(0, 212, 255, 0.16), transparent 68%);
|
||||
border: 1px solid rgba(0, 212, 255, 0.2);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 0.42rem rgba(0, 212, 255, 0.1);
|
||||
transform: rotateX(68deg) translateY(0.2rem);
|
||||
transform-origin: center bottom;
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
.map-container-full::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 999;
|
||||
pointer-events: none;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(137, 221, 255, 0.16), transparent 16%, transparent 72%, rgba(2, 8, 23, 0.24)),
|
||||
linear-gradient(90deg, rgba(2, 8, 23, 0.28), transparent 16%, transparent 84%, rgba(2, 8, 23, 0.28));
|
||||
}
|
||||
|
||||
.map-control {
|
||||
@@ -1204,22 +1299,39 @@
|
||||
.map-radar-glow {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 52%;
|
||||
top: 58%;
|
||||
z-index: 1000;
|
||||
width: 5.2rem;
|
||||
height: 5.2rem;
|
||||
width: 5.6rem;
|
||||
height: 5.6rem;
|
||||
border: 1px solid rgba(0, 212, 255, 0.22);
|
||||
border-radius: 50%;
|
||||
background:
|
||||
repeating-radial-gradient(circle, transparent 0 0.62rem, rgba(0, 212, 255, 0.08) 0.63rem 0.64rem),
|
||||
conic-gradient(from 0deg, transparent 0deg, rgba(0, 212, 255, 0.2) 46deg, transparent 88deg, transparent 360deg);
|
||||
box-shadow: inset 0 0 0.42rem rgba(0, 212, 255, 0.08), 0 0 0.36rem rgba(0, 212, 255, 0.08);
|
||||
transform: translate(-50%, -50%);
|
||||
animation: radarRotate 12s linear infinite;
|
||||
transform: translate(-50%, -50%) rotateX(62deg);
|
||||
transform-origin: center center;
|
||||
animation: radarRotate3d 12s linear infinite;
|
||||
mix-blend-mode: screen;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.map-3d-stage {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 0.28rem;
|
||||
z-index: 1000;
|
||||
width: 5.8rem;
|
||||
height: 1.55rem;
|
||||
pointer-events: none;
|
||||
border: 1px solid rgba(245, 158, 11, 0.24);
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(ellipse at center, rgba(245, 158, 11, 0.14), transparent 62%);
|
||||
box-shadow: 0 0 0.32rem rgba(245, 158, 11, 0.1), inset 0 0 0.28rem rgba(0, 212, 255, 0.08);
|
||||
transform: translateX(-50%);
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
.map-corner {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
@@ -1392,50 +1504,36 @@
|
||||
.container .right .module-card {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(0, 212, 255, 0.16);
|
||||
border-radius: 0.08rem;
|
||||
transform: scale(0.94);
|
||||
transform-origin: center center;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background:
|
||||
linear-gradient(135deg, rgba(14, 165, 233, 0.12), rgba(15, 23, 42, 0.28) 44%, rgba(245, 158, 11, 0.07)),
|
||||
linear-gradient(180deg, rgba(15, 23, 42, 0.5), rgba(2, 6, 23, 0.18));
|
||||
box-shadow:
|
||||
inset 0 0 0.22rem rgba(0, 212, 255, 0.08),
|
||||
0 0.08rem 0.28rem rgba(0, 0, 0, 0.28);
|
||||
backdrop-filter: blur(4px);
|
||||
transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: inherit;
|
||||
padding: 1px;
|
||||
background: linear-gradient(135deg, rgba(0, 212, 255, 0.78), transparent 32%, transparent 62%, rgba(245, 158, 11, 0.55));
|
||||
mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
opacity: 0.75;
|
||||
}
|
||||
radial-gradient(circle at 12% 12%, rgba(0, 212, 255, 0.08), transparent 42%),
|
||||
linear-gradient(135deg, rgba(14, 165, 233, 0.05), rgba(15, 23, 42, 0.1) 48%, rgba(245, 158, 11, 0.035));
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
transition: background 0.35s ease, transform 0.35s ease;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -65%;
|
||||
width: 45%;
|
||||
left: -70%;
|
||||
width: 38%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 212, 255, 0.16), transparent);
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 212, 255, 0.08), transparent);
|
||||
transform: skewX(-18deg);
|
||||
animation: cardGlint 7s ease-in-out infinite;
|
||||
pointer-events: none;
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-0.02rem);
|
||||
border-color: rgba(0, 212, 255, 0.42);
|
||||
box-shadow:
|
||||
inset 0 0 0.28rem rgba(0, 212, 255, 0.13),
|
||||
0 0.12rem 0.32rem rgba(0, 0, 0, 0.34),
|
||||
0 0 0.22rem rgba(0, 212, 255, 0.18);
|
||||
transform: scale(0.98);
|
||||
background:
|
||||
radial-gradient(circle at 12% 12%, rgba(0, 212, 255, 0.11), transparent 44%),
|
||||
linear-gradient(135deg, rgba(14, 165, 233, 0.07), rgba(15, 23, 42, 0.12) 48%, rgba(245, 158, 11, 0.04));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1447,24 +1545,26 @@
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
right: 18%;
|
||||
bottom: -0.06rem;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, rgba(0, 212, 255, 0.8), rgba(59, 130, 246, 0.2), transparent);
|
||||
box-shadow: 0 0 0.12rem rgba(0, 212, 255, 0.55);
|
||||
background: linear-gradient(90deg, rgba(0, 212, 255, 0.34), rgba(59, 130, 246, 0.08), transparent);
|
||||
box-shadow: 0 0 0.08rem rgba(0, 212, 255, 0.18);
|
||||
opacity: 0.55;
|
||||
}
|
||||
}
|
||||
|
||||
.container .module-title {
|
||||
color: #eefaff;
|
||||
font-size: 0.18rem;
|
||||
letter-spacing: 0.02rem;
|
||||
text-shadow: 0 0 0.12rem rgba(0, 212, 255, 0.55);
|
||||
}
|
||||
|
||||
.container .title-icon {
|
||||
position: relative;
|
||||
width: 0.08rem;
|
||||
height: 0.26rem;
|
||||
width: 0.07rem;
|
||||
height: 0.23rem;
|
||||
background: linear-gradient(180deg, #f59e0b 0%, #00e5ff 45%, #2563eb 100%);
|
||||
box-shadow: 0 0 0.12rem rgba(0, 212, 255, 0.9);
|
||||
animation: iconPulse 1.8s ease-in-out infinite;
|
||||
@@ -1673,6 +1773,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.container .device-item {
|
||||
padding: 0.04rem 0.04rem;
|
||||
}
|
||||
|
||||
.container .device-dot,
|
||||
.container .alert-dot,
|
||||
.container .status-dot {
|
||||
@@ -1988,6 +2092,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes radarRotate3d {
|
||||
0% {
|
||||
transform: translate(-50%, -50%) rotateX(62deg) rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: translate(-50%, -50%) rotateX(62deg) rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes controlGlint {
|
||||
0%, 58% {
|
||||
left: -70%;
|
||||
|
||||
@@ -147,7 +147,7 @@ export const getDeviceStatOption = (deviceTypes) => {
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['45%', '70%'],
|
||||
radius: ['42%', '68%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: pieItemStyle,
|
||||
@@ -155,7 +155,7 @@ export const getDeviceStatOption = (deviceTypes) => {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: `{total|${total}}\n{name|设备总数}`,
|
||||
rich: createCenterLabelRich(18, 12)
|
||||
rich: createCenterLabelRich(16, 10)
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
|
||||
Reference in New Issue
Block a user