roxy-cobewebgl
v1.1.3
Published
Cobe-style dotted globe with WebGL (ESM): OffscreenCanvas worker or main-thread fallback
Maintainers
Readme
roxy-cobewebgl
Cobe 风格的高性能点阵地球:纯 WebGL + GLSL,可选 OffscreenCanvas Worker 渲染(主线程只做交互),不支持时自动 主线程 WebGL 回退。以 ESM 发布,可在 Vite / Webpack 5+ 等打包器中使用。
画布背景:WebGL 使用带 alpha 的上下文(premultipliedAlpha: false),每帧以透明色清空缓冲,并用 SRC_ALPHA 混合绘制;球圆外(glowOn 为关时)为全透明,可透出下层。若仍看到暗边,多为外圈光晕,可把 glowOn 设为 0。<canvas> 建议配合 CSS background: transparent。
安装
npm install roxy-cobewebgl
# 或
pnpm add roxy-cobewebgl快速开始
<canvas id="globe" width="600" height="600" style="width:100%;max-width:800px;height:400px;"></canvas>
<script type="module">
import { createGlobe } from 'roxy-cobewebgl';
const canvas = document.getElementById('globe');
const instance = await createGlobe(canvas, {
// 不传 map / mapUrl 时默认加载包内精简地图 globe.min.json
arcs: [],
});
if (!instance) {
console.error('无法创建地球(WebGL 或地图加载失败)');
}
</script>本地调试示例:
pnpm install
pnpm dev浏览器将打开 examples/playground/index.html:本地直连 src/ 源码,带参数面板与示例弧线(不打进 npm 包)。
Vue 3 组件
依赖 Vue ^3.3,构建工具需正确处理 .vue(如 Vite + @vitejs/plugin-vue)。
pnpm add roxy-cobewebgl vue<script setup>
import RoxyCobewebgl from 'roxy-cobewebgl/vue';
const arcs = [
{ startLat: 39.9, startLng: 116.4, endLat: 35.6, endLng: 139.6, color: '#ff6633' },
];
</script>
<template>
<div style="width: 100%; height: 400px">
<RoxyCobewebgl
:arcs="arcs"
:dots="1800"
:globe-radius="0.55"
@error="(e) => console.error(e)"
@ready="() => {}"
/>
</div>
</template>- Props:与
createGlobe的CreateGlobeOptions一致,无onError;错误用@error。 @ready:参数为GlobeInstance | null(与createGlobe返回值相同语义)。ref暴露:setState、resize、destroy、getGlobe()。- 修改
map/mapUrl/arcs/preferWorker/debugShowTexture会销毁并重建地球;其余视觉参数走setState。
示例项目(通过 file:../.. 依赖本地包,可对照集成方式):
pnpm install
pnpm dev:vue或进入 examples/vue-demo 执行 pnpm install 与 pnpm dev(默认端口 5174)。
React 18+ 组件
依赖 React / React-DOM ^18 或 ^19,需能解析 JSX 与 .jsx(如 Vite + @vitejs/plugin-react)。
pnpm add roxy-cobewebgl react react-domimport { useMemo } from 'react';
import RoxyCobewebgl from 'roxy-cobewebgl/react';
export function GlobeCard() {
const arcs = useMemo(
() => [
{ startLat: 39.9, startLng: 116.4, endLat: 35.6, endLng: 139.6, color: '#ff6633' },
],
[]
);
return (
<div style={{ width: '100%', height: 400 }}>
<RoxyCobewebgl
arcs={arcs}
dots={1800}
globeRadius={0.55}
onError={(e) => console.error(e)}
onReady={() => {}}
/>
</div>
);
}另支持 import { RoxyCobewebgl } from 'roxy-cobewebgl/react'。可传 className / style 到内部 <canvas>。
- Props:与
CreateGlobeOptions一致,并增加onReady(onError仍与底层 API 相同)。 ref:setState、resize、destroy、getGlobe()。map/mapUrl/arcs/preferWorker/debugShowTexture变化会整实例重建;其余走setState。onError/onReady通过 ref 保持最新,避免因父组件重渲染导致整球重建。
示例:
pnpm install
pnpm dev:react或 examples/react-demo(默认端口 5175)。
地图数据
| 文件 | 说明 |
|------|------|
| globe.json | 完整国界 GeoJSON,体积大,精度高 |
| globe.min.json | 由脚本精简(仅几何、降精度、无 properties),默认使用 |
从 npm 引用资源 URL(在支持 import.meta.resolve 或打包器解析的环境下):
import { getDefaultMapMinUrl, getDefaultMapFullUrl } from 'roxy-cobewebgl';
const url = getDefaultMapMinUrl();
// 或完整版
const full = getDefaultMapFullUrl();也可把 JSON 放到自己的 CDN,通过 mapUrl 传入。
重新生成 globe.min.json(需先有根目录 globe.json):
pnpm run build:globe对应脚本为 scripts/slim-globe.mjs。
API
createGlobe(canvas, options?)
- canvas
HTMLCanvasElement:目标画布。Worker 模式下会transferControlToOffscreen(),主线程不要再对该 canvas 调用getContext。 - 返回
Promise<GlobeInstance | null>:主线程回退路径需异步加载地图;失败或拿不到 WebGL 时为null。
options 一览
| 字段 | 类型 | 默认 | 说明 |
|------|------|------|------|
| map | object | — | GeoJSON FeatureCollection,结构化克隆进 Worker |
| mapUrl | string \| URL | 包内 globe.min.json | 可 fetch 的地址;与 map 同时传时以 map 为准 |
| preferWorker | boolean | true | false 时强制主线程渲染(便于对照调试) |
| arcs | GlobeArc[] | [] | 大圆飞行弧线动画;空数组不创建弧线程序 |
| onError | (err: Error) => void | console.error | Worker / 网络 / WebGL 错误 |
| debugShowTexture | boolean | false | 仅回退模式:在页面固定角显示陆域纹理缩略图 |
外观与着色器 uniform(均可后续 setState):
| 字段 | 类型 | 默认 | 说明 |
|------|------|------|------|
| phi | number | 0.3 | 绕 Y 旋转(弧度),Worker 内会随 autoRotate 递增 |
| theta | number | 0.15 | 绕 X 倾斜 |
| dots | number | 800 | 斐波那契点数量 |
| dotSize | number | 0.008 | 点大小阈值 |
| globeRadius | number | 0.55 | 屏幕空间中球半径比例 |
| glowOn | number | 1 | 边缘发光开关,0/1 |
| opacity | number | 0.9 | 球体表面不透明度 |
| baseColor | [r,g,b] | 暗蓝 | 海洋 / 底色,0–1 |
| glowColor | [r,g,b] | 蓝 | 发光颜色 |
| dotColor | [r,g,b] | 亮青 | 陆地点颜色 |
| arcColor | [r,g,b] | 橙 | 弧线未指定 color 时的兜底 |
| debug | number | 0 | 0 正常;1 全点;2 UV;3 纹理诊断 |
| autoRotate | boolean | true | 是否每帧增加 phi |
| rotationSpeed | number | 0.003 | 每帧 phi 增量 |
弧线 GlobeArc:startLat, startLng, endLat, endLng(度),可选 color(如 #ff6633),可选 order(绘制顺序,越小越早启动)。
GlobeInstance
setState(partial):合并更新参数。- Worker 模式:仅把你通过
setState写过的键周期性发给 Worker;phi默认由 Worker 推进,除非你也对其setState,否则不会被主线程覆盖。 - 回退模式:内部为完整状态对象,行为与普通 React-less 状态合并一致。
- Worker 模式:仅把你通过
resize():按当前 CSS 尺寸与devicePixelRatio更新绘图缓冲;库已监听window.resize,一般不必调用。destroy():取消动画帧、移除监听、Worker.terminate()(若使用 Worker)。
辅助函数
getDefaultMapMinUrl():包内globe.min.json的绝对 URL(便于传给mapUrl或下载器)。getDefaultMapFullUrl():包内globe.json。
子路径导出(package exports)
roxy-cobewebgl— 主入口roxy-cobewebgl/vue— Vue 3 封装组件RoxyCobewebglroxy-cobewebgl/react— React 封装组件RoxyCobewebglroxy-cobewebgl/globe.worker.js— Worker 源码(多数场景无需直接 import)roxy-cobewebgl/globe.min.json/roxy-cobewebgl/globe.json— 地图文件
创建 Worker 时使用 new URL('./globe.worker.js', import.meta.url)(库内部已处理);自有打包配置需保留对 Worker 文件的解析。
打包与 SSR
- 须在客户端调用
createGlobe(依赖document、Worker、WebGL)。 - Vite / Webpack 5+ 对
new Worker(new URL(...), { type: 'module' })有较好支持;若遇路径问题,检查是否把node_modules/roxy-cobewebgl/src/globe.worker.js打进资源。
协议
ISC
