Skip to main content
Svelte基础
介绍
响应
属性Props
逻辑表达式
事件
绑定
Classes和样式
动作Actions
转场
Svelte高阶
响应式进阶
内容复用
动画
高级绑定
高级转场
上下文API
特殊元素
脚本模块
接下来
SvelteKit基础
介绍
路由
加载数据
Headers和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

通常使用 动画(motion) 展示数据变化是个不错的选择,因此贴心的Svelte提供了些类用于支持在UI上添加动画。
svelte/motion导入 Tween

Often, a good way to communicate that a value is changing is to use motion. Svelte ships classes for adding motion to your user interfaces. Import the Tween class from svelte/motion:

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

	let progress = $state(0);
</script>
<script lang="ts">
	import { Tween } from 'svelte/motion';

	let progress = $state(0);
</script>

progress定义为Tween:

Turn progress into an instance of Tween:

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

	let progress = new Tween(0);
</script>
<script lang="ts">
	import { Tween } from 'svelte/motion';

	let progress = new Tween(0);
</script>

Tween有一个可写的属性target和一个只读的属性current —— 就用它来更新<progress>元素:

The Tween class has a writable target property and a readonly current property — update the <progress> element...

<progress value={progress.current}></progress>

记得在事件处理器中更新target值:

...and each of the event handlers:

<button onclick={() => (progress.target = 0)}>
	0%
</button>

单击按钮就可以设置进度状态,动画效果看起来中规中矩,接下来添加个easing函数:

Clicking the buttons causes the progress bar to animate to its new value. It’s a bit robotic and unsatisfying though. We need to add an easing function:

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

	let progress = new Tween(0, {
		duration: 400,
		easing: cubicOut
	});
</script>
<script lang="ts">
	import { Tween } from 'svelte/motion';
	import { cubicOut } from 'svelte/easing';

	let progress = new Tween(0, {
		duration: 400,
		easing: cubicOut
	});
</script>

svelte/easing模块提供Penner渐变方程, 你也可以指定渐变函数p => t 其中pt都介于0到1 [!NOTE] The svelte/easing module contains the Penner easing equations, or you can supply your own p => t function where p and t are both values between 0 and 1.

Tween支持的配置项:

  • delay —— 插值动画开始前需要等待的毫秒数
  • duration —— 动画的持续时间(以毫秒为单位),或一个 (from, to) => milliseconds 函数,允许你(例如)为较大的值变化指定更长的动画时间
  • easing —— 一个 p => t 函数
  • interpolate —— 一个自定义的 (from, to) => t => value 函数,用于在任意值之间进行插值。默认情况下,Svelte 会在数字、日期以及形状相同的数组和对象(只要它们仅包含数字、日期或其他有效的数组和对象)之间进行插值。如果需要插值(例如)颜色字符串或变换矩阵,请提供自定义插值器

The full set of options available to Tween:

  • delay — milliseconds before the tween starts
  • duration — either the duration of the tween in milliseconds, or a (from, to) => milliseconds function allowing you to (e.g.) specify longer tweens for larger changes in value
  • easing — a p => t function
  • interpolate — a custom (from, to) => t => value function for interpolating between arbitrary values. By default, Svelte will interpolate between numbers, dates, and identically-shaped arrays and objects (as long as they only contain numbers and dates or other valid arrays and objects). If you want to interpolate (for example) colour strings or transformation matrices, supply a custom interpolator

如果需要在每次更新值时指定配置项可以使用 progress.set(value, options),而不是直接赋值给 progress.target,在这种情况下,options 将覆盖默认值。set方法的返回值是一个Promise, 动画结束的时候Promise也就完成了

You can also call progress.set(value, options) instead of assigning directly to progress.target, in which case options will override the defaults. The set method returns a promise that resolves when the tween completes.

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
<script>
	let progress = $state(0);
</script>
 
<progress value={progress}></progress>
 
<button onclick={() => (progress = 0)}>
	0%
</button>
 
<button onclick={() => (progress = 0.25)}>
	25%
</button>
 
<button onclick={() => (progress = 0.5)}>
	50%
</button>
 
<button onclick={() => (progress = 0.75)}>
	75%
</button>
 
<button onclick={() => (progress = 1)}>
	100%
</button>
 
<style>
	progress {
		display: block;
		width: 100%;
	}
</style>