Use fade animation

This commit is contained in:
JovannMC 2025-01-10 11:22:46 +03:00
parent 5941f353b0
commit 9b31cd59f7
No known key found for this signature in database
5 changed files with 36 additions and 246 deletions

View File

@ -1,4 +1,3 @@
import type { EasingFunction, TransitionConfig } from "svelte/transition";
import type { AnimationConfig, FlipParams } from "svelte/animate";
import { cubicOut } from "svelte/easing";
@ -7,129 +6,24 @@ export const transition =
export const duration = 500;
const remap = (
value: number,
low1: number,
high1: number,
low2: number,
high2: number,
) => low2 + ((high2 - low2) * (value - low1)) / (high1 - low1);
interface FadeOptions {
delay?: number;
duration?: number;
easing?: (t: number) => number;
type?: "in" | "out";
}
const choose = (
direction: "in" | "out" | "both",
defaultValue: number,
inValue?: number,
outValue?: number,
) =>
direction !== "out"
? typeof inValue === "number"
? inValue
: defaultValue
: typeof outValue === "number"
? outValue
: defaultValue;
type Combination<T extends string, U extends string> = `${T} ${U}`;
export const blur = (
_: HTMLElement,
config:
| Partial<{
blurMultiplier: number;
duration: number;
easing: EasingFunction;
scale: {
start: number;
end: number;
};
x: {
start: number;
end: number;
};
y: {
start: number;
end: number;
};
delay: number;
opacity: boolean;
origin: Combination<
"top" | "bottom" | "left" | "right" | "center",
"top" | "bottom" | "left" | "right" | "center"
> & {};
}>
| undefined,
dir: {
direction: "in" | "out" | "both";
},
): TransitionConfig => {
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)",
).matches;
if (typeof config?.opacity === "undefined" && config) config.opacity = true;
const isUsingTranslate = !!config?.x || !!config?.y || !!config?.scale;
return {
delay: config?.delay || 0,
duration: prefersReducedMotion ? 0 : config?.duration || 300,
css: (t) => {
if (prefersReducedMotion) return "";
const translate = isUsingTranslate
? `translate(${remap(
t,
0,
1,
choose(
dir.direction,
0,
config?.x?.start,
config?.x?.end,
),
choose(
dir.direction,
0,
config?.x?.end,
config?.x?.start,
),
)}px, ${remap(
t,
0,
1,
choose(
dir.direction,
0,
config?.y?.start,
config?.y?.end,
),
choose(
dir.direction,
0,
config?.y?.end,
config?.y?.start,
),
)}px) scale(${remap(
t,
0,
1,
choose(
dir.direction,
0.9,
config?.scale?.start,
config?.scale?.end,
),
choose(
dir.direction,
1,
config?.scale?.end,
config?.scale?.start,
),
)})`
: ``;
return `filter: blur(${(1 - t) * (config?.blurMultiplier || 1)}px); opacity: ${config?.opacity ? t : 1}; transform: ${
translate
}; ${config?.origin ? `transform-origin: ${config.origin};` : ""}`;
},
easing: config?.easing,
};
};
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 {
@ -165,7 +59,7 @@ export function flip(
? duration(Math.sqrt(dx * dx + dy * dy))
: duration,
easing,
css: (t, u) => {
css: (_t, u) => {
const x = u * dx;
const y = u * dy;
// const sx = scale ? t + (u * from.width) / to.width : 1;

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { blur, duration, transition } from "$lib/animation";
import { duration, fade, transition } from "$lib/animation";
import { ChevronDown } from "lucide-svelte";
import { onMount } from "svelte";
import { quintOut } from "svelte/easing";
@ -60,31 +60,13 @@
<div class="grid grid-cols-1 grid-rows-1 w-fit text-left flex-grow-0">
{#key selected}
<p
in:blur={{
in:fade={{
duration,
easing: quintOut,
blurMultiplier: 6,
scale: {
start: 0.9,
end: 1,
},
y: {
start: isUp ? -50 : 50,
end: 0,
},
}}
out:blur={{
out:fade={{
duration,
easing: quintOut,
blurMultiplier: 6,
scale: {
start: 1,
end: 0.9,
},
y: {
start: 0,
end: isUp ? 50 : -50,
},
}}
class="col-start-1 row-start-1 text-left"
>
@ -108,20 +90,10 @@
</button>
{#if open}
<div
style={hover ? "will-change: opacity, blur, transform" : ""}
transition:blur={{
style={hover ? "will-change: opacity, fade, transform" : ""}
transition:fade={{
duration,
easing: quintOut,
blurMultiplier: 6,
scale: {
start: 0.9,
end: 1,
},
y: {
start: -10,
end: 0,
},
origin: "top center",
}}
class="w-full shadow-xl bg-panel-alt shadow-black/25 absolute overflow-hidden top-full mt-1 left-0 z-50 bg-background rounded-xl"
>

View File

@ -1,7 +1,7 @@
<script lang="ts">
import { browser } from "$app/environment";
import { page } from "$app/stores";
import { blur, duration } from "$lib/animation";
import { duration, fade } from "$lib/animation";
import { theme } from "$lib/store/index.svelte";
import clsx from "clsx";
import { MoonIcon, SunIcon } from "lucide-svelte";
@ -53,23 +53,13 @@
{#key item.name}
<div
class="w-full row-start-1 col-start-1 h-full flex items-center justify-center gap-3"
in:blur={{
blurMultiplier: 6,
in:fade={{
duration,
easing: quintOut,
y: {
start: -48,
end: 0,
},
}}
out:blur={{
blurMultiplier: 6,
out:fade={{
duration,
easing: quintOut,
y: {
start: 0,
end: 48,
},
}}
>
<div class="relative">
@ -78,44 +68,21 @@
<div
class="absolute overflow-hidden grid grid-rows-1 grid-cols-1 -top-1 font-display -right-1 w-fit px-1.5 h-4 rounded-full bg-badge text-on-badge font-medium"
style="font-size: 0.7rem;"
transition:blur={{
blurMultiplier: 4,
transition:fade={{
duration,
easing: quintOut,
scale: {
start: 0.5,
end: 1,
},
}}
>
{#key item.badge}
<div
class="flex items-center justify-center w-full h-full col-start-1 row-start-1"
in:blur={{
in:fade={{
duration,
easing: quintOut,
blurMultiplier: 3,
y: {
start: -12,
end: 0,
},
scale: {
start: 0.75,
end: 1,
},
}}
out:blur={{
out:fade={{
duration,
easing: quintOut,
blurMultiplier: 3,
y: {
start: 0,
end: 12,
},
scale: {
start: 1,
end: 0.75,
},
}}
>
{item.badge}

View File

@ -2,7 +2,7 @@
import { beforeNavigate, goto } from "$app/navigation";
import { page } from "$app/stores";
import { PUB_HOSTNAME, PUB_PLAUSIBLE_URL } from "$env/static/public";
import { blur, duration } from "$lib/animation";
import { duration, fade } from "$lib/animation";
import featuredImage from "$lib/assets/VERT_Feature.webp";
import ConversionPanel from "$lib/components/functional/ConversionPanel.svelte";
import Navbar from "$lib/components/functional/Navbar.svelte";
@ -136,32 +136,14 @@
.find((i) => i.url === "/convert")
?.activeMatch($page.url.pathname)}
<div
in:blur={{
blurMultiplier: 8,
in:fade={{
duration: duration + 50,
delay: 50,
easing: quintOut,
y: {
start: -24,
end: 0,
},
scale: {
start: 0.95,
end: 1,
},
}}
out:blur={{
blurMultiplier: 8,
out:fade={{
duration,
easing: quintOut,
y: {
start: 0,
end: 24,
},
scale: {
start: 1,
end: 1.05,
},
}}
>
<ConversionPanel />
@ -174,33 +156,13 @@
{#key data.pathname}
<div
class="row-start-1 col-start-1"
in:blur={{
blurMultiplier: 8,
in:fade={{
duration,
easing: quintOut,
x: {
start: goingLeft ? -100 : 100,
end: 0,
},
y: {
start: 72,
end: 0,
},
origin: "top center",
}}
out:blur={{
blurMultiplier: 8,
out:fade={{
duration,
easing: quintOut,
x: {
start: 0,
end: goingLeft ? 100 : -100,
},
y: {
start: 0,
end: 72,
},
origin: "top center",
}}
>
<div class="flex flex-col h-full">

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { blur, duration } from "$lib/animation";
import { duration, fade } 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";
@ -121,14 +121,9 @@
{#if files.files.length === 1}
<div
class="w-full relative"
transition:blur={{
blurMultiplier: 24,
transition:fade={{
duration,
easing: quintOut,
scale: {
start: 1.02,
end: 1,
},
}}
>
<img