如何在Svelte中实现支持垂直与水平方向的手风琴过渡动画?
实现支持垂直与水平方向的Svelte手风琴过渡效果
默认的slide过渡仅针对垂直方向(高度)执行动画,因此水平方向(宽度)不会呈现过渡效果。要实现双向支持,我们可以自定义一个过渡函数,根据指定方向动态处理高度或宽度的动画。
自定义双向slide过渡函数
创建一个支持方向参数的自定义过渡,默认值为vertical,根据方向选择动画的尺寸属性:
<script> import { cubicOut } from 'svelte/easing'; function slideBoth(node, { direction = 'vertical', duration = 300, easing = cubicOut }) { const isVertical = direction === 'vertical'; const property = isVertical ? 'height' : 'width'; const originalValue = getComputedStyle(node)[property]; return { duration, easing, css: t => `${property}: ${parseFloat(originalValue) * t}px` }; } let showVertical = false; let showHorizontal = false; </script>
完整使用示例
以下代码同时展示垂直和水平方向的手风琴过渡效果:
<main> <!-- 垂直手风琴 --> <div class="wrapper vertical"> <button on:click={() => showVertical = !showVertical}>切换垂直内容</button> {#if showVertical} <div transition:slideBoth={{ duration: 300 }}> 垂直隐藏内容 垂直隐藏内容 垂直隐藏内容 </div> {/if} </div> <!-- 水平手风琴 --> <div class="wrapper horizontal"> <button on:click={() => showHorizontal = !showHorizontal}>切换水平内容</button> {#if showHorizontal} <div transition:slideBoth={{ direction: 'horizontal', duration: 300 }}> 水平隐藏内容 水平隐藏内容 水平隐藏内容 </div> {/if} </div> </main> <style> .wrapper { border: 1px solid red; padding: 10px; margin: 10px; } .vertical { display: inline-block; } .horizontal { display: flex; align-items: center; gap: 10px; } .horizontal div { white-space: nowrap; } </style>
关键细节说明
slideBoth函数通过direction参数切换动画目标属性(高度/宽度)- 水平手风琴需设置容器为
flex布局,并给内容添加white-space: nowrap,确保宽度计算准确 - 可通过调整
duration(时长)和easing(缓动函数)参数自定义过渡体验
内容的提问来源于stack exchange,提问作者lemon
相关产品推荐
相关产品推荐

