feat: page transitions

This commit is contained in:
not-nullptr 2024-11-16 13:27:57 +00:00
parent 4a4efcfde0
commit 84da07b1c0
2 changed files with 89 additions and 24 deletions

View File

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import "../app.scss"; import "../app.scss";
import { goto } from "$app/navigation"; import { afterNavigate, beforeNavigate, goto } from "$app/navigation";
import { blur, duration } from "$lib/animation"; import { blur, duration } from "$lib/animation";
import { quintOut } from "svelte/easing"; import { quintOut } from "svelte/easing";
import { files, theme } from "$lib/store/index.svelte"; import { files, theme } from "$lib/store/index.svelte";
@ -91,6 +91,22 @@
navbar?.addEventListener("mouseenter", mouseEnter); navbar?.addEventListener("mouseenter", mouseEnter);
navbar?.addEventListener("mouseleave", mouseLeave); navbar?.addEventListener("mouseleave", mouseLeave);
}); });
let goingLeft = $state(false);
beforeNavigate((e) => {
const oldIndex = items.findIndex((i) =>
i.activeMatch(e.from?.url.pathname || ""),
);
const newIndex = items.findIndex((i) =>
i.activeMatch(e.to?.url.pathname || ""),
);
if (newIndex < oldIndex) {
goingLeft = true;
} else {
goingLeft = false;
}
});
</script> </script>
<svelte:head> <svelte:head>
@ -154,25 +170,57 @@
blurMultiplier: 8, blurMultiplier: 8,
duration, duration,
easing: quintOut, easing: quintOut,
x: {
start: goingLeft ? -100 : 100,
end: 0,
},
y: {
start: 72,
end: 0,
},
origin: "top center",
}} }}
out:blur={{ out:blur={{
blurMultiplier: 8, blurMultiplier: 8,
duration, duration,
easing: quintOut, easing: quintOut,
x: {
start: 0,
end: goingLeft ? 100 : -100,
},
y: {
start: 0,
end: 72,
},
origin: "top center",
}} }}
> >
{@render children()} <div class="min-h-screen">
{@render children()}
</div>
<div
class="-mt-14 w-full h-14 border-t border-separator relative -z-50"
>
<Footer
class="w-full h-full"
items={{
"Privacy Policy": "#",
"Source Code": "#",
"Discord Server": "#",
}}
/>
</div>
</div> </div>
{/key} {/key}
</div> </div>
<div class="-mt-14 w-full h-14 border-t border-separator relative z-50"> {#if data.pathname === "/"}
<Footer <div
class="w-full h-full" transition:fade={{
items={{ duration,
"Privacy Policy": "#", easing: quintOut,
"Source Code": "#",
"Discord Server": "#",
}} }}
/> class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
</div> style="background: var(--bg-gradient);"
></div>
{/if}

View File

@ -11,35 +11,52 @@
</script> </script>
<div <div
class="absolute -z-30 top-0 left-0 w-full h-full flex items-center justify-center overflow-hidden" class="absolute -z-30 top-0 left-0 w-screen h-screen flex items-center justify-center overflow-hidden"
> >
<VertVBig class="fill-[--fg] opacity-50" /> <VertVBig class="fill-[--fg] opacity-50" />
</div> </div>
<div
class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
style="background: var(--bg-gradient);"
></div>
<div
class="fixed top-0 left-0 w-screen h-screen -z-50 pointer-events-none bg-panel"
></div>
<div class="w-screen h-screen flex items-center justify-center"> <div class="w-screen h-screen flex items-center justify-center">
<div class="max-w-5xl w-full"> <div class="max-w-5xl w-full">
<div class="flex items-center h-[266px] gap-24"> <div class="flex items-center h-[266px] gap-24">
<div class="flex-grow w-full"> <div class="flex-grow w-full">
<h1 class="text-6xl tracking-tight leading-[72px] mb-6"> <h1
class="text-6xl tracking-tight leading-[72px] mb-6 blur-in"
style:--delay="20ms"
>
The file converter you'll love. The file converter you'll love.
</h1> </h1>
<p class="font-normal text-xl text-muted"> <p
class="font-normal text-xl text-muted blur-in"
style:--delay="60ms"
>
All processing done on your device. No file size limit, no All processing done on your device. No file size limit, no
ads, and completely open source. ads, and completely open source.
</p> </p>
</div> </div>
<div class="flex-grow w-full h-full"> <div class="flex-grow w-full h-full blur-in" style:--delay="60ms">
<Uploader class="w-full h-full" /> <Uploader class="w-full h-full" />
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<style>
@keyframes blur-in {
0% {
filter: blur(8px);
transform: translateY(-8px) scale(0.9);
opacity: 0;
}
100% {
filter: blur(0);
transform: translateY(0) scale(1);
opacity: 1;
}
}
.blur-in {
animation: blur-in 0.75s var(--transition) var(--delay, 0ms) forwards;
opacity: 0;
}
</style>