@trapar-waves/react-three-maplibre 1.2.0 → 2.0.0
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/README.md +49 -88
- package/assets/readme/headers/contributing.svg +15 -0
- package/assets/readme/headers/features.svg +15 -0
- package/assets/readme/headers/getting-started.svg +15 -0
- package/assets/readme/headers/license.svg +15 -0
- package/assets/readme/headers/project-structure.svg +15 -0
- package/assets/readme/headers/tech-stack.svg +15 -0
- package/assets/readme/headers/usage.svg +15 -0
- package/assets/readme/hero.svg +67 -0
- package/eslint.config.js +6 -10
- package/lint-staged.config.js +1 -1
- package/package.json +29 -29
- package/pnpm-workspace.yaml +5 -0
- package/readme/README-CN.md +63 -91
- package/readme/README-JP.md +64 -92
- package/readme/README-RU.md +47 -75
- package/rsbuild.config.ts +11 -13
- package/src/{App.tsx → app.tsx} +66 -58
- package/src/index.tsx +4 -4
- /package/src/{env.d.ts → environment.d.ts} +0 -0
package/src/{App.tsx → app.tsx}
RENAMED
|
@@ -9,13 +9,14 @@ import Map from "react-map-gl/maplibre";
|
|
|
9
9
|
import { Canvas } from "react-three-map/maplibre";
|
|
10
10
|
import { LineMaterial, LineSegments2, LineSegmentsGeometry } from "three-stdlib";
|
|
11
11
|
|
|
12
|
-
extend
|
|
12
|
+
// eslint-disable-next-line unicorn/no-top-level-side-effects -- R3F extend must run before render
|
|
13
|
+
extend({ LineMaterial, LineSegments2, LineSegmentsGeometry });
|
|
13
14
|
|
|
14
15
|
declare module "@react-three/fiber" {
|
|
15
16
|
interface ThreeElements {
|
|
16
|
-
|
|
17
|
-
lineMaterial: ThreeElements["material"] & Partial<LineMaterial>;
|
|
17
|
+
lineMaterial: Partial<LineMaterial> & ThreeElements["material"];
|
|
18
18
|
lineSegments2: ThreeElements["object3D"] & { children?: ReactNode };
|
|
19
|
+
lineSegmentsGeometry: ThreeElements["bufferGeometry"];
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -24,7 +25,9 @@ const latLon = {
|
|
|
24
25
|
longitude: 121.417463,
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Carto 托管的 MapLibre GL 矢量底图,无需 API Key(使用请遵守 https://carto.com/basemaps/ 条款)。
|
|
30
|
+
*/
|
|
28
31
|
const MAP_STYLE_URL = "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json";
|
|
29
32
|
|
|
30
33
|
function publicAssetUrl(filename: string): string {
|
|
@@ -37,23 +40,23 @@ const HOMEPAGE = "https://github.com/Trapar-waves/react-three-maplibre";
|
|
|
37
40
|
const LOGOS_SET_URL = "https://icon-sets.iconify.design/logos/";
|
|
38
41
|
|
|
39
42
|
interface TechPill {
|
|
43
|
+
iconClass: string;
|
|
40
44
|
id: string;
|
|
41
45
|
label: string;
|
|
42
|
-
iconClass: string;
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
const techStack: TechPill[] = [
|
|
46
|
-
{
|
|
47
|
-
{
|
|
48
|
-
{ id: "tailwind", label: "Tailwind 4"
|
|
49
|
-
{
|
|
50
|
-
{ id: "maplibre", label: "MapLibre · react-map-gl"
|
|
51
|
-
{ id: "l7", label: "AntV L7"
|
|
52
|
-
{ id: "r3f", label: "R3F · drei · three-stdlib"
|
|
53
|
-
{ id: "rtmap", label: "react-three-map"
|
|
54
|
-
{
|
|
55
|
-
{
|
|
56
|
-
{
|
|
49
|
+
{ iconClass: "icon-[logos--react]", id: "react", label: "React 19" },
|
|
50
|
+
{ iconClass: "icon-[logos--typescript-icon]", id: "ts", label: "TypeScript" },
|
|
51
|
+
{ iconClass: "icon-[logos--tailwindcss-icon]", id: "tailwind", label: "Tailwind 4" },
|
|
52
|
+
{ iconClass: "icon-[material-icon-theme--rstack]", id: "rsbuild", label: "Rsbuild" },
|
|
53
|
+
{ iconClass: "icon-[simple-icons--maplibre]", id: "maplibre", label: "MapLibre · react-map-gl" },
|
|
54
|
+
{ iconClass: "icon-[logos--markdown]", id: "l7", label: "AntV L7" },
|
|
55
|
+
{ iconClass: "icon-[logos--threejs]", id: "r3f", label: "R3F · drei · three-stdlib" },
|
|
56
|
+
{ iconClass: "icon-[logos--markdown]", id: "rtmap", label: "react-three-map" },
|
|
57
|
+
{ iconClass: "icon-[logos--eslint]", id: "eslint", label: "ESLint" },
|
|
58
|
+
{ iconClass: "icon-[logos--pnpm]", id: "pnpm", label: "pnpm" },
|
|
59
|
+
{ iconClass: "icon-[logos--github-icon]", id: "github", label: "GitHub Actions" },
|
|
57
60
|
];
|
|
58
61
|
|
|
59
62
|
const readmeFeatures: string[] = [
|
|
@@ -72,44 +75,49 @@ const readmeFeatures: string[] = [
|
|
|
72
75
|
const readmeTechNote = "演示使用 @react-three/drei 的 Stats;生产可按需移除。若需其他底图,可在 App.tsx 中替换 MAP_STYLE_URL 并自行处理鉴权。";
|
|
73
76
|
|
|
74
77
|
function App() {
|
|
75
|
-
const
|
|
76
|
-
const
|
|
78
|
+
const divReference = useRef<HTMLDivElement>(null!);
|
|
79
|
+
const mapReference = useRef<MapRef>(null!);
|
|
77
80
|
function initL7() {
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
map: new MapLibre({
|
|
82
|
-
mapInstance: mapRef.current.getMap(),
|
|
83
|
-
}),
|
|
84
|
-
});
|
|
85
|
-
scene.on("loaded", () => {
|
|
86
|
-
fetch(publicAssetUrl("BElVQFEFvpAKzddxFZxJ.txt"))
|
|
87
|
-
.then(res => (res.ok ? res.text() : Promise.reject(new Error(String(res.status)))))
|
|
88
|
-
.then((data) => {
|
|
89
|
-
const pointLayer = new PointLayer({
|
|
90
|
-
blend: "additive",
|
|
91
|
-
})
|
|
92
|
-
.source(data, {
|
|
93
|
-
parser: {
|
|
94
|
-
type: "csv",
|
|
95
|
-
y: "lat",
|
|
96
|
-
x: "lng",
|
|
97
|
-
},
|
|
98
|
-
})
|
|
99
|
-
.size(0.5)
|
|
100
|
-
.color("#080298");
|
|
81
|
+
if (!mapReference.current) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
101
84
|
|
|
102
|
-
|
|
85
|
+
const scene = new Scene({
|
|
86
|
+
id: "map",
|
|
87
|
+
map: new MapLibre({
|
|
88
|
+
mapInstance: mapReference.current.getMap(),
|
|
89
|
+
}),
|
|
90
|
+
});
|
|
91
|
+
scene.on("loaded", async () => {
|
|
92
|
+
try {
|
|
93
|
+
const response = await fetch(publicAssetUrl("BElVQFEFvpAKzddxFZxJ.txt"));
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const data = await response.text();
|
|
98
|
+
const pointLayer = new PointLayer({
|
|
99
|
+
blend: "additive",
|
|
100
|
+
})
|
|
101
|
+
.source(data, {
|
|
102
|
+
parser: {
|
|
103
|
+
type: "csv",
|
|
104
|
+
x: "lng",
|
|
105
|
+
y: "lat",
|
|
106
|
+
},
|
|
103
107
|
})
|
|
104
|
-
.
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
.size(0.5)
|
|
109
|
+
.color("#080298");
|
|
110
|
+
|
|
111
|
+
scene.addLayer(pointLayer);
|
|
112
|
+
}
|
|
113
|
+
catch {}
|
|
114
|
+
});
|
|
107
115
|
}
|
|
108
116
|
return (
|
|
109
|
-
<div className="h-screen w-screen relative overflow-hidden" ref={
|
|
117
|
+
<div className="h-screen w-screen relative overflow-hidden" ref={divReference}>
|
|
110
118
|
<aside
|
|
111
|
-
className="pointer-events-none absolute left-4 top-4 z-10 max-w-sm motion-safe:transition motion-safe:duration-200"
|
|
112
119
|
aria-label="模板说明"
|
|
120
|
+
className="pointer-events-none absolute left-4 top-4 z-10 max-w-sm motion-safe:transition motion-safe:duration-200"
|
|
113
121
|
>
|
|
114
122
|
<div
|
|
115
123
|
className="pointer-events-auto max-h-[min(70vh,560px)] overflow-y-auto overscroll-contain rounded-xl border border-white/15 bg-slate-950/80 p-4 text-sm text-slate-100 shadow-xl backdrop-blur-md"
|
|
@@ -123,10 +131,10 @@ function App() {
|
|
|
123
131
|
画布叠在 L7 之上。底图为 Carto 公开 GL 样式,无需地图服务 API Key。技术图标见
|
|
124
132
|
{" "}
|
|
125
133
|
<a
|
|
126
|
-
href={LOGOS_SET_URL}
|
|
127
134
|
className="font-medium text-sky-300 underline decoration-sky-700 underline-offset-2 hover:text-sky-200"
|
|
128
|
-
|
|
135
|
+
href={LOGOS_SET_URL}
|
|
129
136
|
rel="noreferrer"
|
|
137
|
+
target="_blank"
|
|
130
138
|
>
|
|
131
139
|
Iconify logos
|
|
132
140
|
</a>
|
|
@@ -138,10 +146,10 @@ function App() {
|
|
|
138
146
|
<div className="mt-2 flex flex-wrap gap-2">
|
|
139
147
|
{techStack.map(item => (
|
|
140
148
|
<span
|
|
141
|
-
key={item.id}
|
|
142
149
|
className="inline-flex items-center gap-1.5 rounded-lg border border-white/10 bg-slate-900/80 px-2 py-1 text-xs text-slate-200"
|
|
150
|
+
key={item.id}
|
|
143
151
|
>
|
|
144
|
-
<span className={`${item.iconClass} text-base text-sky-300`}
|
|
152
|
+
<span aria-hidden className={`${item.iconClass} text-base text-sky-300`} />
|
|
145
153
|
{item.label}
|
|
146
154
|
</span>
|
|
147
155
|
))}
|
|
@@ -160,15 +168,15 @@ function App() {
|
|
|
160
168
|
<p className="mt-3 text-xs leading-relaxed text-slate-500">
|
|
161
169
|
品牌图标来自
|
|
162
170
|
{" "}
|
|
163
|
-
<a
|
|
171
|
+
<a className="text-sky-400 underline hover:text-sky-300" href={LOGOS_SET_URL} rel="noreferrer" target="_blank">SVG Logos</a>
|
|
164
172
|
{" "}
|
|
165
173
|
(CC0)。
|
|
166
174
|
</p>
|
|
167
175
|
<a
|
|
168
|
-
href={HOMEPAGE}
|
|
169
176
|
className="mt-3 inline-flex min-h-11 w-full items-center justify-center rounded-lg bg-sky-500 px-4 py-2 text-sm font-semibold text-slate-950 hover:bg-sky-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
|
|
170
|
-
|
|
177
|
+
href={HOMEPAGE}
|
|
171
178
|
rel="noreferrer"
|
|
179
|
+
target="_blank"
|
|
172
180
|
>
|
|
173
181
|
查看仓库
|
|
174
182
|
</a>
|
|
@@ -176,20 +184,20 @@ function App() {
|
|
|
176
184
|
</aside>
|
|
177
185
|
<Map
|
|
178
186
|
id="map"
|
|
179
|
-
ref={mapRef}
|
|
180
187
|
initialViewState={{
|
|
181
188
|
...latLon,
|
|
182
|
-
zoom: 11,
|
|
183
189
|
pitch: 64.88,
|
|
190
|
+
zoom: 11,
|
|
184
191
|
}}
|
|
185
192
|
mapStyle={MAP_STYLE_URL}
|
|
186
193
|
onLoad={initL7}
|
|
194
|
+
ref={mapReference}
|
|
187
195
|
>
|
|
188
|
-
<Stats className="stats" parent={
|
|
196
|
+
<Stats className="stats" parent={divReference} />
|
|
189
197
|
|
|
190
198
|
<Canvas
|
|
191
|
-
overlay
|
|
192
199
|
id="trapar-r3f-overlay"
|
|
200
|
+
overlay
|
|
193
201
|
{...latLon}
|
|
194
202
|
>
|
|
195
203
|
<hemisphereLight
|
package/src/index.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import ReactDOM from "react-dom/client";
|
|
2
|
-
import App from "./
|
|
2
|
+
import App from "./app";
|
|
3
3
|
import "./global.css";
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
if (
|
|
7
|
-
const root = ReactDOM.createRoot(
|
|
5
|
+
const rootElement = document.querySelector("#root");
|
|
6
|
+
if (rootElement) {
|
|
7
|
+
const root = ReactDOM.createRoot(rootElement);
|
|
8
8
|
root.render(
|
|
9
9
|
<App />,
|
|
10
10
|
);
|
|
File without changes
|