跳至主要内容

运行时

svelte/motion

在 GitHub 上编辑此页面

svelte/motion 模块导出了两个函数,tweenedspring,用于创建可写存储,其值在 setupdate 之后随时间变化,而不是立即变化。

tweened

ts
function tweened<T>(
value?: T | undefined,
defaults?: TweenedOptions<T> | undefined
): Tweened<T>;

补间存储在固定持续时间内更新其值。以下选项可用

  • delaynumber,默认值为 0)——开始前的毫秒数
  • durationnumber | function,默认值为 400)——补间持续的毫秒数
  • easingfunction,默认值为 t => t)——缓动函数
  • interpolatefunction)——见下文

store.setstore.update 可以接受第二个 options 参数,该参数将覆盖在实例化时传递的选项。

这两个函数都返回一个 Promise,该 Promise 在补间动画完成后解析。如果补间动画被中断,该 Promise 将永远不会解析。

开箱即用,Svelte 将在两个数字、两个数组或两个对象之间进行插值(只要数组和对象具有相同的“形状”,并且它们的“叶”属性也是数字)。

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

	const size = tweened(1, {
		duration: 300,
		easing: cubicOut
	});

	function handleClick() {
		// this is equivalent to size.update(n => n + 1)
		$size += 1;
	}
</script>

<button on:click={handleClick} style="transform: scale({$size}); transform-origin: 0 0">
	embiggen
</button>

如果初始值是 undefinednull,则第一个值更改将立即生效。当您具有基于道具的补间动画值并且不希望在组件首次渲染时有任何动作时,这非常有用。

ts
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
const size = tweened(undefined, {
duration: 300,
easing: cubicOut
});
$: $size = big ? 100 : 10;

interpolate 选项允许您在任何任意值之间进行补间动画。它必须是一个 (a, b) => t => value 函数,其中 a 是起始值,b 是目标值,t 是 0 到 1 之间的一个数字,value 是结果。例如,我们可以使用 d3-interpolate 包在两种颜色之间平滑插值。

<script>
	import { interpolateLab } from 'd3-interpolate';
	import { tweened } from 'svelte/motion';

	const colors = ['rgb(255, 62, 0)', 'rgb(64, 179, 255)', 'rgb(103, 103, 120)'];

	const color = tweened(colors[0], {
		duration: 800,
		interpolate: interpolateLab
	});
</script>

{#each colors as c}
	<button style="background-color: {c}; color: white; border: none;" on:click={(e) => color.set(c)}>
		{c}
	</button>
{/each}

<h1 style="color: {$color}">{$color}</h1>

弹簧

ts
function spring<T = any>(
value?: T | undefined,
opts?: SpringOpts | undefined
): Spring<T>;

spring 存储根据其 stiffnessdamping 参数逐渐更改为其目标值。而 tweened 存储在固定持续时间内更改其值,spring 存储在由其现有速度决定的持续时间内更改,在许多情况下允许更自然的运动。以下选项可用

  • stiffnessnumber,默认 0.15)——0 到 1 之间的值,其中较高意味着“更紧”的弹簧
  • dampingnumber,默认 0.8)——0 到 1 之间的值,其中较低意味着“更弹”的弹簧
  • precisionnumber,默认 0.01)——确定弹簧被认为“稳定”的阈值,其中较低意味着更精确

当弹簧运动时,上面所有选项都可以更改,并且会立即生效。

ts
import { spring } from 'svelte/motion';
const size = spring(100);
size.stiffness = 0.3;
size.damping = 0.4;
size.precision = 0.005;

tweened 存储一样,setupdate 返回一个 Promise,如果弹簧稳定,该 Promise 将解析。

setupdate 都可以接受第二个参数——一个具有 hardsoft 属性的对象。{ hard: true } 立即设置目标值;{ soft: n } 在稳定之前保留 n 秒的现有动量。{ soft: true } 等于 { soft: 0.5 }

ts
import { spring } from 'svelte/motion';
const coords = spring({ x: 50, y: 50 });
// updates the value immediately
coords.set({ x: 100, y: 200 }, { hard: true });
// preserves existing momentum for 1s
coords.update(
(target_coords, coords) => {
return { x: target_coords.x, y: coords.y };
},
{ soft: 1 }
);

请参阅弹簧教程中的完整示例。

<script>
	import { spring } from 'svelte/motion';

	const coords = spring(
		{ x: 50, y: 50 },
		{
			stiffness: 0.1,
			damping: 0.25
		}
	);
</script>

如果初始值是 undefinednull,则第一个值更改将立即生效,就像 tweened 值一样(见上文)。

ts
import { spring } from 'svelte/motion';
const size = spring();
$: $size = big ? 100 : 10;

类型

Spring

ts
interface Spring<T> extends Readable<T> {}
ts
set: (new_value: T, opts?: SpringUpdateOpts) => Promise<void>;
ts
update: (fn: Updater<T>, opts?: SpringUpdateOpts) => Promise<void>;
ts
precision: number;
ts
damping: number;
ts
stiffness: number;

Tweened

ts
interface Tweened<T> extends Readable<T> {}
ts
set(value: T, opts?: TweenedOptions<T>): Promise<void>;
ts
update(updater: Updater<T>, opts?: TweenedOptions<T>): Promise<void>;
上一个 svelte/store