Skip to main content

animate:

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

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

<!-- 当 `list` 重新排序时动画将会运行 -->
{#each list as item, index (item)}
	<li animate:flip>{item}</li>
{/each}

动画参数

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

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

{#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 将创建一个在元素上播放的web 动画

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

该函数会在动画开始之前被反复调用,并传入不同的 tu 参数。

App
<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,那就尽可能使用 css — web 动画可以在主线程之外运行,防止在较慢的设备上出现卡顿。

App
<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 编辑此页面

上一页 下一页