mirror of
https://github.com/pheralb/svgl.git
synced 2024-11-10 14:46:54 +08:00
⚡️ Remove spotlight effect to improve performance
This commit is contained in:
parent
632ec0ae27
commit
038edfa2ae
@ -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>
|
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user