Skip to content

Instantly share code, notes, and snippets.

@avin
Created January 9, 2026 18:24
Show Gist options
  • Select an option

  • Save avin/bcd0e8fecebe0b80ee6dca82465e4da8 to your computer and use it in GitHub Desktop.

Select an option

Save avin/bcd0e8fecebe0b80ee6dca82465e4da8 to your computer and use it in GitHub Desktop.
svelte WrappedUp transition
<script lang="ts">
import { linear } from "svelte/easing";
import type { TransitionConfig } from "svelte/transition";
let visible = $state(true);
function slideFade(
node: Element,
options: { duration?: number; easing?: (t: number) => number } = {},
): TransitionConfig {
const { duration = 300, easing = linear } = options;
if (!(node instanceof HTMLElement) || !node.isConnected) {
return { duration, easing };
}
// Получаем начальные значения синхронно
let opacity = 1;
let height = 0;
let paddingTop = 0;
let paddingBottom = 0;
let marginTop = 0;
let marginBottom = 0;
try {
const style = window.getComputedStyle(node);
opacity = +style.opacity || 1;
height = node.offsetHeight;
paddingTop = parseFloat(style.paddingTop) || 0;
paddingBottom = parseFloat(style.paddingBottom) || 0;
marginTop = parseFloat(style.marginTop) || 0;
marginBottom = parseFloat(style.marginBottom) || 0;
} catch (e) {
// Если не удалось получить стили, используем значения по умолчанию
height = node.offsetHeight || 0;
}
return {
duration,
easing,
css: (t: number) => {
const eased = easing(t);
return `
opacity: ${eased * opacity};
height: ${eased * height}px;
padding-top: ${eased * paddingTop}px;
padding-bottom: ${eased * paddingBottom}px;
margin-top: ${eased * marginTop}px;
margin-bottom: ${eased * marginBottom}px;
overflow: hidden;
`.trim();
},
};
}
</script>
<label class="select-none">
<input type="checkbox" bind:checked={visible} />
visible
</label>
{#if visible}
<div class="mt-4 pb-8" transition:slideFade={{ duration: 500 }}>
<p>Flies in and out</p>
</div>
{/if}
<p>hello</p>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment