4

本质上,我正在制作一个幻灯片项目,其中每个“幻灯片”都是使用 <svelte:component this={currentSelection.component} />. 每张幻灯片都需要逐个组件的自定义输入和输出转换。我希望下一张幻灯片在当前幻灯片完成转换时“等待”,但是,如 svelte 文档中所述:

与 transition: 不同,使用 in: 和 out: 应用的转换不是双向的——如果在转换进行时块被淘汰,则in 转换将继续与 out 转换一起“播放”,而不是反转。如果退出转换被中止,转换将从头开始。

有没有一种明智的方法可以让下一张幻灯片“等待”直到当前幻灯片完成其结尾过渡?

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 锚标记驱动组件遍历,这些锚标记负责组件的创建/销毁。换句话说:

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

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

我不确定这是否有区别?

4

3 回答 3

3

我知道这个线程已经有几个月了,这是一个简单的解决方案。我也有这个问题。秘诀?延迟参数:

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>

于 2020-03-04T14:26:26.917 回答
1

position: absolute;通过添加到每个动态组件的容器中,我找到了一个半可行的解决方案。这是有效的,因为转换将传入组件附加到 dom 作为旧组件的兄弟,然后再销毁它。通过使位置为绝对,传出和传入组件位于相同的位置。一点淡入淡出调整使它看起来不错。这不是一个理想的解决方案,但它可能就足够了。

例子:

//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

于 2020-01-28T16:35:50.097 回答
0

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

<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>
于 2022-01-21T18:48:40.963 回答