{"_id":"@bimangle/cesium-tool-tour","name":"@bimangle/cesium-tool-tour","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@bimangle/cesium-tool-tour","version":"1.0.0","description":"A Cesium plugin providing first-person scene tour navigation with keyboard, mouse and virtual joystick support.","main":"dist/cesium-tool-tour.js","module":"src/cesium-tool-tour.js","scripts":{"build":"rollup -c","prepare":"npm run build"},"keywords":["cesium","tour","roam","navigate","first-person","3dtiles","bimangle"],"author":{"name":"BimAngle"},"license":"MIT","publishConfig":{"access":"public"},"dependencies":{"@bimangle/cesium-ui":"file:../cesium-ui"},"peerDependencies":{"cesium":"^1.110.0"},"devDependencies":{"@rollup/plugin-commonjs":"^22.0.2","@rollup/plugin-node-resolve":"^13.3.0","rollup":"^2.79.2"},"_id":"@bimangle/cesium-tool-tour@1.0.0","_nodeVersion":"24.11.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-98RVtdFpZXKO0Z5Ax8I9IfTbHwRraOXW2ZbxdXots/hYZwl4qA6sLoF+y+fv3gTSNioctBE8kkBBA6au/W3Thw==","shasum":"9fa62a2e8f60eb66d87233ee218e46408840c2fb","tarball":"https://registry.npmjs.org/@bimangle/cesium-tool-tour/-/cesium-tool-tour-1.0.0.tgz","fileCount":5,"unpackedSize":129238,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEEfiAK9jLDBnPb3SqHCnZormY1+54sc1yUSnNM5PigXAiBKaQWpOOg6A7w+afQQQbKXiw1l33tZ8iKyK2jvETK0pw=="}]},"_npmUser":{"name":"bimangle.liu","email":"liuyongsheng@msn.com"},"directories":{},"maintainers":[{"name":"bimangle.liu","email":"liuyongsheng@msn.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cesium-tool-tour_1.0.0_1783772899881_0.4086553661126162"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-11T12:28:19.796Z","1.0.0":"2026-07-11T12:28:20.014Z","modified":"2026-07-11T12:28:20.184Z"},"maintainers":[{"name":"bimangle.liu","email":"liuyongsheng@msn.com"}],"description":"A Cesium plugin providing first-person scene tour navigation with keyboard, mouse and virtual joystick support.","keywords":["cesium","tour","roam","navigate","first-person","3dtiles","bimangle"],"author":{"name":"BimAngle"},"license":"MIT","readme":"# @bimangle/cesium-tool-tour\n\nA Cesium plugin providing first-person scene tour (漫游导航) navigation.  \n适用于 Cesium 三维场景的第一人称漫游导航插件。\n\nSupports keyboard + mouse (Pointer Lock) mode and a virtual joystick panel mode for touch devices.  \n支持键鼠模式（Pointer Lock）和触控友好的虚拟摇杆模式。\n\n---\n\n## Features / 功能特性\n\n- **Keyboard mode** — WASD + QE movement, mouse look via Pointer Lock  \n  键盘模式：WASD + QE 移动，鼠标通过 Pointer Lock 控制视角\n- **Virtual joystick mode** — on-screen WASDQE buttons + draggable joystick; works on touch devices without interfering with Cesium native gestures  \n  虚拟摇杆模式：屏幕按键 + 可拖拽摇杆，适合触控设备且不干扰 Cesium 原生操作\n- **Step distance** — 0.001 / 0.01 / 0.1 / **1.0** m per keypress (default 1.0 m)  \n  移动步距：0.001 / 0.01 / 0.1 / **1.0** m（默认 1.0 m）\n- **Hold-key acceleration** — continuous movement at 30× step distance/s after 300 ms hold  \n  按住加速：持续按住 300 ms 后以 30 倍步距/秒连续移动\n- **Mouse wheel** — scroll up to move forward, scroll down to move backward (5× step distance per notch)  \n  鼠标滚轮：向上滚前进，向下滚后退，每格 5 倍步距\n- **Double-click to advance** — double-click a scene object to fly halfway toward it; camera faces the target  \n  双击推进：双击场景中的目标点，镜头朝目标点平滑飞行到中点处\n- **Fly / Horizontal mode** — choose whether W/S follows camera pitch or stays on the horizontal plane  \n  飞行 / 水平模式：W/S 可沿相机方向或仅在水平面移动\n- **Bilingual UI** — Chinese (zh-*) or English based on `navigator.language`  \n  双语界面：根据 `navigator.language` 自动切换中文或英文\n- **Integrates with `cesium-tool-measure`** — automatically cancels active measurement when tour mode starts  \n  与测量插件协同：漫游激活时自动取消正在进行的测量\n\n---\n\n## Installation / 安装\n\n### NPM\n\n```bash\nnpm install @bimangle/cesium-tool-tour\n```\n\n### CDN\n\n```html\n<!-- Cesium must be loaded first / 必须先加载 Cesium -->\n<script src=\"https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Cesium.js\"></script>\n<link href=\"https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Widgets/widgets.css\" rel=\"stylesheet\">\n\n<!-- Then include cesium-ui and cesium-tool-tour / 再引入 cesium-ui 和 cesium-tool-tour -->\n<script src=\"https://unpkg.com/@bimangle/cesium-ui/dist/cesium-ui.js\"></script>\n<script src=\"https://unpkg.com/@bimangle/cesium-tool-tour/dist/cesium-tool-tour.js\"></script>\n```\n\n---\n\n## Quick Start / 快速开始\n\n### Browser (CDN)\n\n```html\n<!DOCTYPE html>\n<html>\n<head>\n  <script src=\"https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Cesium.js\"></script>\n  <link href=\"https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Widgets/widgets.css\" rel=\"stylesheet\">\n  <script src=\"https://unpkg.com/@bimangle/cesium-ui/dist/cesium-ui.js\"></script>\n  <script src=\"https://unpkg.com/@bimangle/cesium-tool-tour/dist/cesium-tool-tour.js\"></script>\n  <style>\n    html, body, #cesiumContainer { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; }\n  </style>\n</head>\n<body>\n  <div id=\"cesiumContainer\"></div>\n  <script>\n    const viewer = new Cesium.Viewer('cesiumContainer');\n\n    // One line — cesium-ui is initialized automatically.\n    // 一行接入，cesium-ui 会自动初始化。\n    viewer.extend(ToolTourMixin);\n\n    // Access the instance / 访问实例\n    // viewer.toolTour  → ToolTour instance\n  </script>\n</body>\n</html>\n```\n\n### NPM / ES Modules\n\n```javascript\nimport * as Cesium from 'cesium';\nimport { ToolTourMixin } from '@bimangle/cesium-tool-tour';\n\nconst viewer = new Cesium.Viewer('cesiumContainer');\n\n// One line — cesium-ui is initialized automatically.\n// 一行接入，cesium-ui 会自动初始化。\nviewer.extend(ToolTourMixin);\n\n// Access the instance / 访问实例\n// viewer.toolTour  → ToolTour instance\n```\n\nTo customize the toolbar position / 自定义工具栏位置：\n\n```javascript\nviewer.extend(ToolTourMixin, {\n    uiOptions: {\n        position:              'top-left',\n        direction:             'vertical',\n        notificationPosition:  'bottom-right',\n        panelCascadeDirection: 'right',\n    }\n});\n```\n\nTo co-exist with the measure plugin / 与测量插件共存：\n\n```javascript\nviewer.extend(ToolMeasureMixin);\nviewer.extend(ToolTourMixin);  // shares the same toolbar / 共享同一工具栏\n```\n\n---\n\n## Controls / 操作说明\n\n### Keyboard mode / 键鼠模式\n\n| Key / 按键 | Action / 动作 |\n|------------|---------------|\n| `W` / `↑`  | Move forward / 向前 |\n| `S` / `↓`  | Move backward / 向后 |\n| `A` / `←`  | Move left / 向左 |\n| `D` / `→`  | Move right / 向右 |\n| `Q` / `PageUp`   | Move up / 向上 |\n| `E` / `PageDown` | Move down / 向下 |\n| Mouse move | Rotate view (Pointer Lock) / 旋转视角（Pointer Lock）|\n| Left-drag  | Rotate view (degraded mode) / 旋转视角（降级模式）|\n| Scroll wheel ↑ | Move forward / 向前移动 |\n| Scroll wheel ↓ | Move backward / 向后移动 |\n| Left double-click | Fly halfway to target / 飞向目标中点 |\n| `Esc`      | Exit tour mode / 退出漫游 |\n\nClick **▶ Start Tour / ▶ 开始漫游** in the panel, then move the mouse to look around.  \n点击面板中的 **▶ 开始漫游** 按钮后，移动鼠标控制视角。\n\n### Virtual joystick mode / 虚拟摇杆模式\n\nCheck **Virtual Joystick / 虚拟摇杆** in the panel. Controls are immediately available:  \n勾选面板中的 **虚拟摇杆** 选项，控件立即可用：\n\n- **WASDQE buttons** — same movement as keyboard / 与键盘相同的移动操作\n- **Joystick pad** — drag to rotate the camera view / 拖拽旋转视角\n- Cesium native pan / orbit gestures remain fully active outside the panel / 面板外 Cesium 原生操作不受影响\n\n---\n\n## API\n\n```javascript\n// viewer.extend() — recommended entry point (idempotent)\n// viewer.extend() — 推荐的初始化方式（幂等）\nviewer.extend(ToolTourMixin);\nviewer.extend(ToolTourMixin, options);  // with options / 带配置项\n\n// Direct class usage / 直接使用类\nconst tool = new ToolTour(viewer, options);\n\n// Access via viewer property (set by Mixin)\n// 通过 viewer 属性访问（由 Mixin 设置）\nviewer.toolTour.activate();    // Enter keyboard mode / 进入键鼠模式\nviewer.toolTour.deactivate();  // Exit keyboard mode / 退出键鼠模式\nviewer.toolTour.destroy();     // Full cleanup / 完整销毁\n```\n\n### Options / 配置项\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `uiOptions` | `object` | `{}` | Passed to `CesiumUIMixin` if cesiumUI not yet initialised / 若 cesiumUI 尚未初始化时传入 |\n\n---\n\n## Technical Notes / 技术说明\n\n### Mouse input / 鼠标输入\n\nMouse look is handled via `Cesium.ScreenSpaceEventHandler` bound to the scene canvas, which\noperates inside Cesium's own event pipeline and is unaffected by `stopPropagation` or pointer\ncapture from other elements.  \n鼠标视角通过绑定在 canvas 上的 `Cesium.ScreenSpaceEventHandler` 处理，工作在 Cesium 自身事件管道内，不受外部 `stopPropagation` 影响。\n\n- **Pointer Lock mode**: cursor is hidden, `MOUSE_MOVE` delta is used directly.  \n- **Degraded mode** (Pointer Lock denied / iframe): left-button drag (`LEFT_DOWN` → `MOUSE_MOVE` → `LEFT_UP`) controls view rotation.  \n\n### Mouse wheel / 滚轮前进后退\n\nThe `WHEEL` event from `ScreenSpaceEventHandler` is used. Scroll up (positive delta) = move\nforward; scroll down = move backward. Each standard notch (120 units) moves `stepDist × 5`.  \n通过 `ScreenSpaceEventHandler` 的 `WHEEL` 事件处理滚轮输入。向上滚（正值）为前进，向下滚为后退，每格移动 `stepDist × 5`。\n\n### Double-click advance / 双击推进\n\nDouble-clicking in keyboard mode picks the 3-D scene position under the cursor\n(`scene.pickPosition` → fallback to `globe.pick`) and flies the camera to the midpoint between\nits current position and the picked point. The camera is oriented to face the target throughout\nthe flight. If nothing is picked (sky), the action is ignored.  \n双击时拾取光标下方的三维坐标，镜头平滑飞行到当前位置与目标点的中间处，飞行期间镜头保持面向目标点。点击天空时忽略。\n\n### Keyboard mode implementation / 键鼠模式实现\n\n- Calls `canvas.requestPointerLock()` to enable unlimited mouse movement  \n  调用 `canvas.requestPointerLock()` 实现无限制鼠标移动\n- Disables `viewer.scene.screenSpaceCameraController` (all axes) while active, restores on exit  \n  激活时禁用 `screenSpaceCameraController`，退出时自动恢复原始状态\n- Listens for `pointerlockchange` to handle unexpected unlock (e.g. Alt+Tab)  \n  监听 `pointerlockchange` 处理意外解锁（如 Alt+Tab）\n\n### Hold-key acceleration / 持续按键加速\n\n```\nkeydown → immediate single move (stepDist)\n          ↓ after 300 ms hold\n          continuous: stepDist × 30 × Δt (m/s)\nkeyup   → stop\n```\n\nImplemented via a `Map<code, { pressTime, singleFired }>` polled on every `clock.onTick` frame.  \n通过 `clock.onTick` 每帧轮询 `Map<code, { pressTime, singleFired }>` 实现。\n\n### Pitch clamping / 俯仰角限制\n\nCesium's `camera.pitch` is read-only. Pitch is clamped to `[-85°, +85°]` by accumulating the applied\n`lookUp` delta in `_pitchAccum` and refusing to exceed the limits.  \nCesium 的 `camera.pitch` 为只读，通过累积 `lookUp` 增量并限制在 `[-85°, +85°]` 内实现俯仰角钳制。\n\n### Horizontal mode / 水平模式\n\nIn horizontal mode, W/S/A/D movement direction is projected onto the local tangent plane using\nthe ellipsoid geodetic surface normal at the camera position, so forward/backward/left/right\nmovement is always parallel to the ground regardless of camera pitch.  \n水平模式下，WASD 移动方向通过椭球面法线投影到切平面，无论俯仰角如何，前后左右始终与地面平行。\n\n### Virtual joystick event isolation / 虚拟摇杆事件隔离\n\nAll pointer events inside the joystick area call `stopPropagation()` and `preventDefault()`,\nso they never reach Cesium's canvas event handlers.  \n摇杆区域内的所有 pointer 事件均调用 `stopPropagation()` 和 `preventDefault()`，不会传递到 Cesium 的 canvas 事件处理器。\n\n---\n\n## CSS Class Reference / CSS 命名规范\n\nAll classes use the `ba-ctt-` prefix (`ba` = BimAngle, `ctt` = cesium-tool-tour).  \n所有 CSS 类名采用 `ba-ctt-` 前缀。\n\n| Class | Purpose |\n|-------|---------|\n| `.ba-ctt-panel` | Sub-panel container |\n| `.ba-ctt-panel--visible` | Sub-panel visible state |\n| `.ba-ctt-panel-header` | Title bar (draggable) |\n| `.ba-ctt-section` | Config section block |\n| `.ba-ctt-radio-group` | Step-distance radio group |\n| `.ba-ctt-mode-btn` | View mode toggle button |\n| `.ba-ctt-mode-btn--active` | Active view mode button |\n| `.ba-ctt-checkbox-row` | Joystick toggle row |\n| `.ba-ctt-start-btn` | Start Tour button |\n| `.ba-ctt-joystick-area` | Expandable joystick section |\n| `.ba-ctt-joystick-area--visible` | Joystick section visible state |\n| `.ba-ctt-vbtns` | Virtual button grid |\n| `.ba-ctt-vbtn` | Individual virtual button |\n| `.ba-ctt-vbtn--pressed` | Virtual button pressed state |\n| `.ba-ctt-vjoy-pad` | Joystick outer pad |\n| `.ba-ctt-vjoy-knob` | Joystick inner knob |\n| `.ba-ctt-vjoy-knob--active` | Knob dragging state |\n| `.ba-ctt-hud` | HUD overlay bar (keyboard mode) |\n| `.ba-ctt-hud--visible` | HUD visible state |\n\n---\n\n## Compatibility / 兼容性\n\n- CesiumJS ≥ 1.110.0\n- Chrome 90+, Firefox 88+, Edge 90+, Safari 15+\n- Pointer Lock API required for keyboard mode / 键鼠模式需要 Pointer Lock API 支持\n\n---\n\n## Build / 构建\n\n```bash\nnpm install\nnpm run build\n# Output: dist/cesium-tool-tour.js\n```\n\n---\n\n## License / 许可证\n\nMIT © BimAngle\n","readmeFilename":"README.md","_rev":"1-ba243bbf84013fb7164eeccbe005471c"}