I’m working on a Three.js project with a Tamagotchi-style animated character using GLTF animations and an animation mixer. The project includes a robot, a hatching box, and interactive controls.
Everything runs smoothly until the browser tab is idle for a few minutes. When I return to the window the scene appears frozen and the robot stops animating.
My animation loop is in the class Experience.js
:
this.time.on('tick', () => {
this.update();
});
update() {
const deltaTime = this.time.delta;
this.world.update(deltaTime);
this.camera.update();
this.renderer.update();
}
In the class World.js
the update is:
update(deltaTime) {
if (this.box) {
this.box.update(deltaTime)
}
if (this.robot) {
this.robot.update(deltaTime)
}
}
Inside the Box.js
:
update(deltaTime) {
if (this.mixer) {
this.mixer.update(deltaTime)
}
}
In the Robot.js
:
update(deltaTime) {
if (this.tamagotchiController) {
this.tamagotchiController.update(deltaTime)
}
}
Animation updating in TamagotchiController.js
:
update(deltaTime) {
if (this.mixer) {
this.mixer.update(deltaTime);
}
}
Finally the Camera.js
update is:
update() {
if (this.controls) {
this.controls.update()
}
}
and the Renderer.js
:
update() {
this.instance.render(this.scene, this.camera.instance)
}
The live project is here
I have no idea what is going wrong because no errors appear on the console.
Here is the Time.js
used in the project:
import EventEmitter from './EventEmitter.js'
export default class Time extends EventEmitter {
constructor() {
super()
// Setup
this.start = Date.now()
this.current = this.start
this.elapsed = 0
this.delta = 0.016 // Initialize with a typical frame time in seconds
window.requestAnimationFrame(() => {
this.tick()
})
}
tick() {
const currentTime = Date.now()
this.delta = (currentTime - this.current) / 1000 // Convert milliseconds to seconds
this.current = currentTime
this.elapsed = (this.current - this.start) / 1000 // Convert milliseconds to seconds
this.trigger('tick')
window.requestAnimationFrame(() => {
this.tick()
})
}
}
The source code is here.