Перетёрли мы тут с Марком и вот такое получилось:
<script>
import { gsap } from "gsap";
let visible = false;
function animate(node, isChanged) {
const timeline = gsap.timeline();
timeline.to(node, {
duration: 4,
opacity: 1
});
return {
update(isChanged) {
if (timeline.reversed()) {
timeline.play();
} else {
timeline.reverse();
}
},
destroy() {
return new Promise((res, rej) => {
// анимация сокрытия - резолвим и уничтожаем
timeline.eventCallback("onComplete", reject);
// анимация показа - реджектим и запрещаем уничтожать
timeline.eventCallback("onReverseComplete", resolve);
});
}
};
}
</script>
<button on:click={() => visible = !visible}>Toggle</button>
{#if visible}
<div class="hidden" use:animate={visible}>content</div>
{/if}
<div>
Random text
</div>
<style>
.hidden {
opacity: 0;
}
</style>