fix: pause animation loop while not rendering
This commit is contained in:
@@ -192,6 +192,7 @@ let mesh = null;
|
||||
let directionalLight = null;
|
||||
let ambientLight = null;
|
||||
let animationId = null;
|
||||
let animationPaused = false;
|
||||
|
||||
// Geometry cache for height exaggeration
|
||||
let geometryCache = null;
|
||||
@@ -233,8 +234,19 @@ const initThreeJS = () => {
|
||||
|
||||
updateLightPosition();
|
||||
|
||||
// Animation loop
|
||||
// Don't start animation loop yet - will be controlled by pause/resume
|
||||
};
|
||||
|
||||
// Animation loop control
|
||||
const startAnimation = () => {
|
||||
if (animationId) return; // Already running
|
||||
|
||||
const animate = () => {
|
||||
if (animationPaused) {
|
||||
animationId = null;
|
||||
return;
|
||||
}
|
||||
|
||||
animationId = requestAnimationFrame(animate);
|
||||
if (renderer && scene && camera) {
|
||||
renderer.render(scene, camera);
|
||||
@@ -243,6 +255,26 @@ const initThreeJS = () => {
|
||||
animate();
|
||||
};
|
||||
|
||||
const pauseAnimation = () => {
|
||||
animationPaused = true;
|
||||
if (animationId) {
|
||||
cancelAnimationFrame(animationId);
|
||||
animationId = null;
|
||||
}
|
||||
};
|
||||
|
||||
const resumeAnimation = () => {
|
||||
animationPaused = false;
|
||||
startAnimation();
|
||||
};
|
||||
|
||||
// Render a single frame (for when animation is paused but we need to update the view)
|
||||
const renderSingleFrame = () => {
|
||||
if (renderer && scene && camera) {
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle canvas resize
|
||||
const handleResize = () => {
|
||||
if (!canvasRef.value || !renderer || !camera) return;
|
||||
@@ -422,11 +454,13 @@ const updateHeightScale = () => {
|
||||
|
||||
geometryCache.geometry.attributes.position.needsUpdate = true;
|
||||
geometryCache.geometry.computeVertexNormals();
|
||||
renderSingleFrame(); // Render once to show the change
|
||||
};
|
||||
|
||||
// Update scene (for real-time preview)
|
||||
const updateScene = () => {
|
||||
updateLightPosition();
|
||||
renderSingleFrame(); // Render once to show the change
|
||||
};
|
||||
|
||||
// Color conversion utilities
|
||||
@@ -438,6 +472,7 @@ const updateColor = (e) => {
|
||||
settings.terrainColor = parseInt(e.target.value.replace('#', ''), 16);
|
||||
if (mesh && mesh.material) {
|
||||
mesh.material.color.setHex(settings.terrainColor);
|
||||
renderSingleFrame(); // Render once to show the change
|
||||
}
|
||||
};
|
||||
|
||||
@@ -634,9 +669,7 @@ const downloadLastRender = () => {
|
||||
|
||||
// Cleanup
|
||||
const cleanup = () => {
|
||||
if (animationId) {
|
||||
cancelAnimationFrame(animationId);
|
||||
}
|
||||
pauseAnimation();
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect();
|
||||
resizeObserver = null;
|
||||
@@ -663,6 +696,11 @@ onMounted(() => {
|
||||
});
|
||||
resizeObserver.observe(canvasRef.value);
|
||||
}
|
||||
|
||||
// Only start animation if visible and not offscreen
|
||||
if (!props.offscreen) {
|
||||
resumeAnimation();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -680,7 +718,29 @@ watch(() => props.visible, (newVal) => {
|
||||
});
|
||||
resizeObserver.observe(canvasRef.value);
|
||||
}
|
||||
|
||||
// Start animation when visible and not offscreen
|
||||
if (!props.offscreen) {
|
||||
resumeAnimation();
|
||||
}
|
||||
});
|
||||
} else if (newVal && !props.offscreen) {
|
||||
// Component already initialized, just resume animation
|
||||
resumeAnimation();
|
||||
} else if (!newVal) {
|
||||
// Hidden - pause animation
|
||||
pauseAnimation();
|
||||
}
|
||||
});
|
||||
|
||||
// Watch for offscreen changes
|
||||
watch(() => props.offscreen, (newVal) => {
|
||||
if (newVal) {
|
||||
// Offscreen mode - pause animation (we only render single frames on demand)
|
||||
pauseAnimation();
|
||||
} else if (props.visible) {
|
||||
// Not offscreen and visible - resume animation
|
||||
resumeAnimation();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -721,8 +781,7 @@ defineExpose({
|
||||
}
|
||||
|
||||
.modal-container.offscreen {
|
||||
left: -10000px;
|
||||
top: -10000px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
|
||||
Reference in New Issue
Block a user