click-spark
obsidianui/click-sparkFreeComponent
obsidianui publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by obsidianui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://obsidianui.dev/r/click-spark.jsonSource
1"use client";23import React, { useRef, useEffect, useCallback } from "react";4import { useTheme } from "next-themes";56interface Spark {7 x: number;8 y: number;9 angle: number;10 startTime: number;11}1213interface ClickSparkProps {14 sparkColor?: string;15 sparkSize?: number;16 sparkRadius?: number;17 sparkCount?: number;18 duration?: number;19 easing?: "linear" | "ease-in" | "ease-out" | "ease-in-out";20 extraScale?: number;21}2223export const ClickSpark = ({24 sparkColor,25 sparkSize = 10,26 sparkRadius = 15,27 sparkCount = 8,28 duration = 400,29 easing = "ease-out",30 extraScale = 1,31}: ClickSparkProps) => {32 const canvasRef = useRef<HTMLCanvasElement>(null);33 const sparksRef = useRef<Spark[]>([]);34 const startTimeRef = useRef<number | null>(null);35 const { theme, resolvedTheme } = useTheme();3637 const effectiveColor = sparkColor || (resolvedTheme === "dark" ? "#fff" : "#000");3839 useEffect(() => {40 const canvas = canvasRef.current;41 if (!canvas) return;4243 let resizeTimeout: NodeJS.Timeout;4445 const resizeCanvas = () => {46 if (typeof window !== "undefined") {47 const dpr = window.devicePixelRatio || 1;48 canvas.width = window.innerWidth * dpr;49 canvas.height = window.innerHeight * dpr;50 canvas.style.width = "100%";51 canvas.style.height = "100%";5253 const ctx = canvas.getContext("2d");54 if (ctx) {55 ctx.scale(dpr, dpr);56 }57 }58 };5960 const handleResize = () => {61 if (typeof window !== "undefined") {62 clearTimeout(resizeTimeout);63 resizeTimeout = setTimeout(resizeCanvas, 100);64 }65 };6667 if (typeof window !== "undefined") {68 resizeCanvas();69 window.addEventListener("resize", handleResize);7071 return () => {72 window.removeEventListener("resize", handleResize);73 clearTimeout(resizeTimeout);74 };75 }76 }, []);7778 const easeFunc = useCallback(79 (t: number) => {80 switch (easing) {81 case "linear":82 return t;83 case "ease-in":84 return t * t;85 case "ease-in-out":86 return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;87 case "ease-out":88 default:89 return t * (2 - t);90 }91 },92 [easing]93 );9495 useEffect(() => {96 const canvas = canvasRef.current;97 if (!canvas) return;98 const ctx = canvas.getContext("2d");99 if (!ctx) return;100101 let animationId: number;102103 const draw = (timestamp: number) => {104// … truncated
What it pulls in
npm packages
Files it writes
More from obsidianui
All 111 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ai-inputai-input | obsidianui | Components | Free | 2 deps | |
| alertalert | obsidianui | Components | Free | no deps | |
| animated-tab-baranimated-tab-bar | obsidianui | Components | Free | no deps | |
| apple-spotlightapple-spotlight | obsidianui | Components | Free | 2 deps | |
| avataravatar | obsidianui | Components | Free | 1 dep | |
| badgebadge | obsidianui | Components | Free | 1 dep | |
| breadcrumbbreadcrumb | obsidianui | Components | Free | 2 deps | |
| buttonbutton | obsidianui | Components | Free | 1 dep |
