如何在React中实现页面滚动时移动场景相机的功能?
核心实现逻辑和原生JS完全一致,都是通过监听滚动事件获取偏移量,再同步修改相机的位置参数,只是React中需要按照组件生命周期规则正确绑定/销毁事件,避免出现内存泄漏、事件重复绑定的问题。
以下是React函数组件的标准实现示例(以Three.js场景为例):
import { useEffect, useRef } from 'react'; import * as THREE from 'three'; function ScrollControlledScene() { // 用useRef存储不需要触发重渲染的实例对象 const cameraRef = useRef(null); const containerRef = useRef(null); useEffect(() => { // 初始化场景、相机、渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); containerRef.current.appendChild(renderer.domElement); cameraRef.current = camera; // 滚动处理逻辑,和原生实现思路完全一致 const moveCamera = () => { // 兼容不同浏览器的滚动高度获取,修正你原生代码中document无getBoundingClientRect的问题 const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; cameraRef.current.position.z = scrollTop * -0.001; cameraRef.current.position.x = scrollTop * -0.0001; cameraRef.current.position.y = scrollTop * -0.0001; }; // 绑定全局滚动事件 window.addEventListener('scroll', moveCamera); // 清理逻辑:组件卸载时移除事件监听,避免内存泄漏 return () => { window.removeEventListener('scroll', moveCamera); }; }, []); return <div ref={containerRef} />; } export default ScrollControlledScene;
注意事项:
- 如果你的滚动区域是组件内部的局部容器,直接把事件绑定到对应容器的ref实例上即可,不需要绑定到全局window
- 相机、渲染器这类跨渲染周期需要保持引用的实例,统一用useRef存储即可,作用和原生写法中的全局变量一致
- 如果是类组件实现,把事件绑定逻辑放到componentDidMount生命周期中,事件销毁逻辑放到componentWillUnmount生命周期中即可
内容的提问来源于stack exchange,提问作者Jeoffrey Duke
相关产品推荐
相关产品推荐

