import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; /** * OrbitControls 适配器 * * 封装 Three.js OrbitControls 的初始化和常用配置, * 专为棋盘/拼图类 3D 游戏设计: * - 拖拽旋转视角(限制极角防止穿地) * - 滚轮/pinch 缩放(限制距离范围) * - 可选平移 * - 阻尼平滑 * * 与 CameraController 协同使用: * - CameraController 负责 setupForBoard(初始定位)+ shake + transition * - OrbitControlsAdapter 负责用户交互旋转/缩放 * - 两者共享同一个 camera 实例 * * 注意:启用 OrbitControls 后,CameraController 的 setupForBoard * 不再直接控制 camera(因为 OrbitControls 会覆盖 camera.position)。 * 应改为设置 OrbitControlsAdapter.setTarget() 来调整视角中心。 */ export interface OrbitConfig { /** 启用惯性阻尼(默认 true) */ enableDamping?: boolean; /** 阻尼系数(默认 0.1) */ dampingFactor?: number; /** 启用平移(默认 true) */ enablePan?: boolean; /** 启用缩放(默认 true) */ enableZoom?: boolean; /** 启用旋转(默认 true) */ enableRotate?: boolean; /** 最小缩放距离(默认 3) */ minDistance?: number; /** 最大缩放距离(默认 20) */ maxDistance?: number; /** 最小极角 rad(默认 0.2,防止正上方看不清) */ minPolarAngle?: number; /** 最大极角 rad(默认 Math.PI/2 - 0.1,防止穿地面) */ maxPolarAngle?: number; /** 平移速度(默认 1.0) */ panSpeed?: number; /** 旋转速度(默认 1.0) */ rotateSpeed?: number; } const DEFAULT_CONFIG: Required = { enableDamping: true, dampingFactor: 0.1, enablePan: true, enableZoom: true, enableRotate: true, minDistance: 3, maxDistance: 20, minPolarAngle: 0.2, maxPolarAngle: Math.PI / 2 - 0.1, panSpeed: 1.0, rotateSpeed: 1.0, }; export class OrbitControlsAdapter { private controls: OrbitControls; private _enabled = true; constructor( camera: THREE.PerspectiveCamera, canvas: HTMLCanvasElement, config?: OrbitConfig, ) { const cfg = { ...DEFAULT_CONFIG, ...config }; this.controls = new OrbitControls(camera, canvas); this.controls.enableDamping = cfg.enableDamping; this.controls.dampingFactor = cfg.dampingFactor; this.controls.enablePan = cfg.enablePan; this.controls.enableZoom = cfg.enableZoom; this.controls.enableRotate = cfg.enableRotate; this.controls.minDistance = cfg.minDistance; this.controls.maxDistance = cfg.maxDistance; this.controls.minPolarAngle = cfg.minPolarAngle; this.controls.maxPolarAngle = cfg.maxPolarAngle; this.controls.panSpeed = cfg.panSpeed; this.controls.rotateSpeed = cfg.rotateSpeed; // 默认看向原点 this.controls.target.set(0, 0, 0); this.controls.update(); } /** * 设置视角中心点(OrbitControls 的旋转目标) */ setTarget(position: THREE.Vector3): void { this.controls.target.copy(position); this.controls.update(); } /** * 获取当前 target */ getTarget(): THREE.Vector3 { return this.controls.target.clone(); } /** * 每帧更新(需在 animation loop 中调用) */ update(): void { if (this._enabled) { this.controls.update(); } } /** * 启用交互 */ enable(): void { this._enabled = true; this.controls.enabled = true; } /** * 禁用交互(暂停拖动/缩放) */ disable(): void { this._enabled = false; this.controls.enabled = false; } /** * 是否启用状态 */ get enabled(): boolean { return this._enabled; } /** * 获取原始 OrbitControls 实例(高级用法) */ getRawControls(): OrbitControls { return this.controls; } /** * 销毁 */ dispose(): void { this.controls.dispose(); } }