Home/Docs/Custom JS Transitions
Transitions

Custom JS Transitions

When the effect can't be expressed as styles, return tick(t, u) instead of css — the same (node, params) => { delay?, duration?, easing?, tick?(t, u) } contract, but the function runs arbitrary JS each frame. t goes 0→1 on enter and 1→0 on leave; u is 1 - t.

Component.html
<script>
  const typewriter = (node, { speed = 1 } = {}) => {
    const text = node.textContent;
    const duration = text.length / (speed * 0.01);
    return {
      duration,
      tick: (t) => (node.textContent = text.slice(0, Math.trunc(text.length * t))),
    };
  };
</script>

<transition in="typewriter({ speed: 2 })"><p>Types itself out…</p></transition>
  • On leave the same tick runs in reverse (t 1→0), so the text deletes itself.
  • tick owns whatever it touches — olum doesn't restore it afterwards (unlike css, which is unwound automatically), so write it to land on the final state at t = 1 / t = 0.
  • The JSON-params rule applies here too: params can't carry functions — bake custom easings into the transition function or pass an easing name.