@terra.gl/core 0.0.1-alpha.6 → 0.0.1-alpha.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +200 -0
- package/dist/README.md +200 -0
- package/dist/README_CN.md +201 -0
- package/dist/assets/favicon/android-chrome-192x192.png +0 -0
- package/dist/assets/favicon/android-chrome-512x512.png +0 -0
- package/dist/assets/favicon/apple-touch-icon.png +0 -0
- package/dist/assets/favicon/favicon-16x16.png +0 -0
- package/dist/assets/favicon/favicon-32x32.png +0 -0
- package/dist/assets/favicon/favicon.ico +0 -0
- package/dist/assets/terra.css +501 -0
- package/dist/index.d.ts +7821 -1239
- package/dist/index.js +21083 -7605
- package/dist/index.umd.cjs +580 -113
- package/package.json +21 -8
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Terra-GL Core
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
**基于 Three.js 的高性能 WebGL 三维地图引擎 🌍**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@terra.gl/core)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
10
|
+
[English](./README.md) | 简体中文
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📖 简介
|
|
17
|
+
|
|
18
|
+
Terra-GL Core 是一个基于 Three.js 构建的现代化 WebGL 三维地图引擎核心库。它提供了完整的 GIS 可视化能力,支持瓦片地图加载、矢量要素渲染、三维模型展示等丰富功能,适用于构建智慧城市、数字孪生、地理信息系统等应用场景。
|
|
19
|
+
|
|
20
|
+
### ✨ 核心特性
|
|
21
|
+
|
|
22
|
+
- 🚀 **高性能渲染** - 基于 Three.js WebGL 引擎,支持大规模数据可视化
|
|
23
|
+
- 🗺️ **多源瓦片支持** - 兼容 WMTS、ArcGIS、MapBox、天地图等主流瓦片服务
|
|
24
|
+
- 📐 **丰富的要素类型** - 支持点、线、面、标注、模型等多种地理要素
|
|
25
|
+
- 🎨 **灵活的样式系统** - 支持动态样式配置与主题切换
|
|
26
|
+
- 🎯 **完善的事件系统** - 提供地图交互、要素事件等丰富的事件机制
|
|
27
|
+
- 🛠️ **强大的绘制工具** - 内置绘制工具,支持点线面等要素的交互式绘制
|
|
28
|
+
- 🌈 **三维效果增强** - 支持天空盒、阴影、HDR、云层等视觉效果
|
|
29
|
+
- 📱 **UI 组件系统** - 提供信息窗口、工具提示等常用 UI 组件
|
|
30
|
+
- 🔧 **碰撞检测避让** - 智能标注避让,优化密集要素显示效果
|
|
31
|
+
- 📦 **模块化设计** - 清晰的代码结构,易于扩展和维护
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 🌟 为什么选择 Terra-GL
|
|
36
|
+
|
|
37
|
+
### 💪 技术优势
|
|
38
|
+
|
|
39
|
+
**1. 原生 Three.js 架构**
|
|
40
|
+
- 完全基于 Three.js 构建,无额外渲染层抽象
|
|
41
|
+
- 直接访问 Three.js 场景对象,可自由扩展
|
|
42
|
+
- 充分利用 WebGL 的性能优势
|
|
43
|
+
- 与 Three.js 生态无缝集成
|
|
44
|
+
|
|
45
|
+
**2. 专业的 GIS 能力**
|
|
46
|
+
- 支持多种坐标系统和投影变换(Web Mercator、WGS84 等)
|
|
47
|
+
- 完整的瓦片地图系统,支持海量数据加载
|
|
48
|
+
- 兼容主流地图服务(WMTS、ArcGIS、MapBox、天地图)
|
|
49
|
+
- 矢量瓦片(MVT)渲染支持
|
|
50
|
+
|
|
51
|
+
**3. 丰富的可视化能力**
|
|
52
|
+
- 二维矢量要素(点、线、面)与三维模型统一管理
|
|
53
|
+
- 支持 GLTF/GLB 模型加载,带 Draco 压缩
|
|
54
|
+
- 实时阴影、HDR 环境光、后期处理效果
|
|
55
|
+
- 粒子云层、水面波纹等特效支持
|
|
56
|
+
|
|
57
|
+
**4. 灵活的交互体验**
|
|
58
|
+
- 完善的事件系统(地图事件、要素事件)
|
|
59
|
+
- 内置绘制工具,支持点线面圆等图形绘制
|
|
60
|
+
- 智能碰撞检测与标注避让
|
|
61
|
+
- 信息窗口、工具提示等 UI 组件
|
|
62
|
+
|
|
63
|
+
**5. 开发友好**
|
|
64
|
+
- TypeScript 编写,完整类型定义
|
|
65
|
+
- 清晰的模块化设计,易于理解和扩展
|
|
66
|
+
- 丰富的示例和文档
|
|
67
|
+
- 支持 ES Module 和 UMD 两种模块格式
|
|
68
|
+
|
|
69
|
+
### 💡 适用场景
|
|
70
|
+
|
|
71
|
+
| 场景类型 | 典型应用 | 核心能力 |
|
|
72
|
+
|---------|---------|----------|
|
|
73
|
+
| **🏙️ 智慧城市** | 城市三维建模、BIM 展示、规划方案对比 | 大规模模型渲染、LOD 控制、图层管理 |
|
|
74
|
+
| **🔮 数字孪生** | 工业园区、智慧楼宇、设备监控 | 实时数据绑定、动态更新、状态可视化 |
|
|
75
|
+
| **🗺️ 地理信息** | 地形分析、资源分布、管线管理 | 坐标转换、空间查询、缓冲区分析 |
|
|
76
|
+
| **🚨 应急指挥** | 态势展示、资源调度、路径规划 | 实时轨迹、热力图、动态标绘 |
|
|
77
|
+
|
|
78
|
+
### ⚡ 性能特点
|
|
79
|
+
|
|
80
|
+
- **瓦片按需加载** - 根据视野范围动态加载瓦片,支持数万平方公里数据
|
|
81
|
+
- **LOD 层级控制** - 自动根据距离切换模型细节,优化渲染性能
|
|
82
|
+
- **四叉树空间索引** - 快速查询可见要素,提升交互响应速度
|
|
83
|
+
- **WebGL 实例化渲染** - 批量绘制相同几何体,降低 Draw Call
|
|
84
|
+
- **碰撞避让优化** - 智能隐藏重叠标注,保持界面整洁
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
## 📚 核心模块概述
|
|
88
|
+
|
|
89
|
+
### 🏗️ 核心架构
|
|
90
|
+
- **🗺️ Map** - 地图容器,统一管理图层、视图、事件
|
|
91
|
+
- **👁️ Viewer** - 基于Three.js的渲染引擎,管理场景、相机、光照
|
|
92
|
+
- **📚 Layer System** - 分层管理瓦片、矢量、模型等数据
|
|
93
|
+
- **📍 Feature** - 点、线、面、模型等地理要素的抽象
|
|
94
|
+
- **🔲 TileSystem** - 支持WMTS、ArcGIS等多源瓦片的动态加载系统
|
|
95
|
+
|
|
96
|
+
### 🔑 关键特性
|
|
97
|
+
- **⚡ 事件系统** - 完整的地图/要素级事件机制
|
|
98
|
+
- **✏️ 绘制工具** - 内置交互式绘制(点、线、面、圆等)
|
|
99
|
+
- **🎨 UI组件** - InfoWindow、ToolTip等常用组件
|
|
100
|
+
- **🎯 碰撞检测** - 智能标注避让,优化密集场景显示
|
|
101
|
+
- **🎭 样式系统** - 统一的矢量/模型样式配置
|
|
102
|
+
|
|
103
|
+
[查看详细API文档 →](链接到详细文档)
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 🚀 快速开始
|
|
108
|
+
|
|
109
|
+
### 📦 安装
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npm install @terra.gl/core three@^0.171.0
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### ⚡ 5 分钟上手
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
import * as terra from '@terra.gl/core';
|
|
119
|
+
|
|
120
|
+
// 创建地图
|
|
121
|
+
const map = new terra.Map('#map', {
|
|
122
|
+
center: [116.397428, 39.90923, 1000], // [经度, 纬度, 相机高度]
|
|
123
|
+
basemap: {
|
|
124
|
+
Baselayers: [
|
|
125
|
+
new terra.WMTSTileLayer('base', {
|
|
126
|
+
source: new terra.WMTSSource({
|
|
127
|
+
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
|
|
128
|
+
}),
|
|
129
|
+
projection: terra.ProjectFactory.createFromID('3857', 0)
|
|
130
|
+
})
|
|
131
|
+
],
|
|
132
|
+
minLevel: 1,
|
|
133
|
+
maxLevel: 18
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// 添加标注
|
|
138
|
+
const label = new terra.Label({
|
|
139
|
+
geometry: { type: 'Point', coordinates: [116.397428, 39.90923, 0] },
|
|
140
|
+
style: { text: '北京天安门', fontSize: 16, fontColor: '#ffffff' }
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const pointLayer = new terra.PointLayer('points');
|
|
144
|
+
map.addLayer(pointLayer);
|
|
145
|
+
label.addTo(pointLayer);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
查看 `example/` 目录获取更多示例。
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 🔧 开发
|
|
153
|
+
|
|
154
|
+
### 🔨 构建
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# 开发模式(监听文件变化)
|
|
158
|
+
npm run dev
|
|
159
|
+
|
|
160
|
+
# 生产构建
|
|
161
|
+
npm run build
|
|
162
|
+
|
|
163
|
+
# 生成 API 文档
|
|
164
|
+
npm run doc
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 📂 项目结构
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
packages/core/
|
|
171
|
+
├── src/ # 源代码
|
|
172
|
+
├── dist/ # 编译输出
|
|
173
|
+
├── docs/ # API 文档
|
|
174
|
+
├── assets/ # 资源文件
|
|
175
|
+
├── package.json # 包配置
|
|
176
|
+
├── tsconfig.json # TypeScript 配置
|
|
177
|
+
├── vite.config.ts # Vite 构建配置
|
|
178
|
+
└── typedoc.json # 文档生成配置
|
|
179
|
+
```
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 🤝 贡献
|
|
183
|
+
|
|
184
|
+
欢迎提交 Issue 和 Pull Request!
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 🔗 相关链接
|
|
189
|
+
|
|
190
|
+
- [Three.js 官网](https://threejs.org/)
|
|
191
|
+
- [GeoJSON 规范](https://geojson.org/)
|
|
192
|
+
- [WMTS 标准](https://www.ogc.org/standards/wmts)
|
|
193
|
+
<!-- - [three-tile 官网](https://sxguojf.github.io/three-tile-doc/1.introduce/01.whatIs/) -->
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
<div align="center">
|
|
198
|
+
|
|
199
|
+
**如果这个项目对你有帮助,请给一个 ⭐️ Star 支持一下!**
|
|
200
|
+
|
|
201
|
+
</div>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
/* 毛玻璃核心样式 - 确保在支持的环境中生效 */
|
|
2
|
+
.terra-infowindow,
|
|
3
|
+
.terra-tooltip {
|
|
4
|
+
background: rgba(255, 255, 255, 0.8);
|
|
5
|
+
/* 关键:毛玻璃效果 */
|
|
6
|
+
backdrop-filter: blur(20px) saturate(180%);
|
|
7
|
+
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
8
|
+
/* Safari 兼容性处理 */
|
|
9
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
10
|
+
box-shadow:
|
|
11
|
+
0 8px 32px rgba(0, 0, 0, 0.1),
|
|
12
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.5);
|
|
13
|
+
animation: none;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* 如果 backdrop-filter 不被支持,使用纯色背景作为回退 */
|
|
17
|
+
@supports not (backdrop-filter: blur(20px)) {
|
|
18
|
+
|
|
19
|
+
.terra-infowindow,
|
|
20
|
+
.terra-tooltip {
|
|
21
|
+
background: rgba(255, 255, 255, 0.95);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* ==================== InfoWindow 主容器 ==================== */
|
|
26
|
+
.terra-infowindow {
|
|
27
|
+
border-radius: 14px;
|
|
28
|
+
box-sizing: border-box;
|
|
29
|
+
min-width: 200px;
|
|
30
|
+
position: absolute;
|
|
31
|
+
/* 重要:使用 visible 而不是 hidden,让三角指针可以显示 */
|
|
32
|
+
overflow: visible;
|
|
33
|
+
/* 增强的毛玻璃层叠效果 */
|
|
34
|
+
background: linear-gradient(135deg,
|
|
35
|
+
rgba(255, 255, 255, 0.9) 0%,
|
|
36
|
+
rgba(255, 255, 255, 0.7) 100%);
|
|
37
|
+
/* 内部发光边缘 */
|
|
38
|
+
box-shadow:
|
|
39
|
+
0 10px 40px rgba(0, 0, 0, 0.12),
|
|
40
|
+
0 0 0 0.5px rgba(255, 255, 255, 0.3) inset;
|
|
41
|
+
/* 设置 z-index 确保三角在正确层级 */
|
|
42
|
+
z-index: 1000;
|
|
43
|
+
/* 强制关掉任何来源的动画/过渡 */
|
|
44
|
+
animation: none !important;
|
|
45
|
+
transition: none !important;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* 内部容器 - 用于保持圆角裁剪 */
|
|
49
|
+
.terra-infowindow-inner {
|
|
50
|
+
border-radius: 14px;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
height: 100%;
|
|
53
|
+
position: relative;
|
|
54
|
+
z-index: 2;
|
|
55
|
+
background: inherit;
|
|
56
|
+
backdrop-filter: inherit;
|
|
57
|
+
-webkit-backdrop-filter: inherit;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* ==================== 底部三角指针 ==================== */
|
|
61
|
+
/* 外层阴影三角 */
|
|
62
|
+
.terra-infowindow::before {
|
|
63
|
+
content: "";
|
|
64
|
+
position: absolute;
|
|
65
|
+
bottom: -10px;
|
|
66
|
+
left: 50%;
|
|
67
|
+
transform: translateX(-50%);
|
|
68
|
+
width: 0;
|
|
69
|
+
height: 0;
|
|
70
|
+
z-index: 1;
|
|
71
|
+
border-left: 9px solid transparent;
|
|
72
|
+
border-right: 9px solid transparent;
|
|
73
|
+
border-top: 10px solid rgba(255, 255, 255, 0.3);
|
|
74
|
+
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
|
|
75
|
+
pointer-events: none;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* 内层毛玻璃三角 */
|
|
79
|
+
.terra-infowindow::after {
|
|
80
|
+
content: "";
|
|
81
|
+
position: absolute;
|
|
82
|
+
bottom: -9px;
|
|
83
|
+
left: 50%;
|
|
84
|
+
transform: translateX(-50%);
|
|
85
|
+
width: 0;
|
|
86
|
+
height: 0;
|
|
87
|
+
z-index: 2;
|
|
88
|
+
border-left: 8px solid transparent;
|
|
89
|
+
border-right: 8px solid transparent;
|
|
90
|
+
border-top: 9px solid rgba(255, 255, 255, 0.8);
|
|
91
|
+
/* 继承毛玻璃效果 */
|
|
92
|
+
/* backdrop-filter: blur(20px) saturate(180%);
|
|
93
|
+
-webkit-backdrop-filter: blur(20px) saturate(180%); */
|
|
94
|
+
pointer-events: none;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* 为不同位置的三角提供样式(如果需要的话) */
|
|
98
|
+
/* 顶部三角 */
|
|
99
|
+
.terra-infowindow.terra-arrow-top::before {
|
|
100
|
+
top: -10px;
|
|
101
|
+
bottom: auto;
|
|
102
|
+
border-top: none;
|
|
103
|
+
border-bottom: 10px solid rgba(255, 255, 255, 0.3);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.terra-infowindow.terra-arrow-top::after {
|
|
107
|
+
top: -9px;
|
|
108
|
+
bottom: auto;
|
|
109
|
+
border-top: none;
|
|
110
|
+
border-bottom: 9px solid rgba(255, 255, 255, 0.8);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* 左侧三角 */
|
|
114
|
+
.terra-infowindow.terra-arrow-left::before {
|
|
115
|
+
left: -10px;
|
|
116
|
+
top: 50%;
|
|
117
|
+
bottom: auto;
|
|
118
|
+
transform: translateY(-50%);
|
|
119
|
+
border-top: 9px solid transparent;
|
|
120
|
+
border-bottom: 9px solid transparent;
|
|
121
|
+
border-right: 10px solid rgba(255, 255, 255, 0.3);
|
|
122
|
+
border-left: none;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.terra-infowindow.terra-arrow-left::after {
|
|
126
|
+
left: -9px;
|
|
127
|
+
top: 50%;
|
|
128
|
+
bottom: auto;
|
|
129
|
+
transform: translateY(-50%);
|
|
130
|
+
border-top: 8px solid transparent;
|
|
131
|
+
border-bottom: 8px solid transparent;
|
|
132
|
+
border-right: 9px solid rgba(255, 255, 255, 0.8);
|
|
133
|
+
border-left: none;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* 右侧三角 */
|
|
137
|
+
.terra-infowindow.terra-arrow-right::before {
|
|
138
|
+
right: -10px;
|
|
139
|
+
left: auto;
|
|
140
|
+
top: 50%;
|
|
141
|
+
bottom: auto;
|
|
142
|
+
transform: translateY(-50%);
|
|
143
|
+
border-top: 9px solid transparent;
|
|
144
|
+
border-bottom: 9px solid transparent;
|
|
145
|
+
border-left: 10px solid rgba(255, 255, 255, 0.3);
|
|
146
|
+
border-right: none;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.terra-infowindow.terra-arrow-right::after {
|
|
150
|
+
right: -9px;
|
|
151
|
+
left: auto;
|
|
152
|
+
top: 50%;
|
|
153
|
+
bottom: auto;
|
|
154
|
+
transform: translateY(-50%);
|
|
155
|
+
border-top: 8px solid transparent;
|
|
156
|
+
border-bottom: 8px solid transparent;
|
|
157
|
+
border-left: 9px solid rgba(255, 255, 255, 0.8);
|
|
158
|
+
border-right: none;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* ==================== 头部区域 ==================== */
|
|
162
|
+
.terra-infowindow-header {
|
|
163
|
+
display: flex;
|
|
164
|
+
align-items: center;
|
|
165
|
+
padding: 0 18px;
|
|
166
|
+
height: 48px;
|
|
167
|
+
line-height: 48px;
|
|
168
|
+
font-size: 16px;
|
|
169
|
+
font-weight: 600;
|
|
170
|
+
white-space: nowrap;
|
|
171
|
+
padding-right: 50px;
|
|
172
|
+
position: relative;
|
|
173
|
+
color: #1d1d1f;
|
|
174
|
+
letter-spacing: -0.2px;
|
|
175
|
+
border-radius: 14px 14px 0 0;
|
|
176
|
+
/* 头部更明显的毛玻璃效果 */
|
|
177
|
+
background: rgba(255, 255, 255, 0.5);
|
|
178
|
+
backdrop-filter: blur(30px) saturate(200%);
|
|
179
|
+
-webkit-backdrop-filter: blur(30px) saturate(200%);
|
|
180
|
+
/* 底部细分割线 */
|
|
181
|
+
border-bottom: 0.5px solid rgba(0, 0, 0, 0.1);
|
|
182
|
+
box-shadow: inset 0 -0.5px 0 rgba(255, 255, 255, 0.6);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* 标题文本 */
|
|
186
|
+
.terra-infowindow-title {
|
|
187
|
+
flex: 1;
|
|
188
|
+
overflow: hidden;
|
|
189
|
+
text-overflow: ellipsis;
|
|
190
|
+
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);
|
|
191
|
+
font-weight: 600;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* 关闭按钮 - 圆形毛玻璃按钮 */
|
|
195
|
+
.terra-infowindow-close {
|
|
196
|
+
position: absolute;
|
|
197
|
+
top: 50%;
|
|
198
|
+
right: 10px;
|
|
199
|
+
transform: translateY(-50%);
|
|
200
|
+
width: 24px;
|
|
201
|
+
height: 24px;
|
|
202
|
+
padding: 0;
|
|
203
|
+
margin: 0;
|
|
204
|
+
font-size: 22px;
|
|
205
|
+
line-height: 24px;
|
|
206
|
+
text-align: center;
|
|
207
|
+
color: #666666;
|
|
208
|
+
cursor: pointer;
|
|
209
|
+
/* transition: all 0.2s ease; */
|
|
210
|
+
display: flex;
|
|
211
|
+
align-items: center;
|
|
212
|
+
justify-content: center;
|
|
213
|
+
z-index: 10;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
/* ==================== 内容区域 ==================== */
|
|
221
|
+
.terra-infowindow-content {
|
|
222
|
+
font-size: 14px;
|
|
223
|
+
padding: 18px;
|
|
224
|
+
min-width: 200px;
|
|
225
|
+
color: #1d1d1f;
|
|
226
|
+
line-height: 1.5;
|
|
227
|
+
background: transparent;
|
|
228
|
+
border-radius: 0 0 14px 14px;
|
|
229
|
+
/* 内容区域也有轻微毛玻璃效果 */
|
|
230
|
+
backdrop-filter: blur(5px);
|
|
231
|
+
-webkit-backdrop-filter: blur(5px);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* 内容区域内的链接 */
|
|
235
|
+
.terra-infowindow-content a {
|
|
236
|
+
color: #0066cc;
|
|
237
|
+
text-decoration: none;
|
|
238
|
+
border-bottom: 1px solid rgba(0, 102, 204, 0.2);
|
|
239
|
+
/* transition: all 0.2s ease; */
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.terra-infowindow-content a:hover {
|
|
243
|
+
color: #0052a3;
|
|
244
|
+
border-bottom-color: #0052a3;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* ==================== 工具提示 ==================== */
|
|
248
|
+
.terra-tooltip {
|
|
249
|
+
display: block;
|
|
250
|
+
/* 强化的毛玻璃效果 */
|
|
251
|
+
background: rgba(255, 255, 255, 0.85);
|
|
252
|
+
backdrop-filter: blur(25px) saturate(180%);
|
|
253
|
+
-webkit-backdrop-filter: blur(25px) saturate(180%);
|
|
254
|
+
border: 1px solid rgba(255, 255, 255, 0.25);
|
|
255
|
+
border-radius: 10px;
|
|
256
|
+
padding: 0 16px;
|
|
257
|
+
height: 36px;
|
|
258
|
+
line-height: 36px;
|
|
259
|
+
font-size: 14px;
|
|
260
|
+
white-space: nowrap;
|
|
261
|
+
color: #1d1d1f;
|
|
262
|
+
/* 多层阴影增强立体感 */
|
|
263
|
+
box-shadow:
|
|
264
|
+
0 6px 30px rgba(0, 0, 0, 0.1),
|
|
265
|
+
0 0 0 0.5px rgba(255, 255, 255, 0.4) inset;
|
|
266
|
+
font-weight: 500;
|
|
267
|
+
letter-spacing: -0.1px;
|
|
268
|
+
/* 文字阴影让文字在毛玻璃上更清晰 */
|
|
269
|
+
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
|
|
270
|
+
z-index: 999;
|
|
271
|
+
position: relative;
|
|
272
|
+
overflow: visible;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* ==================== 深色模式 ==================== */
|
|
276
|
+
@media (prefers-color-scheme: dark) {
|
|
277
|
+
|
|
278
|
+
.terra-infowindow,
|
|
279
|
+
.terra-tooltip {
|
|
280
|
+
background: rgba(28, 28, 30, 0.8);
|
|
281
|
+
backdrop-filter: blur(30px) saturate(180%);
|
|
282
|
+
-webkit-backdrop-filter: blur(30px) saturate(180%);
|
|
283
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
284
|
+
color: #ffffff;
|
|
285
|
+
box-shadow:
|
|
286
|
+
0 8px 32px rgba(0, 0, 0, 0.3),
|
|
287
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* InfoWindow 三角 */
|
|
291
|
+
.terra-infowindow::before {
|
|
292
|
+
border-top-color: rgba(255, 255, 255, 0.15);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.terra-infowindow::after {
|
|
296
|
+
border-top-color: rgba(28, 28, 30, 0.8);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* 顶部三角深色模式 */
|
|
300
|
+
.terra-infowindow.terra-arrow-top::before {
|
|
301
|
+
border-bottom-color: rgba(255, 255, 255, 0.15);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.terra-infowindow.terra-arrow-top::after {
|
|
305
|
+
border-bottom-color: rgba(28, 28, 30, 0.8);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* 左侧三角深色模式 */
|
|
309
|
+
.terra-infowindow.terra-arrow-left::before {
|
|
310
|
+
border-right-color: rgba(255, 255, 255, 0.15);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.terra-infowindow.terra-arrow-left::after {
|
|
314
|
+
border-right-color: rgba(28, 28, 30, 0.8);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* 右侧三角深色模式 */
|
|
318
|
+
.terra-infowindow.terra-arrow-right::before {
|
|
319
|
+
border-left-color: rgba(255, 255, 255, 0.15);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.terra-infowindow.terra-arrow-right::after {
|
|
323
|
+
border-left-color: rgba(28, 28, 30, 0.8);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/* 头部区域 */
|
|
327
|
+
.terra-infowindow-header {
|
|
328
|
+
background: rgba(44, 44, 46, 0.7);
|
|
329
|
+
color: rgba(255, 255, 255, 0.95);
|
|
330
|
+
border-bottom: 0.5px solid rgba(255, 255, 255, 0.1);
|
|
331
|
+
box-shadow: inset 0 -0.5px 0 rgba(255, 255, 255, 0.1);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.terra-infowindow-title {
|
|
335
|
+
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/* 关闭按钮 */
|
|
339
|
+
.terra-infowindow-close {
|
|
340
|
+
background: rgba(118, 118, 128, 0.3);
|
|
341
|
+
border: 0.5px solid rgba(255, 255, 255, 0.1);
|
|
342
|
+
color: rgba(235, 235, 245, 0.6);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.terra-infowindow-close:hover {
|
|
346
|
+
background: rgba(118, 118, 128, 0.4);
|
|
347
|
+
color: rgba(235, 235, 245, 0.9);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/* 内容区域 */
|
|
351
|
+
.terra-infowindow-content {
|
|
352
|
+
color: rgba(235, 235, 245, 0.9);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.terra-infowindow-content a {
|
|
356
|
+
color: #5fa9ff;
|
|
357
|
+
border-bottom-color: rgba(95, 169, 255, 0.3);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.terra-infowindow-content a:hover {
|
|
361
|
+
color: #8bc1ff;
|
|
362
|
+
border-bottom-color: #8bc1ff;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/* 工具提示 */
|
|
366
|
+
.terra-tooltip {
|
|
367
|
+
background: rgba(28, 28, 30, 0.85);
|
|
368
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
369
|
+
color: rgba(255, 255, 255, 0.95);
|
|
370
|
+
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* 工具提示三角深色模式 */
|
|
374
|
+
.terra-tooltip::before {
|
|
375
|
+
border-top-color: rgba(255, 255, 255, 0.15);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
.terra-tooltip::after {
|
|
379
|
+
border-top-color: rgba(28, 28, 30, 0.85);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/* ==================== 鼠标悬停增强效果 ==================== */
|
|
384
|
+
.terra-infowindow:hover {
|
|
385
|
+
box-shadow:
|
|
386
|
+
0 12px 48px rgba(0, 0, 0, 0.15),
|
|
387
|
+
0 0 0 0.5px rgba(255, 255, 255, 0.4) inset;
|
|
388
|
+
transform: translateY(-1px);
|
|
389
|
+
/* transition: all 0.3s ease; */
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* 工具提示悬停效果 */
|
|
393
|
+
.terra-tooltip:hover {
|
|
394
|
+
box-shadow:
|
|
395
|
+
0 8px 40px rgba(0, 0, 0, 0.15),
|
|
396
|
+
0 0 0 0.5px rgba(255, 255, 255, 0.5) inset;
|
|
397
|
+
transform: translateY(-1px);
|
|
398
|
+
/* transition: all 0.3s ease; */
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/* ==================== 动画效果 ==================== */
|
|
402
|
+
/* @keyframes terra-fade-in {
|
|
403
|
+
from {
|
|
404
|
+
opacity: 0;
|
|
405
|
+
transform: translateY(10px) scale(0.95);
|
|
406
|
+
}
|
|
407
|
+
to {
|
|
408
|
+
opacity: 1;
|
|
409
|
+
transform: translateY(0) scale(1);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.terra-infowindow,
|
|
414
|
+
.terra-tooltip {
|
|
415
|
+
animation: terra-fade-in 0.3s ease-out;
|
|
416
|
+
} */
|
|
417
|
+
|
|
418
|
+
/* ==================== 响应式设计 ==================== */
|
|
419
|
+
@media (max-width: 768px) {
|
|
420
|
+
.terra-infowindow {
|
|
421
|
+
min-width: 180px;
|
|
422
|
+
max-width: 280px;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.terra-infowindow-header {
|
|
426
|
+
height: 44px;
|
|
427
|
+
line-height: 44px;
|
|
428
|
+
font-size: 15px;
|
|
429
|
+
padding: 0 16px;
|
|
430
|
+
padding-right: 44px;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.terra-infowindow-content {
|
|
434
|
+
padding: 16px;
|
|
435
|
+
font-size: 13px;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.terra-tooltip {
|
|
439
|
+
font-size: 13px;
|
|
440
|
+
height: 32px;
|
|
441
|
+
line-height: 32px;
|
|
442
|
+
padding: 0 14px;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/* 打印样式 */
|
|
447
|
+
@media print {
|
|
448
|
+
|
|
449
|
+
.terra-infowindow,
|
|
450
|
+
.terra-tooltip {
|
|
451
|
+
background: white;
|
|
452
|
+
border: 1px solid #ddd;
|
|
453
|
+
box-shadow: none;
|
|
454
|
+
backdrop-filter: none;
|
|
455
|
+
-webkit-backdrop-filter: none;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.terra-infowindow::before,
|
|
459
|
+
.terra-infowindow::after,
|
|
460
|
+
.terra-tooltip::before,
|
|
461
|
+
.terra-tooltip::after {
|
|
462
|
+
display: none;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
/* 使用纯色箭头替代毛玻璃箭头 */
|
|
468
|
+
.terra-infowindow::before {
|
|
469
|
+
content: "";
|
|
470
|
+
position: absolute;
|
|
471
|
+
bottom: -10px;
|
|
472
|
+
left: 50%;
|
|
473
|
+
transform: translateX(-50%);
|
|
474
|
+
width: 0;
|
|
475
|
+
height: 0;
|
|
476
|
+
border-left: 10px solid transparent;
|
|
477
|
+
border-right: 10px solid transparent;
|
|
478
|
+
border-top: 10px solid rgba(255, 255, 255, 0.9);
|
|
479
|
+
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
|
|
480
|
+
z-index: 1;
|
|
481
|
+
/* 这里原来有毛玻璃,会导致出现一个矩形模糊块 */
|
|
482
|
+
backdrop-filter: none;
|
|
483
|
+
-webkit-backdrop-filter: none;
|
|
484
|
+
pointer-events: none;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.terra-infowindow::after {
|
|
488
|
+
content: "";
|
|
489
|
+
position: absolute;
|
|
490
|
+
bottom: -11px;
|
|
491
|
+
left: 50%;
|
|
492
|
+
transform: translateX(-50%);
|
|
493
|
+
width: 0;
|
|
494
|
+
height: 0;
|
|
495
|
+
border-left: 11px solid transparent;
|
|
496
|
+
border-right: 11px solid transparent;
|
|
497
|
+
/* 保持完全透明,只起占位,不再画底色 */
|
|
498
|
+
border-top: 11px solid transparent;
|
|
499
|
+
z-index: 0;
|
|
500
|
+
pointer-events: none;
|
|
501
|
+
}
|