Skip to main content
Basic Svelte
Introduction
Reactivity
Props
Logic
Events
Bindings
Classes and styles
Actions
Transitions
Advanced Svelte
Advanced reactivity
Reusing content
Motion
Advanced bindings
Advanced transitions
Context API
Special elements
<script module>
Next steps
Basic SvelteKit
Introduction
Routing
Loading data
Headers and cookies
Shared modules
Forms
API routes
$app/state
Errors and redirects
Advanced SvelteKit
Hooks
Page options
Link options
Advanced routing
Advanced loading
Environment variables
Conclusion

svelte/transition モジュールには便利なトランジションがいくつも組み込まれていますが、独自のトランジションを簡単に作成することができます。例として、これは fade トランジションのソースです。

function fade(node, { delay = 0, duration = 400 }) {
	const o = +getComputedStyle(node).opacity;

	return {
		delay,
		duration,
		css: (t) => `opacity: ${t * o}`
	};
}

この関数は、トランジションが適用されるノードと渡されたパラメータの2つの引数を取り、下記のプロパティをもつトランジションオブジェクトを返します。

  • delay — トランジション開始までのミリ秒
  • duration — ミリ秒単位でのトランジションの長さ
  • easingp => t イージング関数 ( tweening の章を参照)
  • cssu === 1 - t である (t, u) => css 関数
  • tick — ノードに何らかの影響を与える (t, u) => {...} 関数

t 値は、イントロの開始やアウトロの終了時点では 0 であり、イントロの終了やアウトロの開始時点では 1 となります。

ほとんどの場合、css プロパティを返すべきであり、tick プロパティを返すべきではありません。なぜなら、CSSアニメーションは、UIが遅くなるのを防ぐために、可能であれば、メインスレッドとは別に動作するからです。Svelte は、トランジションを「シミュレート」し、 CSS アニメーションを作成してから実行させます。

たとえば、fade トランジションは次のような CSS アニメーションを生成します。

0% { opacity: 0 }
10% { opacity: 0.1 }
20% { opacity: 0.2 }
/* ... */
100% { opacity: 1 }

しかし、もっと独創的なものを作れます。本当に余計なトランジションを作ってみましょう。

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

	let visible = $state(true);

	function spin(node, { duration }) {
		return {
			duration,
			css: (t, u) => {
				const eased = elasticOut(t);

				return `
					transform: scale(${eased}) rotate(${eased * 1080}deg);
					color: hsl(
						${Math.trunc(t * 360)},
						${Math.min(100, 1000 * u)}%,
						${Math.min(50, 500 * u)}%
					);`
			}
		};
	}
</script>
<script lang="ts">
	import { fade } from 'svelte/transition';
	import { elasticOut } from 'svelte/easing';

	let visible = $state(true);

	function spin(node, { duration }) {
		return {
			duration,
			css: (t, u) => {
				const eased = elasticOut(t);

				return `
					transform: scale(${eased}) rotate(${eased * 1080}deg);
					color: hsl(
						${Math.trunc(t * 360)},
						${Math.min(100, 1000 * u)}%,
						${Math.min(50, 500 * u)}%
					);`
			}
		};
	}
</script>

忘れないで、大いなる力には大きな責任が伴います。

Edit this page on GitHub

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<script>
	import { fade } from 'svelte/transition';
 
	let visible = $state(true);
 
	function spin(node, { duration }) {
		return {
			duration,
			css: (t, u) => ``
		};
	}
</script>
 
<label>
	<input type="checkbox" bind:checked={visible} />
	visible
</label>
 
{#if visible}
	<div
		class="centered"
		in:spin={{ duration: 8000 }}
		out:fade
	>
		<span>transitions!</span>
	</div>
{/if}
 
<style>
	.centered {
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
	}
 
	span {
		position: absolute;
		transform: translate(-50%, -50%);
		font-size: 4em;
	}
</style>