Advanced Transitions

Back

Loading concept...

🎭 Svelte Advanced Transitions: The Magic Show

Imagine you’re a magician. You don’t just make things disappear—you make them dance, swap places, and tell the audience exactly when the trick starts and ends. That’s what advanced transitions in Svelte let you do!


🌟 The Big Picture

Svelte has built-in transitions like fade and slide. But what if you want something totally unique? What if you want two things to swap places smoothly? What if you need to know exactly when an animation starts or finishes?

That’s where Advanced Transitions come in:

Power What It Does
Custom Transitions Build your own magic tricks
Crossfade Make items swap places beautifully
Transition Events Know when animations start/end

🎨 Custom Transitions: Build Your Own Magic

What Is It?

Think of built-in transitions as toys from a store. Custom transitions are like building your own toy from scratch. You decide everything!

The Simple Recipe

A custom transition is just a function that returns an object with instructions:

<script>
function myMagic(node, params) {
  return {
    delay: 0,
    duration: 400,
    css: (t) => `opacity: ${t}`
  };
}
</script>

<div transition:myMagic>
  I appear with custom magic!
</div>

Breaking It Down

Part What It Means
node The HTML element getting animated
params Extra settings you can pass in
delay Wait before starting (milliseconds)
duration How long the animation takes
css A function that returns CSS styles
t Goes from 0 → 1 (entering) or 1 → 0 (leaving)

🎯 Real Example: Spin & Grow

Let’s make an element spin while it appears:

<script>
function spinIn(node, { duration = 500 }) {
  return {
    duration,
    css: (t) => `
      transform: rotate(${t * 360}deg)
                 scale(${t});
      opacity: ${t};
    `
  };
}

let visible = true;
</script>

<button on:click={() => visible = !visible}>
  Toggle
</button>

