Skip to content

Staggered transitions #545

Open
Open
@Rich-Harris

Description

@Rich-Harris

A common requirement is to stagger transitions:

barchart

In the GIF, it's been faked with an index and a delay:

<g class='bars'>
  {{#each points as point, i}}
    {{#if show}}
      <rect
        in:grow='{delay: i*200}'
        out:fade
        x='{{xScale(i) + 2}}'
        y='{{yScale(point.birthrate)}}'
        width='{{ barWidth - 4 }}'
        height='{{ height - padding.bottom - yScale(point.birthrate) }}'
        ></rect>
    {{/if}}
  {{/each}}
</g>

But that doesn't work well if new items are added, since their indices will start at n rather than 0.

If the intro is aborted (show becomes false, in the example above), if we have staggered outros then we probably want to a) reverse the stagger (last-in-first-out), and b) ignore any intro transitions that haven't yet started, so that the subject of the most recently started intro transition starts to outro immediately. That would be very hard to do with delays.

Not sure what that would look like. It probably needs to be a separate directive — something like this (means 'start each intro transition 200ms after the last one, and each outro transition 50ms after the last one but go backwards'):

<rect
  in:grow
  stagger:in=200
  stagger:out=-50
  ...

Something else you might want to do is supply a fraction rather than an absolute number. This variant means 'start each intro transition once the previous one is 80% done, but use a fixed 50ms interval for outros':

<rect
  in:grow
  stagger:in=0.8
  stagger:out=-50ms
  ...

Any thoughts?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions