旋转立方体 · 原理与代码
基础场景、光照与线框。
运行逻辑
访问 `/threejs/cube` 时,DemoHost 按 registry 的 `mod: 'cube'` 懒加载 `demos/cube.js`,调用 `mountCube(host, { variant: 'cube' })`。 `createThreeStage` 创建 WebGLRenderer、Scene、PerspectiveCamera 与 OrbitControls,并接上信息面板。 模块用 `S.onFrame` 注册每帧回调。 每个 `requestAnimationFrame`:读取控件值,按速度缩放模拟时钟(dt 上限 50 ms),执行帧回调绘制;返回的读数写入信息面板。 改变参数:颜色/速度/大小等即时生效,需要重建的参数触发重新挂载;离开页面时取消 rAF、移除监听并释放资源。
运行环境
Canvas 2D: 2D 画布绘图; WebGL (three.js): three.js 通过 WebGLRenderer 使用 WebGL; requestAnimationFrame: 与屏幕刷新同步的动画循环; ResizeObserver: 画布随容器尺寸自适应; Pointer Events: 鼠标/触摸/触控笔统一事件; devicePixelRatio: HiDPI 清晰渲染(上限 2×) · react 18.3.1, react-router-dom 6.30.6, vite 5.4.21, three 0.170.0
引入的组件与依赖
three 0.170.0, three/addons/controls/OrbitControls.js 0.170.0, react 18.3.1
引入的组件函数
createThreeStage — 共享 Three.js 舞台:WebGLRenderer、场景、透视相机、OrbitControls、自适应取景与渲染循环; addLights — 添加环境光 + 主光 + 补光; THREE — three.js 命名空间; fmt — 数字格式化(固定小数位); deg — 弧度 → 角度文本; F — 公式块 HTML; S.onFrame — 注册每帧回调,返回值进入信息面板读数; THREE.Mesh — 网格物体(几何体 + 材质); THREE.BoxGeometry — 立方体几何体; THREE.MeshStandardMaterial — PBR 标准材质; THREE.LineSegments — 线段集合; THREE.EdgesGeometry — 提取棱线; THREE.LineBasicMaterial — 线条材质; THREE.GridHelper — 网格辅助线
本 demo 代码
frontend/src/demos/cube.js: cube.js (L1-L48)
代码解释
L4-10: `PARAMS_SPEC`(常量/表)。 L11-27: `DOC`(常量/表)。 L29-48: `mountCube`(函数);创建 three.js 对象 `Mesh`, `BoxGeometry`, `MeshStandardMaterial`, `LineSegments`, `EdgesGeometry`, `LineBasicMaterial` …;返回读数 `rx`, `ry`, `wx`, `wy`, `k`, `a` 给信息面板。
原理
θ(t) = θ₀ + ω · t ωx = 0.6·k, ωy = 0.9·k(k = 自转速度) V = a³,S = 6a² 一个最基础的 Three.js 场景: 场景 Scene 放物体, 相机 Camera 决定从哪看, 渲染器 Renderer 每帧把画面画到画布上。 方块每帧绕 X、Y 轴各转一点点,角度随时间 匀速增加 ,这就是“欧拉角旋转”。灯光让每个面明暗不同,你才看得出它是立体的。