Pixel Image
svelte-animations/pixel-imageFreeBlock
An image component that reveals itself through a pixelated grid animation with optional grayscale to color transition.
Install it
npx shadcn@latest add https://sv-animations.vercel.app/r/pixel-image.jsonSource
1<script lang="ts">2 import { cn } from "$UTILS$.js";3 import { useInView } from "motion-sv";4 import { watch } from "runed";56 type Grid = {7 rows: number;8 cols: number;9 };1011 const DEFAULT_GRIDS: Record<string, Grid> = {12 "6x4": { rows: 4, cols: 6 },13 "8x8": { rows: 8, cols: 8 },14 "8x3": { rows: 3, cols: 8 },15 "4x6": { rows: 6, cols: 4 },16 "3x8": { rows: 8, cols: 3 },17 };1819 type PredefinedGridKey = keyof typeof DEFAULT_GRIDS;2021 interface Props {22 src: string;23 grid?: PredefinedGridKey;24 customGrid?: Grid;25 grayscaleAnimation?: boolean;26 pixelFadeInDuration?: number;27 maxAnimationDelay?: number;28 colorRevealDelay?: number;29 once?: boolean;30 }3132 let {33 src,34 grid = "6x4",35 grayscaleAnimation = true,36 pixelFadeInDuration = 1000,37 maxAnimationDelay = 1200,38 colorRevealDelay = 1300,39 customGrid,40 once = false,41 }: Props = $props();4243 let showColor = $state(false);4445 const MIN_GRID = 1;46 const MAX_GRID = 16;4748 let dimensions = $derived.by(() => {49 const isValidGrid = (grid?: Grid) => {50 if (!grid) return false;51 const { rows, cols } = grid;52 return (53 Number.isInteger(rows) &&54 Number.isInteger(cols) &&55 rows >= MIN_GRID &&56 cols >= MIN_GRID &&57 rows <= MAX_GRID &&58 cols <= MAX_GRID59 );60 };6162 return isValidGrid(customGrid) ? customGrid! : DEFAULT_GRIDS[grid];63 });6465 let pieces = $derived.by(() => {66 const total = dimensions.rows * dimensions.cols;67 return Array.from({ length: total }, (_, index) => {68 const row = Math.floor(index / dimensions.cols);69 const col = index % dimensions.cols;7071 const clipPath = `polygon(72 ${col * (100 / dimensions.cols)}% ${row * (100 / dimensions.rows)}%,73 ${(col + 1) * (100 / dimensions.cols)}% ${row * (100 / dimensions.rows)}%,74 ${(col + 1) * (100 / dimensions.cols)}% ${(row + 1) * (100 / dimensions.rows)}%,75 ${col * (100 / dimensions.cols)}% ${(row + 1) * (100 / dimensions.rows)}%76 )`;7778 const delay = Math.random() * maxAnimationDelay;79 return {80 clipPath,81 delay,82 };83 });84 });8586 let element: HTMLDivElement | null = $state(null);87 let view = useInView(88 () => element!,89 () => ({ once }) as any // type definition bug90 );9192 watch(93 () => view.current,94 (isInView) => {95 if (isInView) {96 // Element entered view - start color reveal after delay97 const colorTimeout = setTimeout(() => {98 showColor = true;99 }, colorRevealDelay);100 return () => clearTimeout(colorTimeout);101 } else if (!once) {102// … truncated
What it pulls in
npm packages
Files it writes
More from Svelte Animations
All 66 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Beamanimated-beam | Svelte Animations | Blocks | Free | 1 dep · 6 files | |
| Animated Circular Progress Baranimated-circular-progress-bar | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Animated Gradient Textanimated-gradient-text | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Animated Grid Patternanimated-grid-pattern | Svelte Animations | Blocks | Free | 1 dep · 2 files | |
| Animated Listanimated-list | Svelte Animations | Blocks | Free | 1 dep · 2 files | |
| Animated Shiny Textanimated-shiny-text | Svelte Animations | Blocks | Free | no deps | |
| Animated Theme Toggleranimated-theme-toggler | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Arc Timelinearc-timeline | Svelte Animations | Blocks | Free | no deps · 3 files |
