> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/BintzGavin/helios/llms.txt
> Use this file to discover all available pages before exploring further.

# Sequencing utilities

> Sequence timing, series, stagger, and shift functions

Utilities for organizing and timing sequences of animations.

## sequence()

Calculates the local time and progress of a sequence relative to a start frame.

```typescript theme={null}
const result = sequence(options);
```

<ParamField path="options" type="SequenceOptions" required>
  Sequence configuration

  <Expandable title="properties">
    <ParamField path="frame" type="number" required>
      Current frame number
    </ParamField>

    <ParamField path="from" type="number" required>
      Starting frame number
    </ParamField>

    <ParamField path="durationInFrames" type="number">
      Duration in frames (if undefined, sequence is infinite)
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="result" type="SequenceResult">
  Sequence state object

  <Expandable title="properties">
    <ResponseField name="localFrame" type="number">
      Frame number relative to sequence start (frame - from)
    </ResponseField>

    <ResponseField name="relativeFrame" type="number">
      Alias for localFrame
    </ResponseField>

    <ResponseField name="progress" type="number">
      Progress from 0 to 1 (0 if no duration)
    </ResponseField>

    <ResponseField name="isActive" type="boolean">
      True if within sequence duration
    </ResponseField>
  </Expandable>
</ResponseField>

### Example

```typescript theme={null}
import { sequence } from '@heliosvideo/core';

const seq = sequence({
  frame: currentFrame,
  from: 30,
  durationInFrames: 60,
});

if (seq.isActive) {
  const opacity = seq.progress;
  const scale = 0.5 + seq.progress * 0.5;
}
```

## series()

Calculates start frames for items placed one after another.

```typescript theme={null}
const items = series(itemsWithDuration, startFrame);
```

<ParamField path="items" type="T[]" required>
  Array of items with `durationInFrames` property

  Each item should have:

  * `durationInFrames`: number (required)
  * `offset`: number (optional) - Shifts this item relative to the previous item's end
</ParamField>

<ParamField path="startFrame" type="number" default="0">
  Starting frame for the sequence
</ParamField>

<ResponseField name="items" type="(T & { from: number })[]">
  Items with added `from` property indicating start frame
</ResponseField>

### Example

```typescript theme={null}
import { series } from '@heliosvideo/core';

const scenes = series([
  { id: 'intro', durationInFrames: 60 },
  { id: 'main', durationInFrames: 120 },
  { id: 'outro', durationInFrames: 30, offset: -15 }, // Overlap by 15 frames
]);

// Result:
// [
//   { id: 'intro', durationInFrames: 60, from: 0 },
//   { id: 'main', durationInFrames: 120, from: 60 },
//   { id: 'outro', durationInFrames: 30, offset: -15, from: 165 },
// ]
```

## stagger()

Staggers items by a fixed interval.

```typescript theme={null}
const items = stagger(items, interval, startFrame);
```

<ParamField path="items" type="T[]" required>
  Array of items to stagger
</ParamField>

<ParamField path="interval" type="number" required>
  Number of frames between each item
</ParamField>

<ParamField path="startFrame" type="number" default="0">
  Starting frame for the first item
</ParamField>

<ResponseField name="items" type="(T & { from: number })[]">
  Items with added `from` property
</ResponseField>

### Example

```typescript theme={null}
import { stagger } from '@heliosvideo/core';

const letters = ['H', 'E', 'L', 'L', 'O'].map(letter => ({ letter }));

const staggered = stagger(letters, 5, 0);

// Result:
// [
//   { letter: 'H', from: 0 },
//   { letter: 'E', from: 5 },
//   { letter: 'L', from: 10 },
//   { letter: 'L', from: 15 },
//   { letter: 'O', from: 20 },
// ]

staggered.forEach(({ letter, from }) => {
  const seq = sequence({
    frame: currentFrame,
    from,
    durationInFrames: 30,
  });
  
  if (seq.isActive) {
    // Animate letter
  }
});
```

## shift()

Shifts the start time of sequenced items.

```typescript theme={null}
const shifted = shift(items, offset);
```

<ParamField path="items" type="T[]" required>
  Array of items with `from` property
</ParamField>

<ParamField path="offset" type="number" required>
  Number of frames to shift (can be negative)
</ParamField>

<ResponseField name="items" type="T[]">
  Items with updated `from` values
</ResponseField>

### Example

```typescript theme={null}
import { stagger, shift } from '@heliosvideo/core';

const items = stagger([1, 2, 3], 10);
// [{ from: 0 }, { from: 10 }, { from: 20 }]

const delayed = shift(items, 30);
// [{ from: 30 }, { from: 40 }, { from: 50 }]

const earlier = shift(items, -5);
// [{ from: -5 }, { from: 5 }, { from: 15 }]
```

## Complete example

```typescript theme={null}
import { sequence, series, stagger, shift } from '@heliosvideo/core';

// Create a series of scenes
const scenes = series([
  { name: 'Scene 1', durationInFrames: 90 },
  { name: 'Scene 2', durationInFrames: 120 },
  { name: 'Scene 3', durationInFrames: 60 },
]);

// Stagger elements within each scene
const elements = stagger(
  ['element-1', 'element-2', 'element-3'].map(id => ({ id })),
  8 // 8 frames apart
);

// Shift elements to start at frame 20
const delayedElements = shift(elements, 20);

// Render logic
delayedElements.forEach(({ id, from }) => {
  const seq = sequence({
    frame: currentFrame,
    from,
    durationInFrames: 30,
  });
  
  if (seq.isActive) {
    const opacity = seq.progress;
    // Render element with animated opacity
  }
});
```
