open-slide

Transition

Enter, exit, and morph motion between pages.

SlideTransition describes what happens when the active Page changes. There is no default animation: pages snap unless the deck exports a transition or an incoming page defines its own override.

slides/q2-launch/index.tsx
import type { Page, SlideTransition } from '@open-slide/core';

const Cover: Page = () => <section>…</section>;
const Agenda: Page = () => <section>…</section>;

export const transition: SlideTransition = {
  duration: 220,
  exit: {
    duration: 140,
    easing: 'cubic-bezier(0.4, 0, 1, 1)',
    keyframes: [
      { opacity: 1, transform: 'translateY(0)' },
      { opacity: 0, transform: 'translateY(-4px)' },
    ],
  },
  enter: {
    duration: 220,
    delay: 80,
    easing: 'cubic-bezier(0, 0, 0.2, 1)',
    keyframes: [
      { opacity: 0, transform: 'translateY(6px)' },
      { opacity: 1, transform: 'translateY(0)' },
    ],
  },
};

export default [Cover, Agenda] satisfies Page[];

prefers-reduced-motion: reduce is honored automatically.

Where it lives

There are two declaration surfaces:

  • export const transition in the slide module sets the deck default.
  • Page.transition = … sets an override for one page.

The incoming page wins. Navigating Cover → Agenda uses Agenda.transition ?? module.transition; the selected exit runs on Cover, and enter runs on Agenda. Navigating backward uses the page you are returning to.

const Cover: Page = () => <section>…</section>;
const Agenda: Page = () => <section>…</section>;

export const transition: SlideTransition = {
  duration: 220,
  enter: {
    keyframes: [{ opacity: 0 }, { opacity: 1 }],
  },
};

Agenda.transition = {
  duration: 320,
  enter: {
    keyframes: [
      { opacity: 0, transform: 'scale(0.98)' },
      { opacity: 1, transform: 'scale(1)' },
    ],
  },
};

Direction

During a page transition, the wrapper exposes --osd-dir (1 / -1) and data-osd-dir (forward / backward) so a keyframe can mirror itself on backward navigation. See SlideTransition for the details.

Morph

SlideTransition.morph enables MorphElement matching for objects that should visually continue across two pages.

export const transition: SlideTransition = {
  duration: 600,
  morph: {
    duration: 600,
    easing: 'cubic-bezier(0.22, 1, 0.36, 1)',
  },
};

For the full schema and a reusable family of examples, see SlideTransition.

On this page