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 type { AnimationConfig, FlipParams } from "svelte/animate";
import { cubicOut } from "svelte/easing"; import { cubicOut } from "svelte/easing";
@ -7,129 +6,24 @@ export const transition =
export const duration = 500; export const duration = 500;
const remap = ( interface FadeOptions {
value: number, delay?: number;
low1: number, duration?: number;
high1: number, easing?: (t: number) => number;
low2: number, type?: "in" | "out";
high2: number, }
) => low2 + ((high2 - low2) * (value - low1)) / (high1 - low1);
const choose = ( export function fade(
direction: "in" | "out" | "both", node: HTMLElement,
defaultValue: number, { delay = 0, duration = 400, easing = cubicOut, type = "in" }: FadeOptions = {}
inValue?: number, ): AnimationConfig {
outValue?: number, return {
) => delay,
direction !== "out" duration,
? typeof inValue === "number" easing,
? inValue css: (t) => `opacity: ${type === "in" ? t : 1 - t};`,
: 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,
};
};
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
export function is_function(thing: unknown): thing is Function { export function is_function(thing: unknown): thing is Function {
@ -165,7 +59,7 @@ export function flip(
? duration(Math.sqrt(dx * dx + dy * dy)) ? duration(Math.sqrt(dx * dx + dy * dy))
: duration, : duration,
easing, easing,
css: (t, u) => { css: (_t, u) => {
const x = u * dx; const x = u * dx;
const y = u * dy; const y = u * dy;
// const sx = scale ? t + (u * from.width) / to.width : 1; // const sx = scale ? t + (u * from.width) / to.width : 1;

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { blur, duration, transition } from "$lib/animation"; import { duration, fade, transition } from "$lib/animation";
import { ChevronDown } from "lucide-svelte"; import { ChevronDown } from "lucide-svelte";
import { onMount } from "svelte"; import { onMount } from "svelte";
import { quintOut } from "svelte/easing"; 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"> <div class="grid grid-cols-1 grid-rows-1 w-fit text-left flex-grow-0">
{#key selected} {#key selected}
<p <p
in:blur={{ in:fade={{
duration, duration,
easing: quintOut, easing: quintOut,
blurMultiplier: 6,
scale: {
start: 0.9,
end: 1,
},
y: {
start: isUp ? -50 : 50,
end: 0,
},
}} }}
out:blur={{ out:fade={{
duration, duration,
easing: quintOut, 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" class="col-start-1 row-start-1 text-left"
> >
@ -108,20 +90,10 @@
</button> </button>
{#if open} {#if open}
<div <div
style={hover ? "will-change: opacity, blur, transform" : ""} style={hover ? "will-change: opacity, fade, transform" : ""}
transition:blur={{ transition:fade={{
duration, duration,
easing: quintOut, 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" 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"> <script lang="ts">
import { browser } from "$app/environment"; import { browser } from "$app/environment";
import { page } from "$app/stores"; 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 { theme } from "$lib/store/index.svelte";
import clsx from "clsx"; import clsx from "clsx";
import { MoonIcon, SunIcon } from "lucide-svelte"; import { MoonIcon, SunIcon } from "lucide-svelte";
@ -53,23 +53,13 @@
{#key item.name} {#key item.name}
<div <div
class="w-full row-start-1 col-start-1 h-full flex items-center justify-center gap-3" class="w-full row-start-1 col-start-1 h-full flex items-center justify-center gap-3"
in:blur={{ in:fade={{
blurMultiplier: 6,
duration, duration,
easing: quintOut, easing: quintOut,
y: {
start: -48,
end: 0,
},
}} }}
out:blur={{ out:fade={{
blurMultiplier: 6,
duration, duration,
easing: quintOut, easing: quintOut,
y: {
start: 0,
end: 48,
},
}} }}
> >
<div class="relative"> <div class="relative">
@ -78,44 +68,21 @@
<div <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" 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;" style="font-size: 0.7rem;"
transition:blur={{ transition:fade={{
blurMultiplier: 4,
duration, duration,
easing: quintOut, easing: quintOut,
scale: {
start: 0.5,
end: 1,
},
}} }}
> >
{#key item.badge} {#key item.badge}
<div <div
class="flex items-center justify-center w-full h-full col-start-1 row-start-1" class="flex items-center justify-center w-full h-full col-start-1 row-start-1"
in:blur={{ in:fade={{
duration, duration,
easing: quintOut, easing: quintOut,
blurMultiplier: 3,
y: {
start: -12,
end: 0,
},
scale: {
start: 0.75,
end: 1,
},
}} }}
out:blur={{ out:fade={{
duration, duration,
easing: quintOut, easing: quintOut,
blurMultiplier: 3,
y: {
start: 0,
end: 12,
},
scale: {
start: 1,
end: 0.75,
},
}} }}
> >
{item.badge} {item.badge}

View File

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

View File

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