mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-10-05 09:19:04 +02:00
feat: add animated logo as default logo
This commit is contained in:
@@ -1,18 +1,149 @@
|
||||
<script module lang="ts">
|
||||
type LogoVariant = 'light' | 'dark';
|
||||
|
||||
let defaultLogoHasAnimated = false;
|
||||
const customLogoAvailability: Record<LogoVariant, boolean | undefined> = {
|
||||
light: undefined,
|
||||
dark: undefined
|
||||
};
|
||||
|
||||
const finalLogoPath =
|
||||
'M-250.368,-706.48C-166.912,-706.48 -83.456,-706.48 0,-706.48C149.377,-706.48 270.906,-584.953 270.906,-435.576C270.906,-376.876 252.438,-321.028 217.506,-274.062C183.258,-228.019 136.385,-194.563 81.955,-177.305C76.939,-175.715 71.924,-174.124 66.908,-172.534C54.955,-231.481 43.003,-290.429 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.345,-369.822 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.344,-369.822 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-50.48,-230.815 -69.733,-112.167 -88.985,6.48C-142.779,6.48 -196.574,6.48 -250.368,6.48Z';
|
||||
|
||||
const animationValues = `
|
||||
M-189.277,-455.654C-183.639,-520.099 -145.598,-577.247 -88.32,-607.319C-29.581,-638.158 40.991,-636.125 97.857,-601.956C125.29,-585.473 148.114,-562.328 164.212,-534.668C211.414,-453.567 192.341,-350.154 119.313,-291.228C92.569,-269.648 60.47,-255.723 26.44,-250.94C27.98,-283.752 29.51,-316.564 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.345,-369.822 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.344,-369.822 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-29.632,-316.622 -28.036,-283.781 -26.44,-250.94C-114.05,-263.255 -181.567,-334.403 -189.277,-422.534Z;
|
||||
|
||||
M-189.277,-455.654C-183.639,-520.099 -145.598,-577.247 -88.32,-607.319C-29.581,-638.158 40.991,-636.125 97.857,-601.956C125.29,-585.473 148.114,-562.328 164.212,-534.668C211.414,-453.567 192.341,-350.154 119.313,-291.228C92.569,-269.648 60.47,-255.723 26.44,-250.94C27.98,-283.752 29.51,-316.564 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.345,-369.822 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.344,-369.822 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-29.632,-316.622 -28.036,-283.781 -26.44,-250.94C-114.05,-263.255 -181.567,-334.403 -189.277,-422.534Z;
|
||||
|
||||
M-208.638,-523.827C-208.638,-580.969 -167.157,-631.565 -113.16,-644.659C-38.396,-662.79 43.369,-658.5 117.928,-641.978C156.432,-633.446 188.336,-602.071 196.106,-563.334C220.586,-441.292 205.573,-309.149 173.656,-196.614C158.003,-141.421 105.235,-133.862 43.22,-131.47C39.165,-204.106 35.105,-276.742 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.344,-369.823 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.343,-369.823 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-38.561,-276.801 -45.888,-204.136 -53.22,-131.47C-137.025,-137.627 -208.638,-173.118 -208.638,-262.267Z;
|
||||
|
||||
M-228,-592C-228,-641.7 -187.7,-682 -138,-682C-46,-682 46,-682 138,-682C187.7,-682 228,-641.7 228,-592C228,-428.67 228,-265.33 228,-102C228,-12 150,-12 60,-12C50.35,-124.46 40.7,-236.92 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.345,-369.822 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.344,-369.822 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-47.49,-236.98 -63.74,-124.49 -80,-12C-160,-12 -228,-12 -228,-102Z;
|
||||
|
||||
M-239.184,-594.24C-239.184,-649.466 -194.411,-694.24 -139.184,-694.24C-42.969,-694.24 53.238,-694.24 149.453,-694.24C204.679,-694.24 249.453,-649.466 249.453,-594.24C249.453,-430.415 249.453,-266.585 249.453,-102.76C249.453,-2.76 159.455,-2.76 63.454,-2.76C52.653,-118.299 41.852,-233.839 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.344,-369.823 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.343,-369.823 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-48.985,-233.897 -66.737,-118.328 -84.493,-2.76C-162.5,-2.76 -239.184,-2.76 -239.184,-102.76Z;
|
||||
|
||||
M-250.368,-596.48C-250.368,-657.233 -201.121,-706.48 -140.368,-706.48C-39.938,-706.48 60.476,-706.48 160.906,-706.48C221.659,-706.48 270.906,-657.233 270.906,-596.48C270.906,-432.16 270.906,-267.84 270.906,-103.52C270.906,6.48 168.91,6.48 66.908,6.48C54.955,-112.139 43.003,-230.757 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.345,-369.822 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.344,-369.822 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-50.48,-230.815 -69.733,-112.167 -88.985,6.48C-165,6.48 -250.368,6.48 -250.368,-103.52Z;
|
||||
|
||||
M-250.368,-596.48C-250.368,-657.233 -201.121,-706.48 -140.368,-706.48C-39.938,-706.48 60.476,-706.48 160.906,-706.48C221.659,-706.48 270.906,-657.233 270.906,-596.48C270.906,-432.16 270.906,-267.84 270.906,-103.52C270.906,6.48 168.91,6.48 66.908,6.48C54.955,-112.139 43.003,-230.757 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.345,-369.822 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.344,-369.822 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-50.48,-230.815 -69.733,-112.167 -88.985,6.48C-165,6.48 -250.368,6.48 -250.368,-103.52Z;
|
||||
|
||||
M-250.368,-651.48C-208.64,-681.856 -142.288,-706.48 -70.184,-706.48C54.72,-706.48 158.116,-640.023 215.906,-571.028C243.028,-538.647 257.527,-490.302 244.206,-435.271C219.135,-331.696 192.286,-233.857 176.43,-140.412C167.087,-85.348 120.417,-83.822 66.908,-83.027C54.955,-171.81 43.003,-260.593 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.344,-369.823 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.343,-369.823 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-50.48,-230.815 -69.733,-112.167 -88.985,6.48C-153.889,6.48 -223.471,6.48 -250.368,-48.52Z;
|
||||
|
||||
M-250.368,-706.48C-166.912,-706.48 -83.456,-706.48 0,-706.48C149.377,-706.48 270.906,-584.953 270.906,-435.576C270.906,-376.876 252.438,-321.028 217.506,-274.062C183.258,-228.019 136.385,-194.563 81.955,-177.305C76.939,-175.715 71.924,-174.124 66.908,-172.534C54.955,-231.481 43.003,-290.429 31.05,-349.376C34.355,-350.974 37.661,-352.571 40.966,-354.169C73.345,-369.822 94.269,-403.156 94.269,-439.094C94.269,-491.073 51.982,-533.36 0,-533.36C-51.978,-533.36 -94.267,-491.073 -94.267,-439.094C-94.267,-403.156 -73.344,-369.822 -40.963,-354.169C-37.718,-352.6 -34.473,-351.032 -31.228,-349.463C-50.48,-230.815 -69.733,-112.167 -88.985,6.48C-142.779,6.48 -196.574,6.48 -250.368,6.48Z`;
|
||||
const initialLogoPath = animationValues.trim().split(';', 1)[0];
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { m } from '$lib/paraglide/messages';
|
||||
import appConfigStore from '$lib/stores/application-configuration-store';
|
||||
import { cachedApplicationLogo } from '$lib/utils/cached-image-util';
|
||||
import { cn } from '$lib/utils/style';
|
||||
import { mode } from 'mode-watcher';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
let { ...props }: HTMLAttributes<HTMLImageElement> = $props();
|
||||
let {
|
||||
class: className,
|
||||
alt,
|
||||
defaultOnly = false,
|
||||
animate = true,
|
||||
colorScheme
|
||||
}: {
|
||||
class?: string;
|
||||
alt?: string;
|
||||
defaultOnly?: boolean;
|
||||
animate?: boolean;
|
||||
colorScheme?: 'light' | 'dark';
|
||||
} = $props();
|
||||
|
||||
const isLightMode = $derived(mode.current === 'light');
|
||||
const initialIsLightMode = colorScheme ? colorScheme === 'light' : mode.current === 'light';
|
||||
const initialLogoVariant: LogoVariant = initialIsLightMode ? 'light' : 'dark';
|
||||
|
||||
let customLogoAvailabilityState = $state<Record<LogoVariant, boolean | undefined>>({
|
||||
...customLogoAvailability
|
||||
});
|
||||
let animateDefaultLogo = $state(
|
||||
customLogoAvailability[initialLogoVariant] === false && claimDefaultLogoAnimation()
|
||||
);
|
||||
|
||||
const isLightMode = $derived(colorScheme ? colorScheme === 'light' : mode.current === 'light');
|
||||
const logoVariant = $derived(isLightMode ? 'light' : 'dark');
|
||||
const logoAlt = $derived(alt ?? m.logo());
|
||||
const useDefaultLogo = $derived(
|
||||
defaultOnly || customLogoAvailabilityState[logoVariant] === false
|
||||
);
|
||||
const customLogoLoaded = $derived(customLogoAvailabilityState[logoVariant] === true);
|
||||
|
||||
function handleImageLoad() {
|
||||
customLogoAvailability[logoVariant] = true;
|
||||
customLogoAvailabilityState[logoVariant] = true;
|
||||
}
|
||||
|
||||
function handleImageError() {
|
||||
animateDefaultLogo = claimDefaultLogoAnimation();
|
||||
customLogoAvailability[logoVariant] = false;
|
||||
customLogoAvailabilityState[logoVariant] = false;
|
||||
}
|
||||
|
||||
function claimDefaultLogoAnimation() {
|
||||
if (!animate || defaultOnly || defaultLogoHasAnimated || $appConfigStore?.disableAnimations) {
|
||||
return false;
|
||||
}
|
||||
|
||||
defaultLogoHasAnimated = true;
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<img
|
||||
{...props}
|
||||
class={cn('aspect-square object-contain', props.class)}
|
||||
src={cachedApplicationLogo.getUrl(isLightMode)}
|
||||
alt={m.logo()}
|
||||
/>
|
||||
{#if useDefaultLogo}
|
||||
<svg
|
||||
class={cn('aspect-square', isLightMode ? 'text-black' : 'text-white', className)}
|
||||
viewBox="-346.211 -706.48 712.96 712.96"
|
||||
role="img"
|
||||
aria-label={logoAlt}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
opacity={animateDefaultLogo ? 0 : 1}
|
||||
d={animateDefaultLogo ? initialLogoPath : finalLogoPath}
|
||||
>
|
||||
{#if animateDefaultLogo}
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
dur="1.5s"
|
||||
begin="0s"
|
||||
fill="freeze"
|
||||
keyTimes="0; 0.15; 1"
|
||||
values="0; 1; 1"
|
||||
/>
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
dur="1.5s"
|
||||
begin="0s"
|
||||
fill="freeze"
|
||||
calcMode="spline"
|
||||
keyTimes="0; 0.20; 0.26; 0.44; 1"
|
||||
keySplines="0 0 1 1; 0 0 1 1; 0.35 0 0.35 1; 0 0 1 1"
|
||||
values="-90 0 -439.094; -90 0 -439.094; -90 0 -439.094; 0 0 -439.094; 0 0 -439.094"
|
||||
/>
|
||||
<animate
|
||||
attributeName="d"
|
||||
dur="1.5s"
|
||||
begin="0s"
|
||||
fill="freeze"
|
||||
calcMode="spline"
|
||||
keyTimes="0; 0.4; 0.4681; 0.53; 0.5689; 0.63; 0.68; 0.7944; 1"
|
||||
keySplines="0 0 1 1; 0.402 0 0.6982 0.4985; 0.2986 0.4514 0.6022 0.9053; 0.2862 0.178 0.6233 0.5935; 0.2988 0.5071 0.6368 1; 0 0 1 1; 0.5175 0 0.6923 0.5; 0.1712 0.5 0.4163 1"
|
||||
values={animationValues}
|
||||
/>
|
||||
{/if}
|
||||
</path>
|
||||
</svg>
|
||||
{:else}
|
||||
<img
|
||||
class={cn('aspect-square object-contain', className)}
|
||||
style:visibility={customLogoLoaded ? 'visible' : 'hidden'}
|
||||
src={cachedApplicationLogo.getUrl(isLightMode)}
|
||||
alt={logoAlt}
|
||||
onload={handleImageLoad}
|
||||
onerror={handleImageError}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user