javascript 纤细过渡:如何使传入的“in”动态细长组件转换等待传出的“out”细长组件完成

rsaldnfx  于 2023-02-28  发布在  Java
关注(0)|答案(4)|浏览(122)

实际上,我正在做一个幻灯片放映项目,其中每个"幻灯片"都是使用<svelte:component this={currentSelection.component} />动态加载的。每个幻灯片都需要基于组件的自定义进出过渡。我希望下一张幻灯片"等待"当前幻灯片完成过渡,但是,正如svelte文档中所述:
与转场:不同,应用于in:的转场和出:不是双向的-**入转换将继续在出转换旁边"播放",而不是反转,如果在转换过程中块被超越。如果出转换被中止,转换将从头开始。
有没有一种明智的方法可以让下一张幻灯片"等待"到当前幻灯片完成其结束过渡?
REPL上的玩具示例
玩具代码张贴为子孙后代:

//App.svelte
<script>
    import RedThing from './RedThing.svelte';
    import GreenThing from './GreenThing.svelte';
    import BlueThing from './BlueThing.svelte';

    const slides = [
            RedThing,
            BlueThing,
            GreenThing
    ];
    let currentComponent = 0;
    const prev = () => currentComponent--;
    const next = () => currentComponent++;

</script>

<button on:click={prev}>Prev</button><button on:click={next}>Next</button>
<div>
    <svelte:component this={slides[currentComponent]}/>
</div>
//RedThing.svelte
<script>
    import { fly, slide } from 'svelte/transition';
</script>

<style>
    div { color: red; }
</style>

<div in:fly out:slide>red thing</div>
//GreenThing.svelte
<script>
    import { fade, slide } from 'svelte/transition';
</script>

<style>
    div { color: green; }
</style>

<div in:slide out:fade>green thing</div>
//BlueThing.svelte
<script>
    import { scale, fade } from 'svelte/transition';

</script>

<style>
    div { color: blue; }
</style>

<div in:scale out:fade>blue thing</div>

编辑:我应该添加一个复杂因素--我正在通过sapper anchor标记驱动组件遍历,这些标记负责组件的创建/销毁。换句话说:

<a href={prev} id="previous-button">Previous</a>
<a href={next} id="next-button">Next</a>

<div>
    <svelte:component this={slides[currentComponent]}/>
</div>

我不知道这有什么区别?

r6l8ljro

r6l8ljro1#

我知道这个线程是几个月前,这里是一个简单的解决方案。我也有这个问题。秘密?延迟参数:
REPL

// RedThing.svelte
<script>
    import { fly, slide } from 'svelte/transition';
</script>

<style>
    div { color: red; }
</style>

<div in:fly="{{delay: 300, duration: 300}}" out:slide="{{duration: 300}}">red thing</div>
// GreenThing.svelte
<script>
    import { fade, slide } from 'svelte/transition';
</script>

<style>
    div { color: green; }
</style>

<div in:slide="{{delay: 300, duration: 300}}" out:fade="{{duration: 300}}">green thing</div>
// BlueThing.svelte
<script>
    import { scale, fade } from 'svelte/transition';
</script>

<style>
    div { background-color: blue; }
</style>

<div in:scale="{{delay: 300, duration: 300}}" out:fade="{{duration: 300}}">blue thing</div>
ecr0jaav

ecr0jaav2#

我已经找到了一个半可行的解决方案,通过添加position: absolute;到每个动态组件的容器。这是因为转换在销毁它之前会将传入组件作为旧组件的兄弟组件附加到dom。通过使位置绝对化,传出和传入组件占据相同的位置。稍微进行一些淡入淡出调整会使它看起来 * ok *。这不是一个理想的解决方案。但这可能足够了。
示例:

//RedThing.svelte
<script>
    import { fly, slide } from 'svelte/transition';
</script>

<style>
    div { color: red; }
</style>
<div style="position:absolute;" transition:fade={{duration: tweaky}}>
    <div in:fly out:slide >red thing</div>
</div>
//GreenThing.svelte
<script>
    import { fade, slide } from 'svelte/transition';
</script>

<style>
    div { color: green; }
</style>
<div style="position:absolute;" transition:fade={{duration: tweaky}}>
    <div in:slide out:fade >green thing</div>
</div>

受此解决方案启发/借鉴,在页面之间创建sapper交叉渐变:https://dev.to/buhrmi/svelte-component-transitions-5ie

nhn9ugyo

nhn9ugyo3#

这假定所有过渡的持续时间一致。添加了与每个幻灯片组件中的结尾持续时间匹配的介绍延迟。如果您希望每个幻灯片过渡具有不同的持续时间,则可能需要跟踪并匹配它们(可能在存储中)。

<script>
    import { scale, fade } from 'svelte/transition';
</script>

<style>
    div { background-color: blue; }
</style>

<div in:scale={{duration: 500, delay: 500}} 
     out:fade={{duration: 500}}
     >
     blue thing
     </div>
vmdwslir

vmdwslir4#

参加聚会有点晚了,但我觉得还是值得分享我想出的东西:)
开始,我使用了delay属性(由MaddEye建议),以确保传出元素的动画不会与传入元素的动画重叠。这是一个好的开始,但在这两个元素共存的那一刻,我经历了内容回流。这时我觉得fish的建议可能会派上用场。但我真的希望避免为每个元素设置一个position: absolute,因为这很容易导致不同类型的问题。
这时我想起还有另一种方法可以达到同样的效果,而没有position: absolute的缺点,即在父元素上设置display: grid,然后给子元素指定特定的值grid-columngrid-row,使它们最终处于相同的位置。在同一个网格区域。另外,由于grid布局,您甚至可以根据需要对齐它们:)
我将留给您一个demo REPL来更好地说明我的解释;)

相关问题