{#if visible}
  <div transition:spinIn={{ duration: 800 }}>
    🌟 I spin into existence!
  </div>
{/if}

🔧 Using the tick Function

For complex animations, you might use tick instead of css:

<script>
function typewriter(node, { speed = 50 }) {
  const text = node.textContent;
  const len = text.length;

  return {
    duration: len * speed,
    tick: (t) => {
      const i = Math.floor(len * t);
      node.textContent = text.slice(0, i);
    }
  };
}
</script>

{#if show}
  <p transition:typewriter>
    Hello, I type letter by letter!
  </p>
{/if}

Pro Tip: Use css when possible—it’s faster! Use tick only when you need JavaScript control.


🔄 Crossfade: The Swap Dance

What Is It?

Imagine you have a to-do list. When you move an item from “To Do” to “Done”, wouldn’t it be cool if it flew smoothly from one list to the other?

That’s crossfade! It makes elements look like they’re traveling between locations.

How It Works

graph TD A["Item in List A"] -->|Crossfade| B["Same Item in List B"] C["Position A"] -->|Smooth Animation| D["Position B"]

The Magic Setup

<script>
import { crossfade } from 'svelte/transition';
import { quintOut } from 'svelte/easing';

const [send, receive] = crossfade({
  duration: 400,
  easing: quintOut
});

let todos = [
  { id: 1, text: 'Learn Svelte', done: false },
  { id: 2, text: 'Build app', done: false }
];

function toggle(id) {
  todos = todos.map(t =>
    t.id === id ? {...t, done: !t.done} : t
  );
}
</script>

Using Send & Receive

<div class="lists">
  <div class="todo">
    <h2>To Do</h2>
    {#each todos.filter(t => !t.done) as todo (todo.id)}
      <div
        in:receive={{ key: todo.id }}
        out:send={{ key: todo.id }}
        on:click={() => toggle(todo.id)}
      >
        {todo.text}
      </div>
    {/each}
  </div>

  <div class="done">
    <h2>Done</h2>
    {#each todos.filter(t => t.done) as todo (todo.id)}
      <div
        in:receive={{ key: todo.id }}
        out:send={{ key: todo.id }}
        on:click={() => toggle(todo.id)}
      >
        {todo.text}
      </div>
    {/each}
  </div>
</div>

🔑 The Key Concept

The key links items together:

Directive When Used What Happens
out:send Item leaves Remembers position
in:receive Item arrives Animates from old position

Both use the same key so Svelte knows they’re the same item!

Crossfade Options

const [send, receive] = crossfade({
  duration: 400,        // Animation time
  delay: 0,             // Wait before starting
  easing: quintOut,     // How motion feels
  fallback: fade        // What to do if no match
});

Fallback Magic: If an item has no matching partner (like when first appearing), the fallback transition plays instead!


📣 Transition Events: The Announcer

What Are They?

Sometimes you need to know:

  • “Hey, the animation just started!”
  • “The animation is now done!”

Transition events are like having an announcer that tells you exactly what’s happening.

The Four Events

graph LR A["introstart"] --> B["introend"] C["outrostart"] --> D["outroend"]
Event When It Fires
introstart Element starts appearing
introend Element finished appearing
outrostart Element starts leaving
outroend Element finished leaving

How To Listen

<script>
import { fade } from 'svelte/transition';

let visible = true;
let status = 'Ready';

function handleIntroStart() {
  status = '✨ Appearing...';
}

function handleIntroEnd() {
  status = '🎉 Fully visible!';
}

function handleOutroStart() {
  status = '👋 Leaving...';
}

function handleOutroEnd() {
  status = '💨 Gone!';
}
</script>

<p>Status: {status}</p>

<button on:click={() => visible = !visible}>
  Toggle
</button>

{#if visible}
  <div
    transition:fade
    on:introstart={handleIntroStart}
    on:introend={handleIntroEnd}
    on:outrostart={handleOutroStart}
    on:outroend={handleOutroEnd}
  >
    Watch me animate!
  </div>
{/if}

🎯 Real World Uses

1. Disable buttons during animation:

<script>
let visible = true;
let animating = false;
</script>

<button
  disabled={animating}
  on:click={() => visible = !visible}
>
  {animating ? 'Wait...' : 'Toggle'}
</button>

{#if visible}
  <div
    transition:fade
    on:introstart={() => animating = true}
    on:introend={() => animating = false}
    on:outrostart={() => animating = true}
    on:outroend={() => animating = false}
  >
    Content
  </div>
{/if}

2. Chain animations:

<script>
let step = 1;
</script>

{#if step === 1}
  <div
    transition:fade
    on:outroend={() => step = 2}
  >
    Step 1: I go first
  </div>
{:else}
  <div transition:fade>
    Step 2: Now I appear!
  </div>
{/if}

3. Play sounds or effects:

<div
  transition:fly={{ y: 100 }}
  on:introend={() => playSound('whoosh')}
>
  🚀 Rocket launches with sound!
</div>

🎁 Putting It All Together

Here’s a complete example using all three concepts:

<script>
import { crossfade } from 'svelte/transition';

// Custom elastic transition
function elastic(node, { duration = 400 }) {
  return {
    duration,
    css: (t) => {
      const bounce = Math.sin(t * Math.PI * 3)
                     * (1 - t);
      return `transform: scale(${t + bounce * 0.3})`;
    }
  };
}

// Crossfade setup
const [send, receive] = crossfade({
  duration: 300,
  fallback: elastic
});

let items = [
  { id: 1, name: 'Apple', cart: false },
  { id: 2, name: 'Banana', cart: false }
];

let message = '';

function moveToCart(id) {
  items = items.map(i =>
    i.id === id ? {...i, cart: true} : i
  );
}
</script>

<p>{message}</p>

<div class="shop">
  <h3>Shop</h3>
  {#each items.filter(i => !i.cart) as item (item.id)}
    <button
      in:receive={{ key: item.id }}
      out:send={{ key: item.id }}
      on:click={() => moveToCart(item.id)}
      on:outrostart={() => message = 'Moving...'}
      on:outroend={() => message = 'In cart!'}
    >
      {item.name}
    </button>
  {/each}
</div>

<div class="cart">
  <h3>Cart</h3>
  {#each items.filter(i => i.cart) as item (item.id)}
    <span
      in:receive={{ key: item.id }}
      out:send={{ key: item.id }}
    >
      {item.name}
    </span>
  {/each}
</div>

🏆 Quick Reference

Feature What When To Use
Custom Transition Build your own animation Need unique effects
Crossfade Items swap places Moving items between lists
Transition Events Know when animations happen Chain effects, disable UI

🌈 You Did It!

You now know how to:

Create custom transitions with your own animations ✅ Use crossfade to make items fly between locations ✅ Listen to events to know when animations start and end

You’re not just using transitions anymore—you’re creating magic! ✨

“The best animations don’t just move things. They tell a story.”


Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.