跳至主要内容

动画

带键的 each 块的内容重新排序时,会触发动画。当添加或删除元素时,动画不会运行,只有当 each 块中现有数据项的索引发生变化时,动画才会运行。动画指令必须位于作为带键的 each 块的直接子元素的元素上。

动画可以与 Svelte 的内置动画函数自定义动画函数一起使用。

<!-- When `list` is reordered the animation will run -->
{#each list as item, index (item)}
	<li animate:flip>{item}</li>
{/each}

动画参数

与操作和过渡一样,动画也可以具有参数。

(双 {{curlies}} 不是特殊语法;这是表达式标签内的对象字面量。)

{#each list as item, index (item)}
	<li animate:flip={{ delay: 500 }}>{item}</li>
{/each}

自定义动画函数

animation = (node: HTMLElementnode: HTMLElement, { from: anyfrom: type DOMRect: anyDOMRect, to: anyto: type DOMRect: anyDOMRect } , params: anyparams: any) => {
	delay?: number,
	duration?: number,
	easing?: (t: numbert: number) => number,
	css?: (t: numbert: number, u: numberu: number) => string,
	tick?: (t: numbert: number, u: numberu: number) => void
}

动画可以使用自定义函数,这些函数将 nodeanimation 对象和任何 parameters 作为参数。animation 参数是一个包含 fromto 属性的对象,每个属性都包含一个DOMRect,描述元素在其开始结束位置的几何形状。from 属性是元素在其起始位置的 DOMRect,to 属性是列表重新排序且 DOM 更新后元素在其最终位置的 DOMRect。

如果返回的对象具有 css 方法,则 Svelte 将创建一个网络动画,该动画将在元素上播放。

传递给 csst 参数是一个在应用 easing 函数后从 01 的值。u 参数等于 1 - t

在动画开始之前,该函数会重复调用多次,并使用不同的 tu 参数。

应用程序
<script>
	import { cubicOut } from 'svelte/easing';

	/**
	 * @param {HTMLElement} node
	 * @param {{ from: DOMRect; to: DOMRect }} states
	 * @param {any} params
	 */
	function whizz(node, { from, to }, params) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			css: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px) rotate(${t * 360}deg);`
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}
<script lang="ts">
	import { cubicOut } from 'svelte/easing';

	function whizz(node: HTMLElement, { from, to }: { from: DOMRect; to: DOMRect }, params: any) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			css: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px) rotate(${t * 360}deg);`
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}

自定义动画函数还可以返回一个 tick 函数,该函数在动画期间使用相同的 tu 参数调用。

如果可以使用 css 而不是 tick,请这样做 - 网络动画可以在主线程之外运行,从而防止较慢设备上的卡顿。

应用程序
<script>
	import { cubicOut } from 'svelte/easing';

	/**
	 * @param {HTMLElement} node
	 * @param {{ from: DOMRect; to: DOMRect }} states
	 * @param {any} params
	 */
	function whizz(node, { from, to }, params) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			tick: (t, u) => Object.assign(node.style, { color: t > 0.5 ? 'Pink' : 'Blue' })
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}
<script lang="ts">
	import { cubicOut } from 'svelte/easing';

	function whizz(node: HTMLElement, { from, to }: { from: DOMRect; to: DOMRect }, params: any) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			tick: (t, u) => Object.assign(node.style, { color: t > 0.5 ? 'Pink' : 'Blue' })
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}

在 GitHub 上编辑此页面

上一页 下一页