如何在同一个可切换元素上使用两个苗条的过渡?
How to use two svelte transitions on the same togglable element?
我有一个想要 hide/show 的输入字段,并通过淡入淡出和滑动过渡来实现。我有两个我想出的例子,但都有它们的缺点,我想知道是否有更优雅的解决方案。
我只需要回答这两个问题中的一个,因为它们都可以解决我的问题。
问题 1:有没有办法为一个转换指令触发多个转换?
问题 2:如何添加一个 class 来触发一个普通的 css-transition after if 语句将元素放入 DOM?
示例 1
Svelte 不允许在同一元素上进行两次转换。因此,一种解决方案是嵌套两个元素,如下所示。有没有一种方法可以使用淡入淡出和滑动来编写自定义过渡 transition:myMultiTransition
?
{#if active === true}
<span transition:fade>
<span transition:slide>
<input type="text" />
</span>
</span>
{/if}
示例 2
在我的其他解决方案中,我只是使用正常的 css 转换来切换活动 class。这里的问题是 <input>
-field 永远不会离开 DOM。它的高度是 0px,但把它留在那里似乎是错误的。
如何使用 {#if active === true}
成功显示输入字段,然后添加触发过渡效果的 class? Svelte 似乎添加了 active-class 应该在元素进入 DOM.
之前触发转换
我尝试过使用 await tick()
、onMount
、beforeUpdate
的各种组合,但没有成功。
当使用 setTimeout 延迟添加 class 时,它可以工作 - 但我不喜欢这个解决方案,因为如果时间不准确,它可能会失败,我不希望在转换之前有延迟开始。
<span class:{active}>
<input type="text" />
</span>
<style>
.active {
// Normal transition: opacity 1s etc ...
}
</style>
REPL
https://svelte.dev/repl/89cb7d26d9484d0193b4bc6bf59518ef?version=3.38.3
您可以创建自己的过渡函数:
<script>
import { cubicOut } from 'svelte/easing';
let visibleDoubleElements = false;
function slidefade(node, params) {
const existingTransform = getComputedStyle(node).transform.replace('none', '');
return {
delay: params.delay || 0,
duration: params.duration || 400,
easing: params.easing || cubicOut,
css: (t, u) => `transform-origin: top left; transform: ${existingTransform} scaleY(${t}); opacity: ${t};`
};
}
</script>
<label>
<input type="checkbox" bind:checked={visibleDoubleElements}>
Svelte transition
</label>
{#if visibleDoubleElements === true}
<input transition:slidefade type="text" placeholder="Double elements" />
{/if}
回复:
https://svelte.dev/repl/da8880947eff4f32b740a8742d9f817e?version=3.38.3
坚持使用您已经提供的第一个解决方案可能是最简单的:为每个转换添加一个包装器。
如果您想重复使用特定的转换组合,那么编写您自己的转换组合可能是值得的。此时您可以尝试使用 Svelte 的实现:这是 Slide + Fade
的示例
function fadeSlide(node, options) {
const slideTrans = slide(node, options)
return {
duration: options.duration,
css: t => `
${slideTrans.css(t)}
opacity: ${t};
`
};
}
https://svelte.dev/repl/f5c42c6dc6774f29ad9350cd2dc2d299?version=3.38.3
通用解决方案(理论)
在 Svelte 中,转换本身不依赖于 CSS-转换。 Svelte 过渡仅提供每个过渡步骤的样式。因此,一个通用的解决方案是创建一个合并过渡,它采用 2..N 过渡函数并将来自各个过渡的样式放在一起。不幸的是,由于 CSS.
中的冲突情况,这并不总是微不足道的
例如结合两个过渡...一个不透明度应为 0,另一个目标不透明度为 0.5。问题是:输出应该是什么样的?如果预期为 0,则必须有一些逻辑将“不透明度:0;不透明度:0.5;”转换为到“不透明度:0;”。而且肯定还有更复杂的情况。
我有一个想要 hide/show 的输入字段,并通过淡入淡出和滑动过渡来实现。我有两个我想出的例子,但都有它们的缺点,我想知道是否有更优雅的解决方案。
我只需要回答这两个问题中的一个,因为它们都可以解决我的问题。
问题 1:有没有办法为一个转换指令触发多个转换?
问题 2:如何添加一个 class 来触发一个普通的 css-transition after if 语句将元素放入 DOM?
示例 1
Svelte 不允许在同一元素上进行两次转换。因此,一种解决方案是嵌套两个元素,如下所示。有没有一种方法可以使用淡入淡出和滑动来编写自定义过渡 transition:myMultiTransition
?
{#if active === true}
<span transition:fade>
<span transition:slide>
<input type="text" />
</span>
</span>
{/if}
示例 2
在我的其他解决方案中,我只是使用正常的 css 转换来切换活动 class。这里的问题是 <input>
-field 永远不会离开 DOM。它的高度是 0px,但把它留在那里似乎是错误的。
如何使用 {#if active === true}
成功显示输入字段,然后添加触发过渡效果的 class? Svelte 似乎添加了 active-class 应该在元素进入 DOM.
我尝试过使用 await tick()
、onMount
、beforeUpdate
的各种组合,但没有成功。
当使用 setTimeout 延迟添加 class 时,它可以工作 - 但我不喜欢这个解决方案,因为如果时间不准确,它可能会失败,我不希望在转换之前有延迟开始。
<span class:{active}>
<input type="text" />
</span>
<style>
.active {
// Normal transition: opacity 1s etc ...
}
</style>
REPL
https://svelte.dev/repl/89cb7d26d9484d0193b4bc6bf59518ef?version=3.38.3
您可以创建自己的过渡函数:
<script>
import { cubicOut } from 'svelte/easing';
let visibleDoubleElements = false;
function slidefade(node, params) {
const existingTransform = getComputedStyle(node).transform.replace('none', '');
return {
delay: params.delay || 0,
duration: params.duration || 400,
easing: params.easing || cubicOut,
css: (t, u) => `transform-origin: top left; transform: ${existingTransform} scaleY(${t}); opacity: ${t};`
};
}
</script>
<label>
<input type="checkbox" bind:checked={visibleDoubleElements}>
Svelte transition
</label>
{#if visibleDoubleElements === true}
<input transition:slidefade type="text" placeholder="Double elements" />
{/if}
回复: https://svelte.dev/repl/da8880947eff4f32b740a8742d9f817e?version=3.38.3
坚持使用您已经提供的第一个解决方案可能是最简单的:为每个转换添加一个包装器。
如果您想重复使用特定的转换组合,那么编写您自己的转换组合可能是值得的。此时您可以尝试使用 Svelte 的实现:这是 Slide + Fade
的示例function fadeSlide(node, options) {
const slideTrans = slide(node, options)
return {
duration: options.duration,
css: t => `
${slideTrans.css(t)}
opacity: ${t};
`
};
}
https://svelte.dev/repl/f5c42c6dc6774f29ad9350cd2dc2d299?version=3.38.3
通用解决方案(理论)
在 Svelte 中,转换本身不依赖于 CSS-转换。 Svelte 过渡仅提供每个过渡步骤的样式。因此,一个通用的解决方案是创建一个合并过渡,它采用 2..N 过渡函数并将来自各个过渡的样式放在一起。不幸的是,由于 CSS.
中的冲突情况,这并不总是微不足道的例如结合两个过渡...一个不透明度应为 0,另一个目标不透明度为 0.5。问题是:输出应该是什么样的?如果预期为 0,则必须有一些逻辑将“不透明度:0;不透明度:0.5;”转换为到“不透明度:0;”。而且肯定还有更复杂的情况。