Created
January 9, 2026 18:24
-
-
Save avin/bcd0e8fecebe0b80ee6dca82465e4da8 to your computer and use it in GitHub Desktop.
svelte WrappedUp transition
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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