transition:fn

  1. transition:fn
  1. transition:fn={params}
  1. transition:fn|local
  1. transition:fn|local={params}
  1. transition = (node: HTMLElement, params: any) => {
  2. delay?: number,
  3. duration?: number,
  4. easing?: (t: number) => number,
  5. css?: (t: number, u: number) => string,
  6. tick?: (t: number, u: number) => void
  7. }

transition 是在元素的状态变更的时候触发的,如元素的进入和离开。

在正在离开的块中的元素会一直在 DOM 中,直到所有的过渡动画执行完成。

  1. {#if visible}
  2. <div transition:fade>
  3. fades in and out
  4. </div>
  5. {/if}

transition: 表明是一个双向的过渡,意思是在变化的执行过程中平滑的来回切换执行方向。

  1. > 默认情况下,过渡动画在首次渲染的时候不会执行,你可以在[创建组件](https://svelte.dev/docs#Client-side_component_API)的时候,通过定义 `intro: true` 来修改默认行为。
  2. #### <p id="Transition参数">Transition参数</p>
  3. `Actions` 一样,`transition` 也可自定义参数。
  4. ```html
  5. {#if visible}
  6. <div transition:fade="{{ duration: 2000 }}">
  7. flies in, fades out over two seconds
  8. </div>
  9. {/if}

{{curlies}} 这种双大括号并不是什么特殊的语法,只是一个在表达式标签中包含一个对象字面量。

自定义transition函数

Transitions 支持自定义过渡函数,如果返回的对象有 css 的函数,Svelte 会在这个元素上创建并播放 css 动画。

  1. <script>
  2. import { elasticOut } from 'svelte/easing';
  3. export let visible;
  4. function whoosh(node, params) {
  5. const existingTransform = getComputedStyle(node).transform.replace('none', '');
  6. return {
  7. delay: params.delay || 0,
  8. duration: params.duration || 400,
  9. easing: params.easing || elasticOut,
  10. css: (t, u) => `transform: ${existingTransform} scale(${t})`
  11. };
  12. }
  13. </script>
  14. {#if visible}
  15. <div in:whoosh>
  16. whooshes in
  17. </div>
  18. {/if}

easing 函数执行完成之后,会传入 css 函数 10 的参数 t 。在进入动画中,是从 0 变化到 1 ,在离开动画中,是从 1 变化到 0 -换句话说,1 表示元素的初始状态,就好像没有发生过变化。参数 u 等同于 1-t

在过渡开始之前,函数被不同的参数 tu 反复调用。

自定义的过渡函数,也可以返回一个tick函数,该函数在过渡变化的过程中同样会以参数 tu 被调用。

  1. <script>
  2. export let visible = false;
  3. function typewriter(node, { speed = 50 }) {
  4. const valid = (
  5. node.childNodes.length === 1 &&
  6. node.childNodes[0].nodeType === 3
  7. );
  8. if (!valid) return {};
  9. const text = node.textContent;
  10. const duration = text.length * speed;
  11. return {
  12. duration,
  13. tick: (t, u) => {
  14. const i = ~~(text.length * t);
  15. node.textContent = text.slice(0, i);
  16. }
  17. };
  18. }
  19. </script>
  20. {#if visible}
  21. <p in:typewriter="{{ speed: 20 }}">
  22. The quick brown fox jumps over the lazy dog
  23. </p>
  24. {/if}

尽可能的使用 css 而不是 tick 函数-因为css的动画就会在主线程上运行,这样可以防止在性能差的设备上卡顿。

transition 如果返回了一个函数,而不是 transition 对象,那么这个函数会在下一个微任务被调用。这样就支持多个 transition 同时进行,这也是为什么可以实现交叉淡入的效果。

Transition事件

一个定义了 transition 的元素,除了会调用标准的 DOM 事件,还会调用以下这些事件:

  • introstart
  • introend
  • outrostart
  • outroend
  1. {#if visible}
  2. <p
  3. transition:fly="{{ y: 200, duration: 2000 }}"
  4. on:introstart="{() => status = 'intro started'}"
  5. on:outrostart="{() => status = 'outro started'}"
  6. on:introend="{() => status = 'intro ended'}"
  7. on:outroend="{() => status = 'outro ended'}"
  8. >
  9. Flies in and out
  10. </p>
  11. {/if}

local transition 只会在其所属块的创建或销毁的时候播放,而不是在其父级块的创建或销毁的时候。

  1. {#if x}
  2. {#if y}
  3. <p transition:fade>
  4. fades in and out when x or y change
  5. </p>
  6. <p transition:fade|local>
  7. fades in and out only when y changes
  8. </p>
  9. {/if}
  10. {/if}