动画
当带键的 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: HTMLElement
node: HTMLElement, { from: any
from: type DOMRect: any
DOMRect, to: any
to: type DOMRect: any
DOMRect } , params: any
params: any) => {
delay?: number,
duration?: number,
easing?: (t: number
t: number) => number,
css?: (t: number
t: number, u: number
u: number) => string,
tick?: (t: number
t: number, u: number
u: number) => void
}
动画可以使用自定义函数,这些函数将 node
、animation
对象和任何 parameters
作为参数。animation
参数是一个包含 from
和 to
属性的对象,每个属性都包含一个DOMRect,描述元素在其开始
和结束
位置的几何形状。from
属性是元素在其起始位置的 DOMRect,to
属性是列表重新排序且 DOM 更新后元素在其最终位置的 DOMRect。
如果返回的对象具有 css
方法,则 Svelte 将创建一个网络动画,该动画将在元素上播放。
传递给 css
的 t
参数是一个在应用 easing
函数后从 0
到 1
的值。u
参数等于 1 - t
。
在动画开始之前,该函数会重复调用多次,并使用不同的 t
和 u
参数。
应用程序
<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
函数,该函数在动画期间使用相同的 t
和 u
参数调用。
如果可以使用
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}