DEV Community

liangqi zhao
liangqi zhao

Posted on Fully Autonomous

How to Sample a Loop with Different Durations for Each Animation Frame

By Liangqi Zhao for MotifDeck, an AI game art workspace. This tutorial was prepared with AI assistance.

Uniform frame rates are convenient, but they make every image stay on screen for the same length of time. A short anticipation frame and a longer hold can be useful for a hand-authored animation. Here is a small, engine-independent way to map elapsed time to a frame when each frame has its own duration.

The input contract

Supply one positive duration in milliseconds per frame, in the same order as the images. For example, [100, 150, 250] describes a 500 ms loop. The first frame occupies 0–99 ms, the second 100–249 ms, and the third 250–499 ms. At exactly 500 ms the loop returns to frame zero.

function frameAt(durations, elapsed) {
  if (!durations.length ||
      durations.some(d => !Number.isFinite(d) || d <= 0) ||
      !Number.isFinite(elapsed)) {
    throw new Error('Expected positive durations and finite time');
  }

  const total = durations.reduce((sum, duration) => sum + duration, 0);
  let time = ((elapsed % total) + total) % total;
  for (let i = 0; i < durations.length; i++) {
    if (time < durations[i]) return i;
    time -= durations[i];
  }
  return durations.length - 1;
}
Enter fullscreen mode Exit fullscreen mode

The double modulo keeps a negative time within the loop too; a caller can instead reject negative time if its application never seeks backwards. Validate frame count against the duration array before displaying the result. This example is generic JavaScript, not a claim about MotifDeck's export format.

Test the edges

For the example above, check 99 → frame 0, 100 → frame 1, 250 → frame 2, and 500 → frame 0. Also reject zero or negative durations so a malformed list does not produce ambiguous intervals. The example and these boundaries were checked locally with Node.js.

Keep rendering and gameplay separate

Use the returned index to choose the visual frame, but do not assume every game event must happen exactly when that index changes. A missed render or a large update step can skip over a short frame. Keep gameplay events on a timeline that can detect crossed intervals, and test them separately.

MotifDeck lets users inspect motion and choose frames and timing after generation. Its free plan is a limited preview; generated-file downloads require paid unlock. See the official site for current availability.

Top comments (0)