diff --git a/src/utils/createTravelScene.ts b/src/utils/createTravelScene.ts index 585371e..4d42e7d 100644 --- a/src/utils/createTravelScene.ts +++ b/src/utils/createTravelScene.ts @@ -496,6 +496,7 @@ export function createTravelScene(container: HTMLElement): TravelSceneController let started = false let targetSpeed: number = APP_CONFIG.animation.defaultSpeed let currentSpeed = 0 + let accumulatedWobbleTime = 0 let animationFrameId = 0 let disposed = false @@ -821,13 +822,31 @@ export function createTravelScene(container: HTMLElement): TravelSceneController material.uniforms.uTime.value = elapsed + index * 0.37 }) - travelRoot.rotation.z = pointerCurrent.x * 0.03 - travelRoot.position.x = -pointerCurrent.x * 0.8 - travelRoot.position.y = -pointerCurrent.y * 0.45 + // 自动视角随机摆动,摆动速度跟随当前速度 (currentSpeed) 动态变化 + // 修复抖动:通过 deltaSeconds 累加时间,而不是直接用 elapsed 乘以可变的速度,避免相位突变 + accumulatedWobbleTime += deltaSeconds * (0.8 + currentSpeed * 2.0) + + // 利用多个不同频率的三角函数叠加,生成平滑且看似随机的摆动 + const wobbleX = (Math.sin(accumulatedWobbleTime * 0.8) + Math.sin(accumulatedWobbleTime * 1.7 + 2.1) + Math.sin(accumulatedWobbleTime * 0.5 + 4.3)) / 3 + const wobbleY = (Math.cos(accumulatedWobbleTime * 0.9) + Math.cos(accumulatedWobbleTime * 1.5 + 1.2) + Math.cos(accumulatedWobbleTime * 0.6 + 3.5)) / 3 + + // 基础摆动幅度 + 随速度增加的额外幅度 (显著增加摆动幅度) + const wobbleAmpX = 0.8 + currentSpeed * 0.8 + const wobbleAmpY = 0.5 + currentSpeed * 0.5 - camera.position.x = pointerCurrent.x * APP_CONFIG.interaction.maxOffset * 2.8 - camera.position.y = pointerCurrent.y * APP_CONFIG.interaction.maxOffset * 1.8 - camera.lookAt(pointerCurrent.x * 1.5, pointerCurrent.y * 0.8, -30) + // 综合鼠标位置与自动摆动 + const viewX = pointerCurrent.x + wobbleX * wobbleAmpX + const viewY = pointerCurrent.y + wobbleY * wobbleAmpY + + // 较大幅度地影响场景根节点,增加整体动感 + travelRoot.rotation.z = viewX * 0.06 + travelRoot.position.x = -viewX * 1.8 + travelRoot.position.y = -viewY * 1.0 + + // 加大相机的偏移幅度和观察点偏移 + camera.position.x = viewX * APP_CONFIG.interaction.maxOffset * 4.5 + camera.position.y = viewY * APP_CONFIG.interaction.maxOffset * 3.0 + camera.lookAt(viewX * 2.5, viewY * 1.5, -30) renderer.render(scene, camera) animationFrameId = window.requestAnimationFrame(render)