transition:
Переход инициируется элементом, который входит в DOM или покидает его в результате изменения состояния.
Когда блок (например, блок {#if ...}
) выходит, все элементы внутри него, включая те, которые не имеют собственных переходов, остаются в DOM до тех пор, пока все переходы в блоке не будут завершены.
Директива transition:
указывает на двунаправленный переход, что означает, что его можно плавно отменить, пока переход находится в процессе.
<script> import { fade } from 'svelte/transition';
let visible = $state(false);</script>
<button onclick={() => visible = !visible}>переключить</button>
{#if visible} <div transition:fade>плавно появляется и исчезает</div>{/if}
Локальные и глобальные
Заголовок раздела «Локальные и глобальные»Переходы по умолчанию являются локальными. Локальные переходы воспроизводятся только тогда, когда блок, к которому они принадлежат, создается или уничтожается, а не когда создаются или уничтожаются родительские блоки.
{#if x} {#if y} <p transition:fade>плавно появляется и исчезает только когда изменяется y</p>
<p transition:fade|global>плавно появляется и исчезает, когда изменяются x или y</p> {/if}{/if}
Встроенные переходы
Заголовок раздела «Встроенные переходы»Набор встроенных переходов можно импортировать из модуля svelte/transition
.
Параметры переходов
Заголовок раздела «Параметры переходов»Переходы могут иметь параметры.
(Двойные {{фигурные скобки}}
не являются специальным синтаксисом; это литерал объекта внутри тега выражения.)
{#if visible} <div transition:fade={{ duration: 2000 }}>плавно появляется и исчезает в течение двух секунд</div>{/if}
Пользовательские функции переходов
Заголовок раздела «Пользовательские функции переходов»transition = (node: HTMLElement, params: any, options: { direction: 'in' | 'out' | 'both' }) => { delay?: number, duration?: number, easing?: (t: number) => number, css?: (t: number, u: number) => string, tick?: (t: number, u: number) => void}
Переходы могут использовать пользовательские функции. Если возвращаемый объект имеет функцию css
, Svelte сгенерирует ключевые кадры для веб-анимации.
Аргумент t
, передаваемый в css
, — это значение между 0
и 1
после применения функции easing
. Входные переходы выполняются от 0
до 1
, исходящие переходы выполняются от 1
до 0
— другими словами, 1
соответствует естественному состоянию элемента, как будто переход не был применен. Аргумент u
равен 1 - t
.
Функция вызывается многократно до начала перехода с различными аргументами t
и u
.
<script> import { elasticOut } from 'svelte/easing';
/** @type {boolean} */ export let visible;
/** * @param {HTMLElement} node * @param {{ delay?: number, duration?: number, easing?: (t: number) => number }} params */ function whoosh(node, params) { const existingTransform = getComputedStyle(node).transform.replace('none', '');
return { delay: params.delay || 0, duration: params.duration || 400, easing: params.easing || elasticOut, css: (t, u) => `transform: ${existingTransform} scale(${t})` }; } </script>
{#if visible} <div in:whoosh>влетает с шумом</div> {/if}
<script lang="ts"> import { elasticOut } from 'svelte/easing';
export let visible: boolean;
function whoosh(node: HTMLElement, params: { delay?: number, duration?: number, easing?: (t: number) => number }) { const existingTransform = getComputedStyle(node).transform.replace('none', '');
return { delay: params.delay || 0, duration: params.duration || 400, easing: params.easing || elasticOut, css: (t, u) => `transform: ${existingTransform} scale(${t})` }; } </script>
{#if visible} <div in:whoosh>влетает с шумом</div> {/if}
Пользовательская функция перехода также может возвращать функцию tick
, которая вызывается в процессе перехода с теми же аргументами t
и u
.
<script> export let visible = false;
/** * @param {HTMLElement} node * @param {{ speed?: number }} params */ function typewriter(node, { speed = 1 }) { const valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;
if (!valid) { throw new Error(`Этот переход работает только с элементами, имеющими единственный дочерний текстовый узел`); }
const text = node.textContent; const duration = text.length / (speed * 0.01);
return { duration, tick: (t) => { const i = ~~(text.length * t); node.textContent = text.slice(0, i); } }; }</script>
{#if visible} <p in:typewriter={{ speed: 1 }}>Быстрая коричневая лиса прыгает через ленивую собаку</p>{/if}
<script lang="ts"> export let visible = false;
function typewriter(node: HTMLElement, { speed = 1 }: { speed?: number }) { const valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;
if (!valid) { throw new Error(`Этот переход работает только с элементами, имеющими единственный дочерний текстовый узел`); }
const text = node.textContent; const duration = text.length / (speed * 0.01);
return { duration, tick: (t) => { const i = ~~(text.length * t); node.textContent = text.slice(0, i); } }; } </script>
{#if visible} <p in:typewriter={{ speed: 1 }}>Быстрая коричневая лиса прыгает через ленивую собаку</p> {/if}
Если переход возвращает функцию вместо объекта перехода, функция будет вызвана в следующей микрозадаче. Это позволяет нескольким переходам координироваться, что делает возможными эффекты перекрёстного затухания.
Функции перехода также получают третий аргумент, options
, который содержит информацию о переходе.
Доступные значения в объекте options
:
direction
- одно из значенийin
,out
илиboth
в зависимости от типа перехода
События переходов
Заголовок раздела «События переходов»Элемент с переходами будет генерировать следующие события в дополнение к любым стандартным событиям DOM:
introstart
introend
outrostart
outroend
{#if visible} <p transition:fly={{ y: 200, duration: 2000 }} onintrostart={() => (status = 'intro started')} onoutrostart={() => (status = 'outro started')} onintroend={() => (status = 'intro ended')} onoutroend={() => (status = 'outro ended')} > влетает и вылетает </p>{/if}