roxy-cobewebgl 1.0.0 → 1.1.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 +96 -0
- package/package.json +32 -2
- package/react.d.ts +27 -0
- package/src/react/RoxyCobewebgl.jsx +157 -0
- package/src/react-entry.js +4 -0
- package/src/vue/RoxyCobewebgl.vue +151 -0
- package/src/vue-entry.js +5 -0
- package/vue.d.ts +20 -0
package/README.md
CHANGED
|
@@ -37,6 +37,100 @@ pnpm dev
|
|
|
37
37
|
|
|
38
38
|
浏览器将打开 [examples/playground/index.html](examples/playground/index.html):本地直连 `src/` 源码,带参数面板与示例弧线(**不**打进 npm 包)。
|
|
39
39
|
|
|
40
|
+
## Vue 3 组件
|
|
41
|
+
|
|
42
|
+
依赖 **Vue ^3.3**,构建工具需正确处理 `.vue`(如 Vite + `@vitejs/plugin-vue`)。
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pnpm add roxy-cobewebgl vue
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```vue
|
|
49
|
+
<script setup>
|
|
50
|
+
import RoxyCobewebgl from 'roxy-cobewebgl/vue';
|
|
51
|
+
|
|
52
|
+
const arcs = [
|
|
53
|
+
{ startLat: 39.9, startLng: 116.4, endLat: 35.6, endLng: 139.6, color: '#ff6633' },
|
|
54
|
+
];
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<template>
|
|
58
|
+
<div style="width: 100%; height: 400px">
|
|
59
|
+
<RoxyCobewebgl
|
|
60
|
+
:arcs="arcs"
|
|
61
|
+
:dots="1800"
|
|
62
|
+
:globe-radius="0.55"
|
|
63
|
+
@error="(e) => console.error(e)"
|
|
64
|
+
@ready="() => {}"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
</template>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- **Props**:与 `createGlobe` 的 `CreateGlobeOptions` 一致,**无** `onError`;错误用 **`@error`**。
|
|
71
|
+
- **`@ready`**:参数为 `GlobeInstance | null`(与 `createGlobe` 返回值相同语义)。
|
|
72
|
+
- **`ref` 暴露**:`setState`、`resize`、`destroy`、`getGlobe()`。
|
|
73
|
+
- 修改 **`map` / `mapUrl` / `arcs` / `preferWorker` / `debugShowTexture`** 会销毁并重建地球;其余视觉参数走 `setState`。
|
|
74
|
+
|
|
75
|
+
示例项目(通过 `file:../..` 依赖本地包,可对照集成方式):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pnpm install
|
|
79
|
+
pnpm dev:vue
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
或进入 [examples/vue-demo](examples/vue-demo) 执行 `pnpm install` 与 `pnpm dev`(默认端口 `5174`)。
|
|
83
|
+
|
|
84
|
+
## React 18+ 组件
|
|
85
|
+
|
|
86
|
+
依赖 **React / React-DOM ^18 或 ^19**,需能解析 **JSX** 与 `.jsx`(如 Vite + `@vitejs/plugin-react`)。
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pnpm add roxy-cobewebgl react react-dom
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
```jsx
|
|
93
|
+
import { useMemo } from 'react';
|
|
94
|
+
import RoxyCobewebgl from 'roxy-cobewebgl/react';
|
|
95
|
+
|
|
96
|
+
export function GlobeCard() {
|
|
97
|
+
const arcs = useMemo(
|
|
98
|
+
() => [
|
|
99
|
+
{ startLat: 39.9, startLng: 116.4, endLat: 35.6, endLng: 139.6, color: '#ff6633' },
|
|
100
|
+
],
|
|
101
|
+
[]
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<div style={{ width: '100%', height: 400 }}>
|
|
106
|
+
<RoxyCobewebgl
|
|
107
|
+
arcs={arcs}
|
|
108
|
+
dots={1800}
|
|
109
|
+
globeRadius={0.55}
|
|
110
|
+
onError={(e) => console.error(e)}
|
|
111
|
+
onReady={() => {}}
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
另支持 **`import { RoxyCobewebgl } from 'roxy-cobewebgl/react'`**。可传 **`className` / `style`** 到内部 `<canvas>`。
|
|
119
|
+
|
|
120
|
+
- **Props**:与 `CreateGlobeOptions` 一致,并增加 **`onReady`**(`onError` 仍与底层 API 相同)。
|
|
121
|
+
- **`ref`**:`setState`、`resize`、`destroy`、`getGlobe()`。
|
|
122
|
+
- **`map` / `mapUrl` / `arcs` / `preferWorker` / `debugShowTexture`** 变化会整实例重建;其余走 `setState`。
|
|
123
|
+
- **`onError` / `onReady`** 通过 ref 保持最新,避免因父组件重渲染导致整球重建。
|
|
124
|
+
|
|
125
|
+
示例:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
pnpm install
|
|
129
|
+
pnpm dev:react
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
或 [examples/react-demo](examples/react-demo)(默认端口 `5175`)。
|
|
133
|
+
|
|
40
134
|
## 地图数据
|
|
41
135
|
|
|
42
136
|
| 文件 | 说明 |
|
|
@@ -119,6 +213,8 @@ pnpm run build:globe
|
|
|
119
213
|
## 子路径导出(package exports)
|
|
120
214
|
|
|
121
215
|
- `roxy-cobewebgl` — 主入口
|
|
216
|
+
- `roxy-cobewebgl/vue` — Vue 3 封装组件 `RoxyCobewebgl`
|
|
217
|
+
- `roxy-cobewebgl/react` — React 封装组件 `RoxyCobewebgl`
|
|
122
218
|
- `roxy-cobewebgl/globe.worker.js` — Worker 源码(多数场景无需直接 import)
|
|
123
219
|
- `roxy-cobewebgl/globe.min.json` / `roxy-cobewebgl/globe.json` — 地图文件
|
|
124
220
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roxy-cobewebgl",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Cobe-style dotted globe with WebGL (ESM): OffscreenCanvas worker or main-thread fallback",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -13,17 +13,47 @@
|
|
|
13
13
|
},
|
|
14
14
|
"./globe.worker.js": "./src/globe.worker.js",
|
|
15
15
|
"./globe.json": "./globe.json",
|
|
16
|
-
"./globe.min.json": "./globe.min.json"
|
|
16
|
+
"./globe.min.json": "./globe.min.json",
|
|
17
|
+
"./vue": {
|
|
18
|
+
"types": "./vue.d.ts",
|
|
19
|
+
"import": "./src/vue-entry.js",
|
|
20
|
+
"default": "./src/vue-entry.js"
|
|
21
|
+
},
|
|
22
|
+
"./react": {
|
|
23
|
+
"types": "./react.d.ts",
|
|
24
|
+
"import": "./src/react-entry.js",
|
|
25
|
+
"default": "./src/react-entry.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"vue": "^3.3.0",
|
|
30
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
31
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependenciesMeta": {
|
|
34
|
+
"vue": {
|
|
35
|
+
"optional": true
|
|
36
|
+
},
|
|
37
|
+
"react": {
|
|
38
|
+
"optional": true
|
|
39
|
+
},
|
|
40
|
+
"react-dom": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
17
43
|
},
|
|
18
44
|
"files": [
|
|
19
45
|
"src",
|
|
20
46
|
"globe.json",
|
|
21
47
|
"globe.min.json",
|
|
22
48
|
"index.d.ts",
|
|
49
|
+
"vue.d.ts",
|
|
50
|
+
"react.d.ts",
|
|
23
51
|
"README.md"
|
|
24
52
|
],
|
|
25
53
|
"scripts": {
|
|
26
54
|
"dev": "vite",
|
|
55
|
+
"dev:vue": "pnpm --dir examples/vue-demo dev",
|
|
56
|
+
"dev:react": "pnpm --dir examples/react-demo dev",
|
|
27
57
|
"build:globe": "node scripts/slim-globe.mjs"
|
|
28
58
|
},
|
|
29
59
|
"keywords": [
|
package/react.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ForwardRefExoticComponent,
|
|
3
|
+
RefAttributes,
|
|
4
|
+
CSSProperties,
|
|
5
|
+
} from 'react';
|
|
6
|
+
import type { CreateGlobeOptions, GlobeInstance } from './index';
|
|
7
|
+
|
|
8
|
+
export type RoxyCobewebglProps = Partial<CreateGlobeOptions> & {
|
|
9
|
+
/** 地球实例创建完成(与 `createGlobe` 返回值相同语义) */
|
|
10
|
+
onReady?: (instance: GlobeInstance | null) => void;
|
|
11
|
+
className?: string;
|
|
12
|
+
style?: CSSProperties;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type RoxyCobewebglRef = {
|
|
16
|
+
setState: GlobeInstance['setState'];
|
|
17
|
+
resize: GlobeInstance['resize'];
|
|
18
|
+
destroy: GlobeInstance['destroy'];
|
|
19
|
+
getGlobe: () => GlobeInstance | null;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
declare const RoxyCobewebgl: ForwardRefExoticComponent<
|
|
23
|
+
RoxyCobewebglProps & RefAttributes<RoxyCobewebglRef>
|
|
24
|
+
>;
|
|
25
|
+
|
|
26
|
+
export { RoxyCobewebgl };
|
|
27
|
+
export default RoxyCobewebgl;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useImperativeHandle,
|
|
4
|
+
useRef,
|
|
5
|
+
useEffect,
|
|
6
|
+
} from 'react';
|
|
7
|
+
import { createGlobe } from '../index.js';
|
|
8
|
+
|
|
9
|
+
const SET_STATE_KEYS = [
|
|
10
|
+
'phi', 'theta', 'baseColor', 'glowColor', 'dotColor', 'arcColor',
|
|
11
|
+
'dots', 'dotSize', 'globeRadius', 'glowOn', 'debug', 'opacity',
|
|
12
|
+
'autoRotate', 'rotationSpeed',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
function pickGlobeInitProps(props) {
|
|
16
|
+
const { onReady: _r, onError: _e, ...globe } = props;
|
|
17
|
+
return Object.fromEntries(
|
|
18
|
+
Object.entries(globe).filter(([, v]) => v !== undefined)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function pickSetStatePatch(props) {
|
|
23
|
+
const patch = {};
|
|
24
|
+
for (const k of SET_STATE_KEYS) {
|
|
25
|
+
if (props[k] !== undefined) patch[k] = props[k];
|
|
26
|
+
}
|
|
27
|
+
return patch;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* React 封装:props 与 `createGlobe` 一致,另可传 `onReady(instance)`、`onError(err)`。
|
|
32
|
+
* ref:`setState`、`resize`、`destroy`、`getGlobe`
|
|
33
|
+
*/
|
|
34
|
+
export const RoxyCobewebgl = forwardRef(function RoxyCobewebgl(props, ref) {
|
|
35
|
+
const {
|
|
36
|
+
onReady,
|
|
37
|
+
onError,
|
|
38
|
+
preferWorker = true,
|
|
39
|
+
arcs = [],
|
|
40
|
+
debugShowTexture = false,
|
|
41
|
+
className,
|
|
42
|
+
style,
|
|
43
|
+
...globeRest
|
|
44
|
+
} = props;
|
|
45
|
+
|
|
46
|
+
const fullProps = {
|
|
47
|
+
preferWorker,
|
|
48
|
+
arcs,
|
|
49
|
+
debugShowTexture,
|
|
50
|
+
...globeRest,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const onErrorRef = useRef(onError);
|
|
54
|
+
const onReadyRef = useRef(onReady);
|
|
55
|
+
onErrorRef.current = onError;
|
|
56
|
+
onReadyRef.current = onReady;
|
|
57
|
+
|
|
58
|
+
const canvasRef = useRef(null);
|
|
59
|
+
const globeRef = useRef(null);
|
|
60
|
+
const readyRef = useRef(false);
|
|
61
|
+
const mountSeqRef = useRef(0);
|
|
62
|
+
|
|
63
|
+
useImperativeHandle(ref, () => ({
|
|
64
|
+
setState: (partial) => globeRef.current?.setState(partial),
|
|
65
|
+
resize: () => globeRef.current?.resize(),
|
|
66
|
+
destroy: () => {
|
|
67
|
+
globeRef.current?.destroy();
|
|
68
|
+
globeRef.current = null;
|
|
69
|
+
readyRef.current = false;
|
|
70
|
+
},
|
|
71
|
+
getGlobe: () => globeRef.current,
|
|
72
|
+
}), []);
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
const canvas = canvasRef.current;
|
|
76
|
+
if (!canvas) return undefined;
|
|
77
|
+
|
|
78
|
+
const id = ++mountSeqRef.current;
|
|
79
|
+
readyRef.current = false;
|
|
80
|
+
globeRef.current?.destroy();
|
|
81
|
+
globeRef.current = null;
|
|
82
|
+
|
|
83
|
+
let cancelled = false;
|
|
84
|
+
|
|
85
|
+
(async () => {
|
|
86
|
+
const instance = await createGlobe(canvas, {
|
|
87
|
+
...pickGlobeInitProps(fullProps),
|
|
88
|
+
onError: (e) => onErrorRef.current?.(e),
|
|
89
|
+
});
|
|
90
|
+
if (cancelled || id !== mountSeqRef.current) {
|
|
91
|
+
instance?.destroy();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
globeRef.current = instance;
|
|
95
|
+
readyRef.current = true;
|
|
96
|
+
onReadyRef.current?.(instance);
|
|
97
|
+
})();
|
|
98
|
+
|
|
99
|
+
return () => {
|
|
100
|
+
cancelled = true;
|
|
101
|
+
mountSeqRef.current += 1;
|
|
102
|
+
readyRef.current = false;
|
|
103
|
+
globeRef.current?.destroy();
|
|
104
|
+
globeRef.current = null;
|
|
105
|
+
};
|
|
106
|
+
}, [
|
|
107
|
+
fullProps.map,
|
|
108
|
+
fullProps.mapUrl,
|
|
109
|
+
fullProps.arcs,
|
|
110
|
+
fullProps.preferWorker,
|
|
111
|
+
fullProps.debugShowTexture,
|
|
112
|
+
]);
|
|
113
|
+
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (!globeRef.current || !readyRef.current) return;
|
|
116
|
+
const patch = pickSetStatePatch(fullProps);
|
|
117
|
+
if (Object.keys(patch).length) globeRef.current.setState(patch);
|
|
118
|
+
}, [
|
|
119
|
+
fullProps.phi,
|
|
120
|
+
fullProps.theta,
|
|
121
|
+
fullProps.baseColor,
|
|
122
|
+
fullProps.glowColor,
|
|
123
|
+
fullProps.dotColor,
|
|
124
|
+
fullProps.arcColor,
|
|
125
|
+
fullProps.dots,
|
|
126
|
+
fullProps.dotSize,
|
|
127
|
+
fullProps.globeRadius,
|
|
128
|
+
fullProps.glowOn,
|
|
129
|
+
fullProps.debug,
|
|
130
|
+
fullProps.opacity,
|
|
131
|
+
fullProps.autoRotate,
|
|
132
|
+
fullProps.rotationSpeed,
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
const canvasClass =
|
|
136
|
+
className != null && className !== ''
|
|
137
|
+
? `roxy-cobewebgl-canvas ${className}`
|
|
138
|
+
: 'roxy-cobewebgl-canvas';
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<canvas
|
|
142
|
+
ref={canvasRef}
|
|
143
|
+
className={canvasClass}
|
|
144
|
+
style={{
|
|
145
|
+
display: 'block',
|
|
146
|
+
width: '100%',
|
|
147
|
+
height: '100%',
|
|
148
|
+
verticalAlign: 'middle',
|
|
149
|
+
...style,
|
|
150
|
+
}}
|
|
151
|
+
/>
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
RoxyCobewebgl.displayName = 'RoxyCobewebgl';
|
|
156
|
+
|
|
157
|
+
export default RoxyCobewebgl;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<canvas
|
|
3
|
+
ref="canvasRef"
|
|
4
|
+
class="roxy-cobewebgl-canvas"
|
|
5
|
+
/>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup>
|
|
9
|
+
import { ref, watch, onMounted, onBeforeUnmount, shallowRef } from 'vue';
|
|
10
|
+
import { createGlobe } from '../index.js';
|
|
11
|
+
|
|
12
|
+
const SET_STATE_KEYS = [
|
|
13
|
+
'phi', 'theta', 'baseColor', 'glowColor', 'dotColor', 'arcColor',
|
|
14
|
+
'dots', 'dotSize', 'globeRadius', 'glowOn', 'debug', 'opacity',
|
|
15
|
+
'autoRotate', 'rotationSpeed',
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const RECREATE_KEYS = ['map', 'mapUrl', 'arcs', 'preferWorker', 'debugShowTexture'];
|
|
19
|
+
|
|
20
|
+
const props = defineProps({
|
|
21
|
+
map: { type: Object, default: undefined },
|
|
22
|
+
mapUrl: { type: [String, Object], default: undefined },
|
|
23
|
+
preferWorker: { type: Boolean, default: true },
|
|
24
|
+
arcs: { type: Array, default: () => [] },
|
|
25
|
+
debugShowTexture: { type: Boolean, default: false },
|
|
26
|
+
phi: { type: Number, default: undefined },
|
|
27
|
+
theta: { type: Number, default: undefined },
|
|
28
|
+
baseColor: { type: Array, default: undefined },
|
|
29
|
+
glowColor: { type: Array, default: undefined },
|
|
30
|
+
dotColor: { type: Array, default: undefined },
|
|
31
|
+
arcColor: { type: Array, default: undefined },
|
|
32
|
+
dots: { type: Number, default: undefined },
|
|
33
|
+
dotSize: { type: Number, default: undefined },
|
|
34
|
+
globeRadius: { type: Number, default: undefined },
|
|
35
|
+
glowOn: { type: Number, default: undefined },
|
|
36
|
+
debug: { type: Number, default: undefined },
|
|
37
|
+
opacity: { type: Number, default: undefined },
|
|
38
|
+
autoRotate: { type: Boolean, default: undefined },
|
|
39
|
+
rotationSpeed: { type: Number, default: undefined },
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const emit = defineEmits(['error', 'ready']);
|
|
43
|
+
|
|
44
|
+
const canvasRef = ref(null);
|
|
45
|
+
const globeRef = shallowRef(null);
|
|
46
|
+
const ready = ref(false);
|
|
47
|
+
let mountSeq = 0;
|
|
48
|
+
|
|
49
|
+
function toCreateOptions() {
|
|
50
|
+
const o = {
|
|
51
|
+
map: props.map,
|
|
52
|
+
mapUrl: props.mapUrl,
|
|
53
|
+
preferWorker: props.preferWorker,
|
|
54
|
+
arcs: props.arcs,
|
|
55
|
+
debugShowTexture: props.debugShowTexture,
|
|
56
|
+
onError: (e) => emit('error', e),
|
|
57
|
+
phi: props.phi,
|
|
58
|
+
theta: props.theta,
|
|
59
|
+
baseColor: props.baseColor,
|
|
60
|
+
glowColor: props.glowColor,
|
|
61
|
+
dotColor: props.dotColor,
|
|
62
|
+
arcColor: props.arcColor,
|
|
63
|
+
dots: props.dots,
|
|
64
|
+
dotSize: props.dotSize,
|
|
65
|
+
globeRadius: props.globeRadius,
|
|
66
|
+
glowOn: props.glowOn,
|
|
67
|
+
debug: props.debug,
|
|
68
|
+
opacity: props.opacity,
|
|
69
|
+
autoRotate: props.autoRotate,
|
|
70
|
+
rotationSpeed: props.rotationSpeed,
|
|
71
|
+
};
|
|
72
|
+
return Object.fromEntries(
|
|
73
|
+
Object.entries(o).filter(([, v]) => v !== undefined)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function pickSetStatePatch() {
|
|
78
|
+
const patch = {};
|
|
79
|
+
for (const k of SET_STATE_KEYS) {
|
|
80
|
+
if (props[k] !== undefined) patch[k] = props[k];
|
|
81
|
+
}
|
|
82
|
+
return patch;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function mountGlobe() {
|
|
86
|
+
const canvas = canvasRef.value;
|
|
87
|
+
if (!canvas) return null;
|
|
88
|
+
const id = ++mountSeq;
|
|
89
|
+
ready.value = false;
|
|
90
|
+
globeRef.value?.destroy();
|
|
91
|
+
globeRef.value = null;
|
|
92
|
+
const instance = await createGlobe(canvas, toCreateOptions());
|
|
93
|
+
if (id !== mountSeq) {
|
|
94
|
+
instance?.destroy();
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
globeRef.value = instance;
|
|
98
|
+
ready.value = true;
|
|
99
|
+
emit('ready', instance);
|
|
100
|
+
return instance;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
onMounted(() => {
|
|
104
|
+
mountGlobe();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
onBeforeUnmount(() => {
|
|
108
|
+
mountSeq++;
|
|
109
|
+
ready.value = false;
|
|
110
|
+
globeRef.value?.destroy();
|
|
111
|
+
globeRef.value = null;
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
watch(
|
|
115
|
+
() => RECREATE_KEYS.map((k) => props[k]),
|
|
116
|
+
async () => {
|
|
117
|
+
if (!canvasRef.value) return;
|
|
118
|
+
await mountGlobe();
|
|
119
|
+
},
|
|
120
|
+
{ deep: true }
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
watch(
|
|
124
|
+
() => pickSetStatePatch(),
|
|
125
|
+
(patch) => {
|
|
126
|
+
if (!globeRef.value || !ready.value) return;
|
|
127
|
+
if (Object.keys(patch).length) globeRef.value.setState(patch);
|
|
128
|
+
},
|
|
129
|
+
{ deep: true }
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
defineExpose({
|
|
133
|
+
setState: (partial) => globeRef.value?.setState(partial),
|
|
134
|
+
resize: () => globeRef.value?.resize(),
|
|
135
|
+
destroy: () => {
|
|
136
|
+
globeRef.value?.destroy();
|
|
137
|
+
globeRef.value = null;
|
|
138
|
+
ready.value = false;
|
|
139
|
+
},
|
|
140
|
+
getGlobe: () => globeRef.value,
|
|
141
|
+
});
|
|
142
|
+
</script>
|
|
143
|
+
|
|
144
|
+
<style scoped>
|
|
145
|
+
.roxy-cobewebgl-canvas {
|
|
146
|
+
display: block;
|
|
147
|
+
width: 100%;
|
|
148
|
+
height: 100%;
|
|
149
|
+
vertical-align: middle;
|
|
150
|
+
}
|
|
151
|
+
</style>
|
package/src/vue-entry.js
ADDED
package/vue.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DefineComponent } from 'vue';
|
|
2
|
+
import type { CreateGlobeOptions, GlobeInstance } from './index';
|
|
3
|
+
|
|
4
|
+
/** 与 CreateGlobeOptions 一致,无 onError(请用 @error 事件) */
|
|
5
|
+
export type RoxyCobewebglProps = Partial<Omit<CreateGlobeOptions, 'onError'>>;
|
|
6
|
+
|
|
7
|
+
export type RoxyCobewebglExpose = {
|
|
8
|
+
setState: GlobeInstance['setState'];
|
|
9
|
+
resize: GlobeInstance['resize'];
|
|
10
|
+
destroy: GlobeInstance['destroy'];
|
|
11
|
+
getGlobe: () => GlobeInstance | null;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
declare const RoxyCobewebgl: DefineComponent<
|
|
15
|
+
RoxyCobewebglProps,
|
|
16
|
+
RoxyCobewebglExpose
|
|
17
|
+
>;
|
|
18
|
+
|
|
19
|
+
export { RoxyCobewebgl };
|
|
20
|
+
export default RoxyCobewebgl;
|