Skip to content

Simple reverse playback for multiple animations by allowing THREE.AnimationAction.time to exceed duration #33291

@fullmooooon

Description

@fullmooooon

Description

my sample code

I am using Blender together with three.js to display 3D animations on the web.
My goal is to play an animation forward once, and then reverse it once.

For example, in Blender:

  • From 0–1 seconds: Box 1 rotates 90° on the X axis
  • From 1–2 seconds: Box 2 rotates 90° on the Y axis
  • From 2–3 seconds: Box 3 rotates 90° on the Z axis

test.blend

Image

After importing with GLTFLoader, the resulting clip durations become: 1, 2, 3 (It seems that the start time is normalized to 0 for each clip.)

When THREE.AnimationAction.time exceeds duration, the animation is effectively ignored .

Because of this behavior, reverse playback does not work correctly in the following code:

const playAnimation = (reverse = false) => {
  actions.forEach((action) => {
    const clip = action.getClip()
    const duration = clip.duration

    action.stop()
    action.reset()

    if (reverse) {
      // reverse playback  !!! not work !!!
      action.time = 3 // start from 3 seconds  (maximum duration of the animation) for reverse playback
      action.timeScale = -1
    } else {
      // forward playback
      action.time = 0
      action.timeScale = 1
    }

    action.setLoop(THREE.LoopOnce, 1)
    action.clampWhenFinished = true

    action.play()
  })
}

Expected Behavior

If THREE.AnimationAction.time is allowed to exceed clip.duration,
easy reverse playback across multiple animations would become possible.

This would benefit all users who need to implement reverse playback, as it significantly simplifies the required logic.

In addition, this would make negative timeScale (e.g. timeScale < 0) behave more consistently, allowing reverse playback to continue evaluating the final pose even when time goes beyond the clip duration.

Solution

  • Allow THREE.AnimationAction.time to exceed clip.duration
  • When time > duration, the animation should:
    • Stay at the final keyframe (last pose)
    • Continue to be evaluable (instead of being ignored)

Alternatives

In Blender, extend all animations so that they share the same start and end time

workaround.blend

Image

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions