Kurs Svelte i SvelteKit · Moduł 9: Przejścia i animacje

Custom Transitions

2 min czytania ·
W tej lekcji4

Stwórz własne transitions:

Struktura custom transition

import { cubicOut } from 'svelte/easing';

function myTransition(node, params) {
  return {
    delay: params.delay || 0,
    duration: params.duration || 400,
    easing: params.easing || cubicOut,
    css: (t, u) => `
      transform: scale(${t});
      opacity: ${t};
    `
    // t: 0 -> 1 (in), 1 -> 0 (out)
    // u: 1 - t
  };
}

Przykład: Spin transition

<script>
  import { cubicOut } from 'svelte/easing';

  function spin(node, { duration = 500, times = 1 }) {
    return {
      duration,
      css: (t) => {
        const degrees = times * 360 * t;
        return `
          transform: rotate(${degrees}deg) scale(${t});
          opacity: ${t};
        `;
      }
    };
  }

  let visible = $state(true);
</script>

{#if visible}
  <div transition:spin={{ duration: 800, times: 2 }}>
    Spinning!
  </div>
{/if}

Transition z tick (dla JS animation)

function typewriter(node, { speed = 50 }) {
  const text = node.textContent;
  const duration = text.length * speed;

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

draw - Dla SVG

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

  let visible = $state(true);
</script>

<svg viewBox="0 0 100 100">
  {#if visible}
    <path
      transition:draw={{ duration: 1000 }}
      d="M10 10 L90 10 L90 90 L10 90 Z"
      fill="none"
      stroke="gold"
      stroke-width="2"
    />
  {/if}
</svg>
Kod do tej lekcji: App.svelte
<script>
  // in: i out: - osobne animacje wejścia/wyjścia
  import { fly, fade, scale } from 'svelte/transition';

  let items = $state([
    { id: 1, name: 'Ragnar' },
    { id: 2, name: 'Bjorn' },
    { id: 3, name: 'Ivar' }
  ]);

  let nextId = 4;

  function addItem() {
    const names = ['Ubbe', 'Sigurd', 'Hvitserk', 'Lagertha', 'Rollo'];
    const name = names[Math.floor(Math.random() * names.length)];
    items = [...items, { id: nextId++, name }];
  }

  function removeItem(id) {
    items = items.filter(i => i.id !== id);
  }
</script>

<main class="in-out-demo">
  <h1>in: vs out:</h1>
  <p class="subtitle">Różne animacje dla wejścia i wyjścia</p>

  <button onclick={addItem}>+ Dodaj wojownika</button>

  <div class="list">
    {#each items as item (item.id)}
      <div
        class="item"
        in:fly={{ x: -200, duration: 400 }}
        out:fade={{ duration: 200 }}
      >
        <span>{item.name}</span>
        <button onclick={() => removeItem(item.id)}>Usuń</button>
      </div>
    {/each}
  </div>

  <section class="code">
    <h2>Składnia</h2>
    <pre>
{"<div"}
  in:fly={"{"}{"{"} x: -200 {"}"}{"}"}
  out:fade
{">"}
  Różne animacje!
{"</div>"}
    </pre>
  </section>
</main>

<style>
  .in-out-demo {
    font-family: 'Georgia', serif;
    max-width: 400px;
    margin: 0 auto;
    padding: 2rem;
    background: #1a0a0a;
    color: #f7d5e8;
    min-height: 100vh;
  }

  h1 {
    color: #ff6b6b;
    text-align: center;
  }

  .subtitle {
    text-align: center;
    color: #a87ca8;
    margin-bottom: 1rem;
  }

  button {
    padding: 0.5rem 1rem;
    background: #3a1a2a;
    color: #f7d5e8;
    border: 1px solid #ff6b6b;
    border-radius: 4px;
    cursor: pointer;
  }

  .list {
    margin-top: 1rem;
  }

  .item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem;
    background: rgba(255, 107, 107, 0.1);
    border: 1px solid #ff6b6b;
    border-radius: 4px;
    margin-bottom: 0.5rem;
  }

  .item button {
    background: #8b0000;
    border-color: #8b0000;
    padding: 0.25rem 0.5rem;
  }

  .code {
    margin-top: 2rem;
    background: rgba(0,0,0,0.5);
    border-radius: 8px;
    padding: 1rem;
  }

  .code h2 {
    color: #ff6b6b;
    font-size: 1rem;
    margin-top: 0;
  }

  .code pre {
    font-size: 0.9rem;
    margin: 0;
  }
</style>

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Przydatne artykuły