1import{$ as C,r as g,j as e,B as x,T as R,F as S}from"./index-CQKK0Imd.js";import{u as w,C as T,T as b,P as y,O as z,a as E,b as F,c as P}from"./useComponentProps-CEvMaZsz.js";import{u as M}from"./useForceRerender-DWXB3a6h.js";import{P as s}from"./PreviewSlider-Ch78y-a-.js";import{P as I}from"./PreviewColorPickerCustom-CxB8ex0e.js";import{C as j}from"./Customize-D9LDBJtX.js";import A from"./ClickSpark-D5xBVByV.js";import"./index-2zoGWYkB.js";import"./backgroundThemeProps-DVgeaD0m.js";import"./ShikiCode-C19L5K1F.js";import"./aiExport-CBeFnU7D.js";import"./IconSelect-D5LzCXat.js";import"./sparkles-Df4Xp1Rb.js";import"./file-code-2-CTN1MbwE.js";import"./useScrubGesture-Db-j4kh3.js";import"./preview-slider-zh8UBlwx.js";const L=`import { useRef, useEffect, useCallback } from 'react'; 2 3const ClickSpark = ({ 4 sparkColor = '#fff', 5 sparkSize = 10, 6 sparkRadius = 15, 7 sparkCount = 8, 8 duration = 400, 9 easing = 'ease-out', 10 extraScale = 1.0, 11 children 12}) => { 13 const canvasRef = useRef(null); 14 const sparksRef = useRef([]); 15 const startTimeRef = useRef(null); 16 17 useEffect(() => { 18 const canvas = canvasRef.current; 19 if (!canvas) return; 20 21 const parent = canvas.parentElement; 22 if (!parent) return; 23 24 let resizeTimeout; 25 26 const resizeCanvas = () => { 27 const { width, height } = parent.getBoundingClientRect(); 28 if (canvas.width !== width || canvas.height !== height) { 29 canvas.width = width; 30 canvas.height = height; 31 } 32 }; 33 34 const handleResize = () => { 35 clearTimeout(resizeTimeout); 36 resizeTimeout = setTimeout(resizeCanvas, 100); 37 }; 38 39 const ro = new ResizeObserver(handleResize); 40 ro.observe(parent); 41 42 resizeCanvas(); 43 44 return () => { 45 ro.disconnect(); 46 clearTimeout(resizeTimeout); 47 }; 48 }, []); 49 50 const easeFunc = useCallback( 51 t => { 52 switch (easing) { 53 case 'linear': 54 return t; 55 case 'ease-in': 56 return t * t; 57 case 'ease-in-out': 58 return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; 59 default: 60 return t * (2 - t); 61 } 62 }, 63 [easing] 64 ); 65 66 useEffect(() => { 67 const canvas = canvasRef.current; 68 if (!canvas) return; 69 const ctx = canvas.getContext('2d'); 70 71 let animationId; 72 73 const draw = timestamp => { 74 if (!startTimeRef.current) { 75 startTimeRef.current = timestamp; 76 } 77 ctx.clearRect(0, 0, canvas.width, canvas.height); 78 79 sparksRef.current = sparksRef.current.filter(spark => { 80 const elapsed = timestamp - spark.startTime; 81 if (elapsed >= duration) { 82 return false; 83 } 84 85 const progress = elapsed / duration; 86 const eased = easeFunc(progress); 87 88 const distance = eased * sparkRadius * extraScale; 89 const lineLength = sparkSize * (1 - eased); 90 91 const x1 = spark.x + distance * Math.cos(spark.angle); 92 const y1 = spark.y + distance * Math.sin(spark.angle); 93 const x2 = spark.x + (distance + lineLength) * Math.cos(spark.angle); 94 const y2 = spark.y + (distance + lineLength) * Math.sin(spark.angle); 95 96 ctx.strokeStyle = sparkColor; 97 ctx.lineWidth = 2; 98 ctx.beginPath(); 99 ctx.moveTo(x1, y1); 100 ctx.lineTo(x2, y2); 101 ctx.stroke(); 102 103 return true; 104 }); 105 106 animationId = requestAnimationFrame(draw); 107 }; 108 109 animationId = requestAnimationFrame(draw); 110 111 return () => { 112 cancelAnimationFrame(animationId); 113 }; 114 }, [sparkColor, sparkSize, sparkRadius, sparkCount, duration, easeFunc, extraScale]); 115 116 const handleClick = e => { 117 const canvas = canvasRef.current; 118 if (!canvas) return; 119 const rect = canvas.getBoundingClientRect(); 120 const x = e.clientX - rect.left; 121 const y = e.clientY - rect.top; 122 123 const now = performance.now(); 124 const newSparks = Array.from({ length: sparkCount }, (_, i) => ({ 125 x, 126 y, 127 angle: (2 * Math.PI * i) / sparkCount, 128 startTime: now 129 })); 130 131 sparksRef.current.push(...newSparks); 132 }; 133 134 return ( 135 <div 136 style={{ 137 position: 'relative', 138 width: '100%', 139 height: '100%' 140 }} 141 onClick={handleClick} 142 > 143 <canvas 144 ref={canvasRef} 145 style={{ 146 width: '100%', 147 height: '100%', 148 display: 'block', 149 userSelect: 'none', 150 position: 'absolute', 151 top: 0, 152 left: 0, 153 pointerEvents: 'none' 154 }} 155 /> 156 {children} 157 </div> 158 ); 159}; 160 161export default ClickSpark; 162`,B=`import { useRef, useEffect, useCallback } from 'react'; 163 164const ClickSpark = ({ 165 sparkColor = '#fff', 166 sparkSize = 10, 167 sparkRadius = 15, 168 sparkCount = 8, 169 duration = 400, 170 easing = 'ease-out', 171 extraScale = 1.0, 172 children 173}) => { 174 const canvasRef = useRef(null); 175 const sparksRef = useRef([]); 176 const startTimeRef = useRef(null); 177 178 useEffect(() => { 179 const canvas = canvasRef.current; 180 if (!canvas) return; 181 182 const parent = canvas.parentElement; 183 if (!parent) return; 184 185 let resizeTimeout; 186 187 const resizeCanvas = () => { 188 const { width, height } = parent.getBoundingClientRect(); 189 if (canvas.width !== width || canvas.height !== height) { 190 canvas.width = width; 191 canvas.height = height; 192 } 193 }; 194 195 const handleResize = () => { 196 clearTimeout(resizeTimeout); 197 resizeTimeout = setTimeout(resizeCanvas, 100); 198 }; 199
200 const ro = new ResizeObserver(handleResize); 201 ro.observe(parent); 202 203 resizeCanvas(); 204 205 return () => { 206 ro.disconnect(); 207 clearTimeout(resizeTimeout); 208 }; 209 }, []); 210 211 const easeFunc = useCallback( 212 t => { 213 switch (easing) { 214 case 'linear': 215 return t; 216 case 'ease-in': 217 return t * t; 218 case 'ease-in-out': 219 return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; 220 default: 221 return t * (2 - t); 222 } 223 }, 224 [easing] 225 ); 226 227 useEffect(() => { 228 const canvas = canvasRef.current; 229 if (!canvas) return; 230 const ctx = canvas.getContext('2d'); 231 232 let animationId; 233 234 const draw = timestamp => { 235 if (!startTimeRef.current) { 236 startTimeRef.current = timestamp; 237 } 238 ctx.clearRect(0, 0, canvas.width, canvas.height); 239 240 sparksRef.current = sparksRef.current.filter(spark => { 241 const elapsed = timestamp - spark.startTime; 242 if (elapsed >= duration) { 243 return false; 244 } 245 246 const progress = elapsed / duration; 247 const eased = easeFunc(progress); 248 249 const distance = eased * sparkRadius * extraScale; 250 const lineLength = sparkSize * (1 - eased); 251 252 const x1 = spark.x + distance * Math.cos(spark.angle); 253 const y1 = spark.y + distance * Math.sin(spark.angle); 254 const x2 = spark.x + (distance + lineLength) * Math.cos(spark.angle); 255 const y2 = spark.y + (distance + lineLength) * Math.sin(spark.angle); 256 257 ctx.strokeStyle = sparkColor; 258 ctx.lineWidth = 2; 259 ctx.beginPath(); 260 ctx.moveTo(x1, y1); 261 ctx.lineTo(x2, y2); 262 ctx.stroke(); 263 264 return true; 265 }); 266 267 animationId = requestAnimationFrame(draw); 268 }; 269 270 animationId = requestAnimationFrame(draw); 271 272 return () => { 273 cancelAnimationFrame(animationId); 274 }; 275 }, [sparkColor, sparkSize, sparkRadius, sparkCount, duration, easeFunc, extraScale]); 276 277 const handleClick = e => { 278 const canvas = canvasRef.current; 279 if (!canvas) return; 280 const rect = canvas.getBoundingClientRect(); 281 const x = e.clientX - rect.left; 282 const y = e.clientY - rect.top; 283 284 const now = performance.now(); 285 const newSparks = Array.from({ length: sparkCount }, (_, i) => ({ 286 x, 287 y, 288 angle: (2 * Math.PI * i) / sparkCount, 289 startTime: now 290 })); 291 292 sparksRef.current.push(...newSparks); 293 }; 294 295 return ( 296 <div className="relative w-full h-full" onClick={handleClick}> 297 <canvas ref={canvasRef} className="w-full h-full block absolute top-0 left-0 select-none pointer-events-none" /> 298 {children} 299 </div> 300 ); 301}; 302 303export default ClickSpark; 304`,N=`import React, { useRef, useEffect, useCallback } from 'react'; 305 306interface ClickSparkProps { 307 sparkColor?: string; 308 sparkSize?: number; 309 sparkRadius?: number; 310 sparkCount?: number; 311 duration?: number; 312 easing?: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out'; 313 extraScale?: number; 314 children?: React.ReactNode; 315} 316 317interface Spark { 318 x: number; 319 y: number; 320 angle: number; 321 startTime: number; 322} 323 324const ClickSpark: React.FC<ClickSparkProps> = ({ 325 sparkColor = '#fff', 326 sparkSize = 10, 327 sparkRadius = 15, 328 sparkCount = 8, 329 duration = 400, 330 easing = 'ease-out', 331 extraScale = 1.0, 332 children 333}) => { 334 const canvasRef = useRef<HTMLCanvasElement>(null); 335 const sparksRef = useRef<Spark[]>([]); 336 const startTimeRef = useRef<number | null>(null); 337 338 useEffect(() => { 339 const canvas = canvasRef.current; 340 if (!canvas) return; 341 342 const parent = canvas.parentElement; 343 if (!parent) return; 344 345 let resizeTimeout: ReturnType<typeof setTimeout>; 346 347 const resizeCanvas = () => { 348 const { width, height } = parent.getBoundingClientRect(); 349 if (canvas.width !== width || canvas.height !== height) { 350 canvas.width = width; 351 canvas.height = height; 352 } 353 }; 354 355 const handleResize = () => { 356 clearTimeout(resizeTimeout); 357 resizeTimeout = setTimeout(resizeCanvas, 100); 358 }; 359 360 const ro = new ResizeObserver(handleResize); 361 ro.observe(parent); 362 363 resizeCanvas(); 364 365 return () => { 366 ro.disconnect(); 367 clearTimeout(resizeTimeout); 368 }; 369 }, []); 370 371 const easeFunc = useCallback( 372 (t: number) => { 373 switch (easing) { 374 case 'linear': 375 return t; 376 case 'ease-in': 377 return t * t; 378 case 'ease-in-out': 379 return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; 380 default: 381 return t * (2 - t); 382 } 383 }, 384 [easing] 385 ); 386 387 useEffect(() => { 388 const canvas = canvasRef.current; 389 if (!canvas) return; 390 const ctx = canvas.getContext('2d'); 391 if (!ctx) return; 392 393 let animationId: number; 394 395 const draw = (timestamp: number) => { 396 if (!startTimeRef.current) { 397 startTimeRef.current = timestamp; 398 } 399 ctx?.clearRect(0, 0, canvas.width, canvas.height); 400 401 sparksRef.current = sparksRef.current.filter((spark: Spark) => {
402 const elapsed = timestamp - spark.startTime; 403 if (elapsed >= duration) { 404 return false; 405 } 406 407 const progress = elapsed / duration; 408 const eased = easeFunc(progress); 409 410 const distance = eased * sparkRadius * extraScale; 411 const lineLength = sparkSize * (1 - eased); 412 413 const x1 = spark.x + distance * Math.cos(spark.angle); 414 const y1 = spark.y + distance * Math.sin(spark.angle); 415 const x2 = spark.x + (distance + lineLength) * Math.cos(spark.angle); 416 const y2 = spark.y + (distance + lineLength) * Math.sin(spark.angle); 417 418 ctx.strokeStyle = sparkColor; 419 ctx.lineWidth = 2; 420 ctx.beginPath(); 421 ctx.moveTo(x1, y1); 422 ctx.lineTo(x2, y2); 423 ctx.stroke(); 424 425 return true; 426 }); 427 428 animationId = requestAnimationFrame(draw); 429 }; 430 431 animationId = requestAnimationFrame(draw); 432 433 return () => { 434 cancelAnimationFrame(animationId); 435 }; 436 }, [sparkColor, sparkSize, sparkRadius, sparkCount, duration, easeFunc, extraScale]); 437 438 const handleClick = (e: React.MouseEvent<HTMLDivElement>): void => { 439 const canvas = canvasRef.current; 440 if (!canvas) return; 441 const rect = canvas.getBoundingClientRect(); 442 const x = e.clientX - rect.left; 443 const y = e.clientY - rect.top; 444 445 const now = performance.now(); 446 const newSparks: Spark[] = Array.from({ length: sparkCount }, (_, i) => ({ 447 x, 448 y, 449 angle: (2 * Math.PI * i) / sparkCount, 450 startTime: now 451 })); 452 453 sparksRef.current.push(...newSparks); 454 }; 455 456 return ( 457 <div 458 style={{ 459 width: '100%', 460 height: '100%', 461 position: 'relative' 462 }} 463 onClick={handleClick} 464 > 465 <canvas 466 ref={canvasRef} 467 style={{ 468 position: 'absolute', 469 inset: 0, 470 pointerEvents: 'none' 471 }} 472 /> 473 {children} 474 </div> 475 ); 476}; 477 478export default ClickSpark; 479`,q=`import React, { useRef, useEffect, useCallback } from 'react'; 480 481interface ClickSparkProps { 482 sparkColor?: string; 483 sparkSize?: number; 484 sparkRadius?: number; 485 sparkCount?: number; 486 duration?: number; 487 easing?: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out'; 488 extraScale?: number; 489 children?: React.ReactNode; 490} 491 492interface Spark { 493 x: number; 494 y: number; 495 angle: number; 496 startTime: number; 497} 498 499const ClickSpark: React.FC<ClickSparkProps> = ({ 500 sparkColor = '#fff', 501 sparkSize = 10, 502 sparkRadius = 15, 503 sparkCount = 8, 504 duration = 400, 505 easing = 'ease-out', 506 extraScale = 1.0, 507 children 508}) => { 509 const canvasRef = useRef<HTMLCanvasElement>(null); 510 const sparksRef = useRef<Spark[]>([]); 511 const startTimeRef = useRef<number | null>(null); 512 513 useEffect(() => { 514 const canvas = canvasRef.current; 515 if (!canvas) return; 516 517 const parent = canvas.parentElement; 518 if (!parent) return; 519 520 let resizeTimeout: ReturnType<typeof setTimeout>; 521 522 const resizeCanvas = () => { 523 const { width, height } = parent.getBoundingClientRect(); 524 if (canvas.width !== width || canvas.height !== height) { 525 canvas.width = width; 526 canvas.height = height; 527 } 528 }; 529 530 const handleResize = () => { 531 clearTimeout(resizeTimeout); 532 resizeTimeout = setTimeout(resizeCanvas, 100); 533 }; 534 535 const ro = new ResizeObserver(handleResize); 536 ro.observe(parent); 537 538 resizeCanvas(); 539 540 return () => { 541 ro.disconnect(); 542 clearTimeout(resizeTimeout); 543 }; 544 }, []); 545 546 const easeFunc = useCallback( 547 (t: number) => { 548 switch (easing) { 549 case 'linear': 550 return t; 551 case 'ease-in': 552 return t * t; 553 case 'ease-in-out': 554 return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; 555 default: 556 return t * (2 - t); 557 } 558 }, 559 [easing] 560 ); 561 562 useEffect(() => { 563 const canvas = canvasRef.current; 564 if (!canvas) return; 565 const ctx = canvas.getContext('2d'); 566 if (!ctx) return; 567 568 let animationId: number; 569 570 const draw = (timestamp: number) => { 571 if (!startTimeRef.current) { 572 startTimeRef.current = timestamp; 573 } 574 ctx?.clearRect(0, 0, canvas.width, canvas.height); 575 576 sparksRef.current = sparksRef.current.filter((spark: Spark) => {
577 const elapsed = timestamp - spark.startTime; 578 if (elapsed >= duration) { 579 return false; 580 } 581 582 const progress = elapsed / duration; 583 const eased = easeFunc(progress); 584 585 const distance = eased * sparkRadius * extraScale; 586 const lineLength = sparkSize * (1 - eased); 587 588 const x1 = spark.x + distance * Math.cos(spark.angle); 589 const y1 = spark.y + distance * Math.sin(spark.angle); 590 const x2 = spark.x + (distance + lineLength) * Math.cos(spark.angle); 591 const y2 = spark.y + (distance + lineLength) * Math.sin(spark.angle); 592 593 ctx.strokeStyle = sparkColor; 594 ctx.lineWidth = 2; 595 ctx.beginPath(); 596 ctx.moveTo(x1, y1); 597 ctx.lineTo(x2, y2); 598 ctx.stroke(); 599 600 return true; 601 }); 602 603 animationId = requestAnimationFrame(draw); 604 }; 605 606 animationId = requestAnimationFrame(draw); 607 608 return () => { 609 cancelAnimationFrame(animationId); 610 }; 611 }, [sparkColor, sparkSize, sparkRadius, sparkCount, duration, easeFunc, extraScale]); 612 613 const handleClick = (e: React.MouseEvent<HTMLDivElement>): void => { 614 const canvas = canvasRef.current; 615 if (!canvas) return; 616 const rect = canvas.getBoundingClientRect(); 617 const x = e.clientX - rect.left; 618 const y = e.clientY - rect.top; 619 620 const now = performance.now(); 621 const newSparks: Spark[] = Array.from({ length: sparkCount }, (_, i) => ({ 622 x, 623 y, 624 angle: (2 * Math.PI * i) / sparkCount, 625 startTime: now 626 })); 627 628 sparksRef.current.push(...newSparks); 629 }; 630 631 return ( 632 <div className="relative w-full h-full" onClick={handleClick}> 633 <canvas ref={canvasRef} className="absolute inset-0 pointer-events-none" /> 634 {children} 635 </div> 636 ); 637}; 638 639export default ClickSpark; 640`,O={usage:`import ClickSpark from './ClickSpark'; 641 642<ClickSpark 643 sparkColor='#fff' 644 sparkSize={10} 645 sparkRadius={15} 646 sparkCount={8} 647 duration={400} 648> 649 {/* Your content here */} 650</ClickSpark>`,code:L,tailwind:B,tsCode:N,tsTailwind:q},i={sparkColor:"#ffffff",sparkSize:10,sparkRadius:15,sparkCount:8,duration:400,extraScale:1},te=()=>{const{props:d,updateProp:t,resetProps:k,hasChanges:f}=w(i),{sparkColor:r,sparkSize:c,sparkRadius:o,sparkCount:u,duration:l,extraScale:p}=d,m=C(r===i.sparkColor?"#18181b":r,r),[h,a]=M(),v=g.useMemo(()=>[{name:"sparkColor",type:"string",default:"'#fff'",description:"Color of each spark line."},{name:"sparkSize",type:"number",default:10,description:"Initial length of each spark line."},{name:"sparkRadius",type:"number",default:15,description:"How far sparks travel from the click center."},{name:"sparkCount",type:"number",default:8,description:"Number of spark lines that appear on each click."},{name:"duration",type:"number",default:400,description:"Animation duration in milliseconds."},{name:"easing",type:"string",default:"'ease-out'",description:"Easing function used for the spark animation."},{name:"extraScale",type:"number",default:1,description:"Additional multiplier for spark distance."},{name:"children",type:"React.ReactNode",default:"",description:"React children to render."}],[]);return e.jsx(T,{props:d,defaultProps:i,resetProps:k,hasChanges:f,children:e.jsxs(b,{children:[e.jsxs(y,{children:[e.jsxs(x,{position:"relative",className:"demo-container",h:400,p:0,overflow:"hidden",children:[e.jsx(A,{sparkColor:m,sparkSize:c,sparkRadius:o,sparkCount:u,duration:l,extraScale:p},h),e.jsx(R,{position:"absolute",fontWeight:600,fontSize:"2rem",textAlign:"center",className:"demo-instruction",userSelect:"none",children:"Click Around!"})]}),e.jsx(S,{justify:"flex-end",mt:2,mb:-2,children:e.jsx(z,{backgroundId:"click-spark",currentProps:{sparkColor:r,sparkSize:c,sparkRadius:o,sparkCount:u,duration:l,extraScale:p},defaultProps:i})}),e.jsxs(j,{children:[e.jsx(I,{title:"Spark Color",color:m,onChange:n=>{t("sparkColor",n),a()}}),e.jsx(s,{title:"Spark Size",min:5,max:60,step:1,value:c,onChange:n=>{t("sparkSize",n),a()}}),e.jsx(s,{title:"Spark Radius",min:10,max:200,step:5,value:o,onChange:n=>{t("sparkRadius",n),a()}}),e.jsx(s,{title:"Spark Count",min:1,max:20,step:1,value:u,onChange:n=>{t("sparkCount",n),a()}}),e.jsx(s,{title:"Duration",min:200,max:2e3,step:100,value:l,valueUnit:"ms",onChange:n=>{t("duration",n),a()}}),e.jsx(s,{title:"Extra Scale",min:.5,max:2,step:.1,value:p,onChange:n=>{t("extraScale",n),a()}})]}),e.jsx(E,{data:v})]}),e.jsx(F,{children:e.jsx(P,{codeObject:O,componentName:"ClickSpark"})})]})})};export{te as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.