Svelte基础
Svelte高阶
上下文API
特殊元素
接下来
SvelteKit基础
Shared modules
API routes
$app/state
Errors and redirects
Advanced SvelteKit
Page options
Link options
Advanced routing
Advanced loading
Environment variables
Conclusion
svelte/transition
模块提供了丰富的转场,小主可以拿来用。如果小主也想自己写一个可以参考fade
转场源码:
The
svelte/transition
module has a handful of built-in transitions, but it’s very easy to create your own. By way of example, this is the source of thefade
transition:
function fade(node, { delay = 0, duration = 400 }) {
const o = +getComputedStyle(node).opacity;
return {
delay,
duration,
css: (t) => `opacity: ${t * o}`
};
}
是不是似曾相识?!跟先前定义动作(action)的函数如出一辙啊!第一个参数也是应用到的Dom元素,第二个参数是包含所需配置信息的对象, 不过返回值可就有讲究了,是一个可以包含以下属性的转场对象:
delay
—— 转场开始前需要延迟多少毫秒duration
—— 转场持续的毫秒数easing
—— 缓动函数 可以访问tweening了解更多css
—— 设置CSS的函数(t, u) => css
其中u === 1 - t
tick
—— 调整函数(t, u) => {...}
用于对Dom元素进行修改 在转入开始和转出结束的时候t的值为0, 在转入结束和转出开始的时候t的值为1
The function takes two arguments — the node to which the transition is applied, and any parameters that were passed in — and returns a transition object which can have the following properties:
delay
— milliseconds before the transition beginsduration
— length of the transition in millisecondseasing
— ap => t
easing function (see the chapter on tweening)css
— a(t, u) => css
function, whereu === 1 - t
tick
— a(t, u) => {...}
function that has some effect on the node Thet
value is0
at the beginning of an intro or the end of an outro, and1
at the end of an intro or beginning of an outro.
大多数情况下,小主应该返回“css”属性而不要返回“tick”属性,因为 CSS 动画会脱离主线程运行,以尽可能避免出现卡顿现象。Svelte 会模拟转场过程并构建 CSS 动画,然后让其运行。
比如fade
转场会生成这样的css动画:
Most of the time you should return the
css
property and not thetick
property, as CSS animations run off the main thread to prevent jank where possible. Svelte ‘simulates’ the transition and constructs a CSS animation, then lets it run. For example, thefade
transition generates a CSS animation somewhat like this:
0% { opacity: 0 }
10% { opacity: 0.1 }
20% { opacity: 0.2 }
/* ... */
100% { opacity: 1 }
当然我们还能再有创意点。让我们做点没什么用的: We can get a lot more creative though. Let’s make something truly gratuitous:
<script>
import { fade } from 'svelte/transition';
import { elasticOut } from 'svelte/easing';
let visible = $state(true);
function spin(node, { duration }) {
return {
duration,
css: (t, u) => {
const eased = elasticOut(t);
return `
transform: scale(${eased}) rotate(${eased * 1080}deg);
color: hsl(
${Math.trunc(t * 360)},
${Math.min(100, 1000 * u)}%,
${Math.min(50, 500 * u)}%
);`
}
};
}
</script>
<script lang="ts">
import { fade } from 'svelte/transition';
import { elasticOut } from 'svelte/easing';
let visible = $state(true);
function spin(node, { duration }) {
return {
duration,
css: (t, u) => {
const eased = elasticOut(t);
return `
transform: scale(${eased}) rotate(${eased * 1080}deg);
color: hsl(
${Math.trunc(t * 360)},
${Math.min(100, 1000 * u)}%,
${Math.min(50, 500 * u)}%
);`
}
};
}
</script>
小主能力越大责任就越大哦! 我看好你哦!
Remember: with great power comes great responsibility.
<script>
import { fade } from 'svelte/transition';
let visible = $state(true);
function spin(node, { duration }) {
return {
duration,
css: (t, u) => ``
};
}
</script>
<label>
<input type="checkbox" bind:checked={visible} />
visible
</label>
{#if visible}
<div
class="centered"
in:spin={{ duration: 8000 }}
out:fade
>
<span>transitions!</span>
</div>
{/if}
<style>
.centered {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
span {
position: absolute;
transform: translate(-50%, -50%);
font-size: 4em;
}
</style>