如何构建你的第一个自定义 Svelte 过渡

Avatar of Austin Crim
Austin Crim

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费信用额度!

Svelte 的 transition API 提供了一种一流的方式来为组件进入或离开文档时设置动画,包括自定义 Svelte 过渡。默认情况下,transition 指令使用 CSS 动画,这通常提供更好的性能并允许浏览器的主线程保持畅通。API 非常简单:<element transition:transitionFunction />。您还可以指定 inout 指令,它们是单向过渡,仅在元素挂载 *或*卸载时运行。

An animated example of a custom Svelte transition showing a to do list. An item is typed and animated into the list of items when entered. Clicking a done button animates the item out of view.
一个正在工作的 Svelte 过渡示例(跳转到演示

Svelte 提供了一个运行时 svelte/transition 包,其中包含七个预打包的 Svelte 过渡函数,所有这些函数都可以直接使用并根据您的需要进行调整。将其与 svelte/easing 包结合使用,可以实现各种交互,而无需自己编写任何过渡代码。尝试使用 不同的过渡和缓动函数 来了解可能的应用。

正在寻找有关如何开始使用 Svelte 的说明?我们有一个 详细概述 供您查看。

Svelte 自定义过渡 API

如果您需要比 Svelte 过渡 API 默认提供的更多控制,Svelte 允许您指定自己的自定义过渡函数,只要您遵守一些约定即可。根据文档,以下是自定义过渡 API 的外观

transition = (node: HTMLElement, params: any) => {
  delay?: number,
  duration?: number,
  easing?: (t: number) => number,
  css?: (t: number, u: number) => string,
  tick?: (t: number, u: number) => void
} 

让我们分解一下。过渡函数接收对使用 transition 指令的 DOM 节点的引用,并返回一个包含一些控制动画参数的对象,最重要的是一个 csstick 函数。

css 函数的作用是返回一个描述动画的 CSS 字符串,通常包括某种变换或不透明度变化。或者,您可以选择返回一个 tick 函数,它允许您使用 JavaScript 的强大功能控制动画的各个方面,但会带来性能损失,因为这种类型的过渡不使用 CSS 动画。

csstick 函数都采用两个参数,按照惯例称为 (t, u)t 是一个从 0.001.00 的十进制数,当元素进入 DOM 时,它从 0.001.00,当元素离开时,它从 1.00 返回到 0.00u 参数是 t 的倒数或 1 - t 在任何给定时刻。例如,如果您返回一个 transform: scale(${t}) 的字符串,您的元素将在进入时从 0 平滑动画到 1,反之亦然。

这些概念可能看起来有点抽象,所以让我们通过构建我们自己的自定义 Svelte 过渡来巩固它们!

构建你的第一个自定义 Svelte 过渡

首先,让我们设置一些样板代码,以便我们使用 Svelte 的 #if 块切换 DOM 中元素的存在。请记住,Svelte 过渡仅在元素实际离开或进入 DOM 时运行。

<script>
  let showing = true
</script>

<label for="showing">
  Showing
</label>
<input id="showing" type="checkbox" bind:checked={showing} />

{#if showing}
  <h1>Hello custom transition!</h1>
{/if}

您应该能够切换复选框并看到我们的元素在原位突然出现和消失。

接下来,让我们设置我们的自定义 Svelte 过渡函数并将其连接到我们的元素。

<script>
  let showing = true
  // Custom transition function
  function whoosh(node) {
    console.log(node)
  }
</script>

<label for="showing">
  Showing
</label>
<input id="showing" type="checkbox" bind:checked={showing} />

{#if showing}
  <h1 transition:whoosh>Hello custom transition!</h1>
{/if}

现在,如果您切换复选框,您将看到 <h1> 元素被记录到控制台。这证明我们已正确连接了自定义过渡!在我们的示例中,我们实际上不会使用 DOM 节点,但通常可以访问该元素以引用其当前样式或尺寸。

为了让我们的元素进行任何动画,我们需要返回一个包含 css(或 tick)函数的对象。让我们让我们的 css 函数返回一行 CSS 来缩放我们的元素。我们还将返回一个 duration 属性来控制动画持续时间。

<script>
  function swoop() {
    return {
      duration: 1000,
      css: () => `transform: scale(.5)`
    }
  }
  let showing = true
</script>

<!-- markup -->

我们已经有一些动画了!您会注意到,当切换复选框时,我们的元素会直接跳到 .5 比例。这算是一个开始,但如果它能 *平滑* 过渡会感觉好得多。这就是 (t, u) 参数的用武之地。

<script>
  function swoop() {
    return {
      duration: 1000,
      css: (t) => `transform: scale(${t})`
    }
  }
  let showing = true
</script>

<!-- markup -->

现在我们说到点子上了!请记住,t 在元素进入时从 0.00 平滑滚动到 1.00,反之亦然。这使我们能够实现我们想要的平滑效果。事实上,我们刚刚编写的代码本质上就是 svelte/transition 包中内置的 scale 过渡。

让我们变得更花哨一点。为了不辜负我们自定义 Svelte 过渡的名称“swoop”,让我们向我们的 transform 添加一个 translateX,以便我们的元素从侧面缩放。

在继续之前,我想挑战您先尝试实现它。相信我,这会很有趣!假设我们希望在元素离开时将其平移到 100%,并在进入时将其平移回 0%。

[等待…]

结果如何?想比较一下答案吗?

这是我的结果

css: (t, u) => `transform: scale(${t}) translateX(${u * 100}%);`

如果您有不同的结果也没关系!让我分解一下我做了什么。

这里的关键是 css 函数中第二个参数的使用。如果我们在元素进入屏幕时考虑我们的动画,我们希望最终达到 scale(1) translateX(0%),因此我们不能对 scaletransform 都使用未经修改的 t。这就是 u 参数的便利之处——它是在任何给定时刻 t 的倒数,因此我们知道当 t1 时它将为 0!然后我将 u 乘以 100 以获取百分比值,并在末尾添加 % 符号。

学习 tu 之间的相互作用是 Svelte 中自定义过渡难题的重要部分。这两个参数为您的动画提供了无限的活力;它们可以被分割、相乘、扭曲或变形为满足您的任何需求。

让我们将我最喜欢的 svelte/easing 函数添加到我们的过渡中,然后结束。

<script>
  import { elasticOut } from 'svelte/easing'
  function swoop() {
    return {
      duration: 1000,
      easing: elasticOut,
      css: (t, u) => `transform: scale(${t}) translateX(${u * 100}%)`
    }
  }
  let showing = true
</script>

<label for="showing">
  Showing
</label>
<input id="showing" type="checkbox" bind:checked={showing} />

{#if showing}
  <h1 transition:swoop>Hello custom transition!</h1>
{/if}

总结

恭喜!您现在可以构建自定义 Svelte 过渡函数了。我们仅仅触及了可能的应用的皮毛,但我希望您感觉自己已经掌握了探索更深入的工具。我强烈建议您阅读 文档 并完成 官方教程 以获得更多熟悉程度。