Use fly-in animation

This commit is contained in:
JovannMC 2025-01-21 18:42:47 +03:00
parent 7649c8e014
commit fb7ec5e3b2
No known key found for this signature in database
7 changed files with 65 additions and 54 deletions

View File

@ -7,6 +7,38 @@
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
%sveltekit.head%
<script>
// FIXME: flash of dark mode when using light mode
(function() {
// Apply theme before DOM is loaded
let theme = localStorage.getItem("theme");
const prefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
console.log(`Theme: ${theme || "default"}, prefers dark: ${prefersDark}`);
if (theme !== "light" && theme !== "dark") {
console.log("Invalid theme, setting to default");
if (!theme) {
console.log("First time visitor, setting theme");
// first time visitor
window.addEventListener("load", () => {
window.plausible("Theme set", {
props: { theme: prefersDark ? "dark" : "light" },
});
});
}
// invalid theme or first time visitor, set to default
theme = prefersDark ? "dark" : "light";
console.log(`Setting theme to ${theme}`);
localStorage.setItem("theme", theme);
}
console.log(`Applying theme: ${theme}`);
document.documentElement.classList.add(theme);
})();
</script>
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>

View File

@ -6,25 +6,6 @@ export const transition =
export const duration = 500;
interface FadeOptions {
delay?: number;
duration?: number;
easing?: (t: number) => number;
type?: "in" | "out";
}
export function fade(
node: HTMLElement,
{ delay = 0, duration = 400, easing = cubicOut, type = "in" }: FadeOptions = {}
): AnimationConfig {
return {
delay,
duration,
easing,
css: (t) => `opacity: ${type === "in" ? t : 1 - t};`,
};
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
export function is_function(thing: unknown): thing is Function {
return typeof thing === "function";

View File

@ -1,8 +1,9 @@
<script lang="ts">
import { duration, fade, transition } from "$lib/animation";
import { duration, transition } from "$lib/animation";
import { ChevronDown } from "lucide-svelte";
import { onMount } from "svelte";
import { quintOut } from "svelte/easing";
import { fade } from "svelte/transition";
type Props = {
options: string[];

View File

@ -1,12 +1,12 @@
<script lang="ts">
import { browser } from "$app/environment";
import { page } from "$app/stores";
import { fly } from "svelte/transition";
import { duration } from "$lib/animation";
import clsx from "clsx";
import { onMount, tick } from "svelte";
import { quintOut } from "svelte/easing";
import type { Writable } from "svelte/store";
import clsx from "clsx";
import { browser } from "$app/environment";
import { onMount, tick } from "svelte";
import { fly } from "svelte/transition";
interface Props {
links: {

View File

@ -1,11 +1,12 @@
<script lang="ts">
import { browser } from "$app/environment";
import { page } from "$app/stores";
import { duration, fade } from "$lib/animation";
import { duration } from "$lib/animation";
import { setTheme } from "$lib/store/index.svelte";
import clsx from "clsx";
import { MoonIcon, SunIcon } from "lucide-svelte";
import { quintOut } from "svelte/easing";
import { fade } from "svelte/transition";
import Panel from "../visual/Panel.svelte";
import Logo from "../visual/svg/Logo.svelte";

View File

@ -1,7 +1,7 @@
<script lang="ts">
import { beforeNavigate, goto } from "$app/navigation";
import { PUB_HOSTNAME, PUB_PLAUSIBLE_URL } from "$env/static/public";
import { duration, fade } from "$lib/animation";
import { duration } from "$lib/animation";
import featuredImage from "$lib/assets/VERT_Feature.webp";
import Navbar from "$lib/components/functional/Navbar.svelte";
import Footer from "$lib/components/visual/Footer.svelte";
@ -20,6 +20,7 @@
import { onMount } from "svelte";
import { quintOut } from "svelte/easing";
import { writable } from "svelte/store";
import { fade, fly } from "svelte/transition";
import "../app.scss";
let { children, data } = $props();
@ -111,35 +112,10 @@
src="{PUB_PLAUSIBLE_URL}/js/script.pageview-props.tagged-events.js"
></script>{/if}
<script src="/coi-serviceworker.min.js"></script>
<script type="module">
// Apply theme before DOM is loaded
let theme = localStorage.getItem("theme");
const prefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
if (theme !== "light" && theme !== "dark") {
if (!theme) {
// first time visitor
window.addEventListener("load", () => {
window.plausible("Theme set", {
props: { theme: prefersDark ? "dark" : "light" },
});
});
}
// invalid theme or first time visitor, set to default
theme = prefersDark ? "dark" : "light";
localStorage.setItem("theme", theme);
}
document.documentElement.classList.add(theme);
</script>
</svelte:head>
<div class="flex flex-col min-h-screen h-full">
<!-- FIXME: if user resizes between desktop/mobile, highlight of page disappears (only shows on original size) -->
<!-- FIXME: if user has to scroll in a page, transitioning to a page that fits users viewport makes the elements jump after transition ends -->
<div>
<!-- Mobile logo -->
@ -167,12 +143,31 @@
{#key data.pathname}
<div
class="row-start-1 col-start-1"
transition:fade={{
in:fly={{
x: goingLeft ? -window.innerWidth : window.innerWidth,
duration,
easing: quintOut,
delay: 25,
}}
out:fly={{
x: goingLeft ? window.innerWidth : -window.innerWidth,
duration,
easing: quintOut,
}}
>
<div class="flex flex-col h-full pb-36 md:pb-0">
<div
class="flex flex-col h-full pb-36 md:pb-0"
in:fade={{
duration,
easing: quintOut,
delay: 100,
}}
out:fade={{
duration,
easing: quintOut,
delay: 200,
}}
>
{@render children()}
</div>
</div>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { duration, fade } from "$lib/animation";
import { duration } from "$lib/animation";
import ConversionPanel from "$lib/components/functional/ConversionPanel.svelte";
import Dropdown from "$lib/components/functional/Dropdown.svelte";
import Uploader from "$lib/components/functional/Uploader.svelte";
@ -21,6 +21,7 @@
XIcon,
} from "lucide-svelte";
import { quintOut } from "svelte/easing";
import { fade } from "svelte/transition";
$effect(() => {
if (files.files.length === 1 && files.files[0].blobUrl) {