perf: render theo nhu cầu + throttle cameraYaw (giảm tải khi đứng yên)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -958,6 +958,8 @@ function TourExperience({
|
||||
const transitionLockRef = useRef(false);
|
||||
const currentFovRef = useRef(DEFAULT_FOV);
|
||||
const targetFovRef = useRef(DEFAULT_FOV);
|
||||
const needsRenderRef = useRef(true);
|
||||
const lastYawRef = useRef(0);
|
||||
const lastPinchDistanceRef = useRef<number | null>(null);
|
||||
const infoMarkerRefs = useRef<Map<string, HTMLButtonElement>>(new Map());
|
||||
const [activeInfoMarker, setActiveInfoMarker] = useState<InfoMarker | null>(null);
|
||||
@@ -1428,6 +1430,11 @@ function TourExperience({
|
||||
}
|
||||
};
|
||||
|
||||
const handleControlsChange = () => {
|
||||
needsRenderRef.current = true;
|
||||
};
|
||||
controls.addEventListener("change", handleControlsChange);
|
||||
|
||||
renderer.domElement.addEventListener("wheel", handleWheel, { passive: false });
|
||||
renderer.domElement.addEventListener("touchstart", handleTouchStart, { passive: false });
|
||||
renderer.domElement.addEventListener("touchmove", handleTouchMove, { passive: false });
|
||||
@@ -1455,8 +1462,9 @@ function TourExperience({
|
||||
|
||||
const animate = () => {
|
||||
const targetFov = targetFovRef.current;
|
||||
const fovAnimating = Math.abs(currentFovRef.current - targetFov) > 0.01;
|
||||
|
||||
if (Math.abs(currentFovRef.current - targetFov) > 0.01) {
|
||||
if (fovAnimating) {
|
||||
currentFovRef.current += (targetFov - currentFovRef.current) * 0.16;
|
||||
camera.fov = currentFovRef.current;
|
||||
camera.updateProjectionMatrix();
|
||||
@@ -1464,20 +1472,35 @@ function TourExperience({
|
||||
currentFovRef.current = targetFov;
|
||||
camera.fov = targetFov;
|
||||
camera.updateProjectionMatrix();
|
||||
needsRenderRef.current = true;
|
||||
}
|
||||
|
||||
if (!vrModeRef.current) {
|
||||
controls.update();
|
||||
}
|
||||
// controls.update() trả về true khi camera vừa thay đổi (kể cả damping đang lắng).
|
||||
const controlsChanged = vrModeRef.current ? false : controls.update();
|
||||
const transitionActive = transitionFrameRef.current !== null;
|
||||
const active =
|
||||
needsRenderRef.current ||
|
||||
fovAnimating ||
|
||||
controlsChanged ||
|
||||
controls.autoRotate ||
|
||||
vrModeRef.current ||
|
||||
transitionActive;
|
||||
|
||||
// Update camera yaw for mini-map rotation
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
needsRenderRef.current = false;
|
||||
|
||||
// Cập nhật yaw cho mini-map — chỉ setState khi đổi đủ lớn để tránh re-render thừa.
|
||||
const direction = new THREE.Vector3();
|
||||
camera.getWorldDirection(direction);
|
||||
const yaw = yawFromDirection(direction);
|
||||
setCameraYaw(yaw);
|
||||
if (Math.abs(normalizeYaw(yaw - lastYawRef.current)) > 0.15) {
|
||||
lastYawRef.current = yaw;
|
||||
setCameraYaw(yaw);
|
||||
}
|
||||
|
||||
updateHotspots();
|
||||
|
||||
renderer.render(threeScene, camera);
|
||||
};
|
||||
|
||||
@@ -1495,6 +1518,7 @@ function TourExperience({
|
||||
renderer.domElement.removeEventListener("pointermove", handlePointerMove);
|
||||
renderer.domElement.removeEventListener("pointerup", handlePointerEnd);
|
||||
renderer.domElement.removeEventListener("pointercancel", handlePointerEnd);
|
||||
controls.removeEventListener("change", handleControlsChange);
|
||||
renderer.setAnimationLoop(null);
|
||||
controls.dispose();
|
||||
geometry.dispose();
|
||||
|
||||
Reference in New Issue
Block a user