️ Remove spotlight effect to improve performance

This commit is contained in:
pheralb 2024-04-20 23:41:34 +01:00
parent 632ec0ae27
commit 038edfa2ae
2 changed files with 130 additions and 184 deletions

View File

@ -1,55 +0,0 @@
<script lang="ts">
let domElement: HTMLElement;
let focused = false;
let position = { x: 0, y: 0 };
let opacity = 0;
const handleMouseMove = (e: MouseEvent) => {
if (!domElement || focused) return;
const rect = domElement.getBoundingClientRect();
position = {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
};
const handleFocus = () => {
focused = true;
opacity = 1;
};
const handleBlur = () => {
focused = false;
opacity = 0;
};
const handleMouseEnter = () => {
opacity = 1;
};
const handleMouseLeave = () => {
opacity = 0;
};
</script>
<!--Se quito el aria-hidden="true" para que se pueda leer el contenido del card con el lector de pantalla -->
<article
bind:this={domElement}
on:mousemove={handleMouseMove}
on:focus={handleFocus}
on:blur={handleBlur}
on:mouseenter={handleMouseEnter}
on:mouseleave={handleMouseLeave}
class="relative flex items-center justify-center overflow-hidden rounded-md border border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-900"
>
<div
class="pointer-events-none absolute transform-gpu -inset-px opacity-0 transition duration-300"
style={`
opacity: ${opacity};
background: radial-gradient(600px circle at ${position.x}px ${position.y}px, rgba(97, 97, 97, 0.1), transparent 40%);
`}
/>
<slot />
</article>

View File

@ -1,16 +1,14 @@
<script lang="ts"> <script lang="ts">
import type { iSVG } from '../types/svg'; import type { iSVG } from '@/types/svg';
import { toast } from 'svelte-sonner';
// Utils: // Utils:
import { cn } from '@/utils/cn'; import { cn } from '@/utils/cn';
import { getSvgContent } from '@/utils/getSvgContent'; import { getSvgContent } from '@/utils/getSvgContent';
// Icons: // Icons:
import { CopyIcon, LinkIcon, ChevronsRight, Baseline, Sparkles } from 'lucide-svelte'; import { LinkIcon, ChevronsRight, Baseline, Sparkles } from 'lucide-svelte';
// Components & styles: // Components & styles:
import CardSpotlight from './cardSpotlight.svelte';
import DownloadSvg from './downloadSvg.svelte'; import DownloadSvg from './downloadSvg.svelte';
import CopySvg from './copySvg.svelte'; import CopySvg from './copySvg.svelte';
import { badgeStyles } from '@/ui/styles'; import { badgeStyles } from '@/ui/styles';
@ -39,134 +37,137 @@
// Icon Stroke & Size: // Icon Stroke & Size:
let iconStroke = 1.8; let iconStroke = 1.8;
let iconSize = 16; let iconSize = 16;
// Global Images Styles:
const globalImageStyles = 'mb-4 mt-2 h-10 select-none';
</script> </script>
<CardSpotlight> <div
<div class="flex flex-col items-center justify-center rounded-md p-4"> class="flex flex-col items-center justify-center rounded-md p-4 border border-neutral-200 dark:border-neutral-800 hover:bg-neutral-300/50 dark:hover:bg-neutral-800/20 transition-colors duration-100 group"
<!-- Image --> >
{#if wordmarkSvg == true} <!-- Image -->
<img {#if wordmarkSvg == true}
class="hidden dark:block mb-4 mt-2 h-10 select-none" <img
src={typeof svgInfo.wordmark !== 'string' class={cn('hidden dark:block', globalImageStyles)}
? svgInfo.wordmark?.dark || '' src={typeof svgInfo.wordmark !== 'string'
: svgInfo.wordmark || ''} ? svgInfo.wordmark?.dark || ''
alt={svgInfo.title} : svgInfo.wordmark || ''}
title={svgInfo.title} alt={svgInfo.title}
loading="lazy" title={svgInfo.title}
/> loading="lazy"
<img />
class="block dark:hidden mb-4 mt-2 h-10 select-none" <img
src={typeof svgInfo.wordmark !== 'string' class={cn('block dark:hidden', globalImageStyles)}
? svgInfo.wordmark?.light || '' src={typeof svgInfo.wordmark !== 'string'
: svgInfo.wordmark || ''} ? svgInfo.wordmark?.light || ''
alt={svgInfo.title} : svgInfo.wordmark || ''}
title={svgInfo.title} alt={svgInfo.title}
loading="lazy" title={svgInfo.title}
/> loading="lazy"
{:else} />
<img {:else}
class={cn('hidden dark:block mb-4 mt-2 h-10 select-none')} <img
src={typeof svgInfo.route !== 'string' ? svgInfo.route.dark : svgInfo.route} class={cn('hidden dark:block', globalImageStyles)}
alt={svgInfo.title} src={typeof svgInfo.route !== 'string' ? svgInfo.route.dark : svgInfo.route}
title={svgInfo.title} alt={svgInfo.title}
loading="lazy" title={svgInfo.title}
/> loading="lazy"
<img />
class={cn('block dark:hidden mb-4 mt-2 h-10 select-none')} <img
src={typeof svgInfo.route !== 'string' ? svgInfo.route.light : svgInfo.route} class={cn('block dark:hidden', globalImageStyles)}
alt={svgInfo.title} src={typeof svgInfo.route !== 'string' ? svgInfo.route.light : svgInfo.route}
title={svgInfo.title} alt={svgInfo.title}
loading="lazy" title={svgInfo.title}
/> loading="lazy"
{/if} />
<!-- Title --> {/if}
<div class="mb-3 flex flex-col space-y-1 items-center justify-center"> <!-- Title -->
<p class="truncate text-[15px] font-medium text-balance text-center select-all"> <div class="mb-3 flex flex-col space-y-1 items-center justify-center">
{svgInfo.title} <p class="truncate text-[15px] font-medium text-balance text-center select-all">
</p> {svgInfo.title}
<div class="flex items-center space-x-1 justify-center"> </p>
{#if Array.isArray(svgInfo.category)} <div class="flex items-center space-x-1 justify-center">
{#each svgInfo.category.sort() as c, index} {#if Array.isArray(svgInfo.category)}
<a href={`/directory/${c.toLowerCase()}`} class={badgeStyles}>{c} </a> {#each svgInfo.category.sort() as c, index}
{/each} <a href={`/directory/${c.toLowerCase()}`} class={badgeStyles}>{c} </a>
{:else} {/each}
<a href={`/directory/${svgInfo.category.toLowerCase()}`} class={badgeStyles}>
{svgInfo.category}
</a>
{/if}
</div>
</div>
<!-- Actions -->
<div class="flex items-center space-x-1">
{#if isInFigma}
<button
title="Insert to figma"
on:click={() => {
const svgHasTheme = typeof svgInfo.route !== 'string';
if (!svgHasTheme) {
insertSVG(
typeof svgInfo.route === 'string'
? svgInfo.route
: "Something went wrong. Couldn't copy the SVG."
);
return;
}
const dark = document.documentElement.classList.contains('dark');
insertSVG(
typeof svgInfo.route !== 'string'
? dark
? svgInfo.route.dark
: svgInfo.route.light
: svgInfo.route
);
}}
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
>
<ChevronsRight size={iconSize} strokeWidth={iconStroke} />
</button>
{/if}
{#if wordmarkSvg}
<CopySvg {iconSize} {iconStroke} {svgInfo} isInFigma={false} isWordmarkSvg={true} />
{:else} {:else}
<CopySvg {iconSize} {iconStroke} {svgInfo} isInFigma={false} isWordmarkSvg={false} /> <a href={`/directory/${svgInfo.category.toLowerCase()}`} class={badgeStyles}>
{/if} {svgInfo.category}
</a>
<DownloadSvg
{svgInfo}
isDarkTheme={() => {
const dark = document.documentElement.classList.contains('dark');
return dark;
}}
/>
<a
href={svgInfo.url}
title="Website"
target="_blank"
rel="noopener noreferrer"
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
>
<LinkIcon size={iconSize} strokeWidth={iconStroke} />
</a>
{#if svgInfo.wordmark !== undefined}
<button
title={wordmarkSvg ? 'Show logo SVG' : 'Show wordmark SVG'}
on:click={() => {
wordmarkSvg = !wordmarkSvg;
}}
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
>
{#if wordmarkSvg}
<Sparkles size={iconSize} strokeWidth={iconStroke} />
{:else}
<Baseline size={iconSize} strokeWidth={iconStroke} />
{/if}
</button>
{/if} {/if}
</div> </div>
</div> </div>
</CardSpotlight> <!-- Actions -->
<div class="flex items-center space-x-1">
{#if isInFigma}
<button
title="Insert to figma"
on:click={() => {
const svgHasTheme = typeof svgInfo.route !== 'string';
if (!svgHasTheme) {
insertSVG(
typeof svgInfo.route === 'string'
? svgInfo.route
: "Something went wrong. Couldn't copy the SVG."
);
return;
}
const dark = document.documentElement.classList.contains('dark');
insertSVG(
typeof svgInfo.route !== 'string'
? dark
? svgInfo.route.dark
: svgInfo.route.light
: svgInfo.route
);
}}
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
>
<ChevronsRight size={iconSize} strokeWidth={iconStroke} />
</button>
{/if}
{#if wordmarkSvg}
<CopySvg {iconSize} {iconStroke} {svgInfo} isInFigma={false} isWordmarkSvg={true} />
{:else}
<CopySvg {iconSize} {iconStroke} {svgInfo} isInFigma={false} isWordmarkSvg={false} />
{/if}
<DownloadSvg
{svgInfo}
isDarkTheme={() => {
const dark = document.documentElement.classList.contains('dark');
return dark;
}}
/>
<a
href={svgInfo.url}
title="Website"
target="_blank"
rel="noopener noreferrer"
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
>
<LinkIcon size={iconSize} strokeWidth={iconStroke} />
</a>
{#if svgInfo.wordmark !== undefined}
<button
title={wordmarkSvg ? 'Show logo SVG' : 'Show wordmark SVG'}
on:click={() => {
wordmarkSvg = !wordmarkSvg;
}}
class="flex items-center space-x-2 rounded-md p-2 duration-100 hover:bg-neutral-200 dark:hover:bg-neutral-700/40"
>
{#if wordmarkSvg}
<Sparkles size={iconSize} strokeWidth={iconStroke} />
{:else}
<Baseline size={iconSize} strokeWidth={iconStroke} />
{/if}
</button>
{/if}
</div>
</div>