PageSourceSearch

https://reactbits.dev/assets/DecayCardDemo-DbLLdI6x.js

js reactbits.dev collected 2026-09-25 14:14:43 UTC 26,954 bytes, 679 lines download raw bytes

1import{r as d,j as e,a1 as V,B as E,T as X}from"./index-CQKK0Imd.js";import{u as j,C as q,T as A,P as L,a as N,b as O,c as H}from"./useComponentProps-CEvMaZsz.js";import{C as P}from"./Customize-D9LDBJtX.js";import{P as u}from"./PreviewSlider-Ch78y-a-.js";import{D as W}from"./Dependencies-Bm-Pofg-.js";import{u as I}from"./useForceRerender-DWXB3a6h.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"./preview-slider-zh8UBlwx.js";import"./useScrubGesture-Db-j4kh3.js";import"./copy-DhagMDuz.js";const $=({width:w=300,height:o=400,image:R="https://picsum.photos/300/400?grayscale",baseFrequency:M=.015,numOctaves:v=5,seed:x=4,maxDisplacement:f=400,movementBound:r=50,children:y})=>{const l=d.useRef(null),g=d.useRef(null),a=d.useRef({x:typeof window<"u"?window.innerWidth/2:0,y:typeof window<"u"?window.innerHeight/2:0}),c=d.useRef({...a.current}),h=d.useRef({width:typeof window<"u"?window.innerWidth:0,height:typeof window<"u"?window.innerHeight:0});return d.useEffect(()=>{const t=(n,i,m)=>(1-m)*n+m*i,b=(n,i,m,p,T)=>(n-i)*(T-p)/(m-i)+p,Y=(n,i,m,p)=>{const T=n-i,S=m-p;return Math.hypot(T,S)},z=()=>{h.current={width:window.innerWidth,height:window.innerHeight}},C=n=>{a.current={x:n.clientX,y:n.clientY}};window.addEventListener("resize",z),window.addEventListener("mousemove",C);const s={imgTransforms:{x:0,y:0,rz:0},displacementScale:0},B=()=>{let n=t(s.imgTransforms.x,b(a.current.x,0,h.current.width,-120,120),.1),i=t(s.imgTransforms.y,b(a.current.y,0,h.current.height,-120,120),.1),m=t(s.imgTransforms.rz,b(a.current.x,0,h.current.width,-10,10),.1);n>r&&(n=r+(n-r)*.2),n<-r&&(n=-r+(n+r)*.2),i>r&&(i=r+(i-r)*.2),i<-r&&(i=-r+(i+r)*.2),s.imgTransforms.x=n,s.imgTransforms.y=i,s.imgTransforms.rz=m,l.current&&V.set(l.current,{x:s.imgTransforms.x,y:s.imgTransforms.y,rotateZ:s.imgTransforms.rz});const p=Y(c.current.x,a.current.x,c.current.y,a.current.y);s.displacementScale=t(s.displacementScale,b(p,0,200,0,f),.06),g.current&&V.set(g.current,{attr:{scale:s.displacementScale}}),c.current={...a.current},D=requestAnimationFrame(B)};let D=requestAnimationFrame(B);return()=>{cancelAnimationFrame(D),window.removeEventListener("resize",z),window.removeEventListener("mousemove",C)}},[f,r]),e.jsxs("div",{className:"content",style:{width:`${w}px`,height:`${o}px`},ref:l,children:[e.jsxs("svg",{viewBox:"-60 -75 720 900",preserveAspectRatio:"xMidYMid slice",className:"svg",children:[e.jsxs("filter",{id:"imgFilter",children:[e.jsx("feTurbulence",{type:"turbulence",baseFrequency:M,numOctaves:v,seed:x,stitchTiles:"stitch",x:"0%",y:"0%",width:"100%",height:"100%",result:"turbulence1"}),e.jsx("feDisplacementMap",{ref:g,in:"SourceGraphic",in2:"turbulence1",scale:"0",xChannelSelector:"R",yChannelSelector:"B",x:"0%",y:"0%",width:"100%",height:"100%",result:"displacementMap3"})]}),e.jsx("g",{children:e.jsx("image",{href:R,x:"0",y:"0",width:"600",height:"750",filter:"url(#imgFilter)",preserveAspectRatio:"xMidYMid slice"})})]}),e.jsx("div",{className:"card-text",children:y})]})},k=`import { useEffect, useRef } from 'react';
2import { gsap } from 'gsap';
3
4import './DecayCard.css';
5
6const DecayCard = ({
7  width = 300,
8  height = 400,
9  image = 'https://picsum.photos/300/400?grayscale',
10  baseFrequency = 0.015,
11  numOctaves = 5,
12  seed = 4,
13  maxDisplacement = 400,
14  movementBound = 50,
15  children
16}) => {
17  const svgRef = useRef(null);
18  const displacementMapRef = useRef(null);
19  const cursor = useRef({
20    x: typeof window !== 'undefined' ? window.innerWidth / 2 : 0,
21    y: typeof window !== 'undefined' ? window.innerHeight / 2 : 0
22  });
23  const cachedCursor = useRef({ ...cursor.current });
24  const winsize = useRef({
25    width: typeof window !== 'undefined' ? window.innerWidth : 0,
26    height: typeof window !== 'undefined' ? window.innerHeight : 0
27  });
28
29  useEffect(() => {
30    const lerp = (a, b, n) => (1 - n) * a + n * b;
31
32    const map = (x, a, b, c, d) => ((x - a) * (d - c)) / (b - a) + c;
33
34    const distance = (x1, x2, y1, y2) => {
35      const a = x1 - x2;
36      const b = y1 - y2;
37      return Math.hypot(a, b);
38    };
39
40    const handleResize = () => {
41      winsize.current = { width: window.innerWidth, height: window.innerHeight };
42    };
43
44    const handleMouseMove = ev => {
45      cursor.current = { x: ev.clientX, y: ev.clientY };
46    };
47
48    window.addEventListener('resize', handleResize);
49    window.addEventListener('mousemove', handleMouseMove);
50
51    const imgValues = {
52      imgTransforms: { x: 0, y: 0, rz: 0 },
53      displacementScale: 0
54    };
55
56    const render = () => {
57      let targetX = lerp(imgValues.imgTransforms.x, map(cursor.current.x, 0, winsize.current.width, -120, 120), 0.1);
58      let targetY = lerp(imgValues.imgTransforms.y, map(cursor.current.y, 0, winsize.current.height, -120, 120), 0.1);
59      let targetRz = lerp(imgValues.imgTransforms.rz, map(cursor.current.x, 0, winsize.current.width, -10, 10), 0.1);
60
61      if (targetX > movementBound) targetX = movementBound + (targetX - movementBound) * 0.2;
62      if (targetX < -movementBound) targetX = -movementBound + (targetX + movementBound) * 0.2;
63      if (targetY > movementBound) targetY = movementBound + (targetY - movementBound) * 0.2;
64      if (targetY < -movementBound) targetY = -movementBound + (targetY + movementBound) * 0.2;
65
66      imgValues.imgTransforms.x = targetX;
67      imgValues.imgTransforms.y = targetY;
68      imgValues.imgTransforms.rz = targetRz;
69
70      if (svgRef.current) {
71        gsap.set(svgRef.current, {
72          x: imgValues.imgTransforms.x,
73          y: imgValues.imgTransforms.y,
74          rotateZ: imgValues.imgTransforms.rz
75        });
76      }
77
78      const cursorTravelledDistance = distance(
79        cachedCursor.current.x,
80        cursor.current.x,
81        cachedCursor.current.y,
82        cursor.current.y
83      );
84      imgValues.displacementScale = lerp(
85        imgValues.displacementScale,
86        map(cursorTravelledDistance, 0, 200, 0, maxDisplacement),
87        0.06
88      );
89
90      if (displacementMapRef.current) {
91        gsap.set(displacementMapRef.current, { attr: { scale: imgValues.displacementScale } });
92      }
93
94      cachedCursor.current = { ...cursor.current };
95
96      rafId = requestAnimationFrame(render);
97    };
98
99    let rafId = requestAnimationFrame(render);
100
101    return () => {
102      cancelAnimationFrame(rafId);
103      window.removeEventListener('resize', handleResize);
104      window.removeEventListener('mousemove', handleMouseMove);
105    };
106  }, [maxDisplacement, movementBound]);
107
108  return (
109    <div className="content" style={{ width: \`\${width}px\`, height: \`\${height}px\` }} ref={svgRef}>
110      <svg viewBox="-60 -75 720 900" preserveAspectRatio="xMidYMid slice" className="svg">
111        <filter id="imgFilter">
112          <feTurbulence
113            type="turbulence"
114            baseFrequency={baseFrequency}
115            numOctaves={numOctaves}
116            seed={seed}
117            stitchTiles="stitch"
118            x="0%"
119            y="0%"
120            width="100%"
121            height="100%"
122            result="turbulence1"
123          />
124          <feDisplacementMap
125            ref={displacementMapRef}
126            in="SourceGraphic"
127            in2="turbulence1"
128            scale="0"
129            xChannelSelector="R"
130            yChannelSelector="B"
131            x="0%"
132            y="0%"
133            width="100%"
134            height="100%"
135            result="displacementMap3"
136          />
137        </filter>
138        <g>
139          <image
140            href={image}
141            x="0"
142            y="0"
143            width="600"
144            height="750"
145            filter="url(#imgFilter)"
146            preserveAspectRatio="xMidYMid slice"
147          />
148        </g>
149      </svg>
150      <div className="card-text">{children}</div>
151    </div>
152  );
153};
154
155export default DecayCard;
156`,G=`.content {
157  position: relative;
158}
159
160.svg {
161  position: relative;
162  width: 100%;
163  height: 100%;
164  display: block;
165  will-change: transform;
166}
167
168.card-text {
169  position: absolute;
170  bottom: 1.2em;
171  letter-spacing: -0.5px;
172  font-weight: 900;
173  left: 1em;
174  font-size: 2.5rem;
175  line-height: 1.5em;
176}
177
178.card-text::first-line {
179  font-size: 4rem;
180}
181`,Z=`import { useEffect, useRef } from 'react';
182import { gsap } from 'gsap';
183
184const DecayCard = ({
185  width = 300,
186  height = 400,
187  image = 'https://picsum.photos/300/400?grayscale',
188  baseFrequency = 0.015,
189  numOctaves = 5,
190  seed = 4,
191  maxDisplacement = 400,
192  movementBound = 50,
193  children
194}) => {
195  const svgRef = useRef(null);
196  const displacementMapRef = useRef(null);
197  const cursor = useRef({
198    x: typeof window !== 'undefined' ? window.innerWidth / 2 : 0,
199    y: typeof window !== 'undefined' ? window.innerHeight / 2 : 0
200  });
201  const cachedCursor = useRef({ ...cursor.current });
202  const winsize = useRef({
203    width: typeof window !== 'undefined' ? window.innerWidth : 0,
204    height: typeof window !== 'undefined' ? window.innerHeight : 0
205  });
206
207  useEffect(() => {
208    const lerp = (a, b, n) => (1 - n) * a + n * b;
209    const map = (x, a, b, c, d) => ((x - a) * (d - c)) / (b - a) + c;
210    const distance = (x1, x2, y1, y2) => Math.hypot(x1 - x2, y1 - y2);
211
212    const handleResize = () => {
213      winsize.current = { width: window.innerWidth, height: window.innerHeight };
214    };
215
216    const handleMouseMove = ev => {
217      cursor.current = { x: ev.clientX, y: ev.clientY };
218    };
219
220    window.addEventListener('resize', handleResize);
221    window.addEventListener('mousemove', handleMouseMove);
222
223    const imgValues = {
224      imgTransforms: { x: 0, y: 0, rz: 0 },
225      displacementScale: 0
226    };
227
228    const render = () => {
229      let targetX = lerp(imgValues.imgTransforms.x, map(cursor.current.x, 0, winsize.current.width, -120, 120), 0.1);
230      let targetY = lerp(imgValues.imgTransforms.y, map(cursor.current.y, 0, winsize.current.height, -120, 120), 0.1);
231      let targetRz = lerp(imgValues.imgTransforms.rz, map(cursor.current.x, 0, winsize.current.width, -10, 10), 0.1);
232
233      if (targetX > movementBound) targetX = movementBound + (targetX - movementBound) * 0.2;
234      if (targetX < -movementBound) targetX = -movementBound + (targetX + movementBound) * 0.2;
235      if (targetY > movementBound) targetY = movementBound + (targetY - movementBound) * 0.2;
236      if (targetY < -movementBound) targetY = -movementBound + (targetY + movementBound) * 0.2;
237
238      imgValues.imgTransforms.x = targetX;
239      imgValues.imgTransforms.y = targetY;
240      imgValues.imgTransforms.rz = targetRz;
241
242      if (svgRef.current) {
243        gsap.set(svgRef.current, {
244          x: imgValues.imgTransforms.x,
245          y: imgValues.imgTransforms.y,
246          rotateZ: imgValues.imgTransforms.rz
247        });
248      }
249
250      const cursorTravelledDistance = distance(
251        cachedCursor.current.x,
252        cursor.current.x,
253        cachedCursor.current.y,
254        cursor.current.y
255      );
256      imgValues.displacementScale = lerp(
257        imgValues.displacementScale,
258        map(cursorTravelledDistance, 0, 200, 0, maxDisplacement),
259        0.06
260      );
261
262      if (displacementMapRef.current) {
263        gsap.set(displacementMapRef.current, { attr: { scale: imgValues.displacementScale } });
264      }
265
266      cachedCursor.current = { ...cursor.current };
267
268      rafId = requestAnimationFrame(render);
269    };
270
271    let rafId = requestAnimationFrame(render);
272
273    return () => {
274      cancelAnimationFrame(rafId);
275      window.removeEventListener('resize', handleResize);
276      window.removeEventListener('mousemove', handleMouseMove);
277    };
278  }, [maxDisplacement, movementBound]);
279
280  return (
281    <div ref={svgRef} className="relative" style={{ width: \`\${width}px\`, height: \`\${height}px\` }}>
282      <svg
283        viewBox="-60 -75 720 900"
284        preserveAspectRatio="xMidYMid slice"
285        className="relative w-full h-full block [will-change:transform]"
286      >
287        <filter id="imgFilter">
288          <feTurbulence
289            type="turbulence"
290            baseFrequency={baseFrequency}
291            numOctaves={numOctaves}
292            seed={seed}
293            stitchTiles="stitch"
294            x="0%"
295            y="0%"
296            width="100%"
297            height="100%"
298            result="turbulence1"
299          />
300          <feDisplacementMap
301            ref={displacementMapRef}
302            in="SourceGraphic"
303            in2="turbulence1"
304            scale="0"
305            xChannelSelector="R"
306            yChannelSelector="B"
307            x="0%"
308            y="0%"
309            width="100%"
310            height="100%"
311            result="displacementMap3"
312          />
313        </filter>
314        <g>
315          <image
316            href={image}
317            x="0"
318            y="0"
319            width="600"
320            height="750"
321            filter="url(#imgFilter)"
322            preserveAspectRatio="xMidYMid slice"
323          />
324        </g>
325      </svg>
326      <div className="absolute bottom-[1.2em] left-[1em] tracking-[-0.5px] font-black text-[2.5rem] leading-[1.5em] first-line:text-[6rem]">
327        {children}
328      </div>
329    </div>
330  );
331};
332
333export default DecayCard;
334`,J=`import React, { useEffect, useRef, type ReactNode } from 'react';
335import { gsap } from 'gsap';
336import './DecayCard.css';
337
338interface DecayCardProps {
339  width?: number;
340  height?: number;
341  image?: string;
342  baseFrequency?: number;
343  numOctaves?: number;
344  seed?: number;
345  maxDisplacement?: number;
346  movementBound?: number;
347  children?: ReactNode;
348}
349
350const DecayCard: React.FC<DecayCardProps> = ({
351  width = 300,
352  height = 400,
353  image = 'https://picsum.photos/300/400?grayscale',
354  baseFrequency = 0.015,
355  numOctaves = 5,
356  seed = 4,
357  maxDisplacement = 400,
358  movementBound = 50,
359  children
360}) => {
361  const svgRef = useRef<HTMLDivElement>(null);
362  const displacementMapRef = useRef<SVGFEDisplacementMapElement>(null);
363  const cursor = useRef<{ x: number; y: number }>({
364    x: typeof window !== 'undefined' ? window.innerWidth / 2 : 0,
365    y: typeof window !== 'undefined' ? window.innerHeight / 2 : 0
366  });
367  const cachedCursor = useRef<{ x: number; y: number }>({ ...cursor.current });
368  const winsize = useRef<{ width: number; height: number }>({
369    width: typeof window !== 'undefined' ? window.innerWidth : 0,
370    height: typeof window !== 'undefined' ? window.innerHeight : 0
371  });
372
373  useEffect(() => {
374    const lerp = (a: number, b: number, n: number): number => (1 - n) * a + n * b;
375
376    const map = (x: number, a: number, b: number, c: number, d: number): number => ((x - a) * (d - c)) / (b - a) + c;
377
378    const distance = (x1: number, x2: number, y1: number, y2: number): number => {
379      const a = x1 - x2;
380      const b = y1 - y2;
381      return Math.hypot(a, b);
382    };
383
384    const handleResize = (): void => {
385      winsize.current = {
386        width: window.innerWidth,
387        height: window.innerHeight
388      };
389    };
390
391    const handleMouseMove = (ev: MouseEvent): void => {
392      cursor.current = { x: ev.clientX, y: ev.clientY };
393    };
394
395    window.addEventListener('resize', handleResize);
396    window.addEventListener('mousemove', handleMouseMove);
397
398    const imgValues = {
399      imgTransforms: { x: 0, y: 0, rz: 0 },
400      displacementScale: 0
401    };
402
403    const render = () => {
404      let targetX = lerp(imgValues.imgTransforms.x, map(cursor.current.x, 0, winsize.current.width, -120, 120), 0.1);
405      let targetY = lerp(imgValues.imgTransforms.y, map(cursor.current.y, 0, winsize.current.height, -120, 120), 0.1);
406      let targetRz = lerp(imgValues.imgTransforms.rz, map(cursor.current.x, 0, winsize.current.width, -10, 10), 0.1);
407
408      if (targetX > movementBound) targetX = movementBound + (targetX - movementBound) * 0.2;
409      if (targetX < -movementBound) targetX = -movementBound + (targetX + movementBound) * 0.2;
410      if (targetY > movementBound) targetY = movementBound + (targetY - movementBound) * 0.2;
411      if (targetY < -movementBound) targetY = -movementBound + (targetY + movementBound) * 0.2;
412
413      imgValues.imgTransforms.x = targetX;
414      imgValues.imgTransforms.y = targetY;
415      imgValues.imgTransforms.rz = targetRz;
416
417      if (svgRef.current) {
418        gsap.set(svgRef.current, {
419          x: imgValues.imgTransforms.x,
420          y: imgValues.imgTransforms.y,
421          rotateZ: imgValues.imgTransforms.rz
422        });
423      }
424
425      const cursorTravelledDistance = distance(
426        cachedCursor.current.x,
427        cursor.current.x,
428        cachedCursor.current.y,
429        cursor.current.y
430      );
431      imgValues.displacementScale = lerp(
432        imgValues.displacementScale,
433        map(cursorTravelledDistance, 0, 200, 0, maxDisplacement),
434        0.06
435      );
436
437      if (displacementMapRef.current) {
438        gsap.set(displacementMapRef.current, {
439          attr: { scale: imgValues.displacementScale }
440        });
441      }
442
443      cachedCursor.current = { ...cursor.current };
444
445      rafId = requestAnimationFrame(render);
446    };
447
448    let rafId = requestAnimationFrame(render);
449
450    return () => {
451      cancelAnimationFrame(rafId);
452      window.removeEventListener('resize', handleResize);
453      window.removeEventListener('mousemove', handleMouseMove);
454    };
455  }, [maxDisplacement, movementBound]);
456
457  return (
458    <div className="content" style={{ width: \`\${width}px\`, height: \`\${height}px\` }} ref={svgRef}>
459      <svg viewBox="-60 -75 720 900" preserveAspectRatio="xMidYMid slice" className="svg">
460        <filter id="imgFilter">
461          <feTurbulence
462            type="turbulence"
463            baseFrequency={baseFrequency}
464            numOctaves={numOctaves}
465            seed={seed}
466            stitchTiles="stitch"
467            x="0%"
468            y="0%"
469            width="100%"
470            height="100%"
471            result="turbulence1"
472          />
473          <feDisplacementMap
474            ref={displacementMapRef}
475            in="SourceGraphic"
476            in2="turbulence1"
477            scale="0"
478            xChannelSelector="R"
479            yChannelSelector="B"
480            x="0%"
481            y="0%"
482            width="100%"
483            height="100%"
484            result="displacementMap3"
485          />
486        </filter>
487        <g>
488          <image
489            href={image}
490            x="0"
491            y="0"
492            width="600"
493            height="750"
494            filter="url(#imgFilter)"
495            preserveAspectRatio="xMidYMid slice"
496          />
497        </g>
498      </svg>
499      <div className="card-text">{children}</div>
500    </div>
501  );
502};
503
504export default DecayCard;
505`,U=`import React, { useEffect, useRef, type ReactNode } from 'react';
506import { gsap } from 'gsap';
507
508interface DecayCardProps {
509  width?: number;
510  height?: number;
511  image?: string;
512  baseFrequency?: number;
513  numOctaves?: number;
514  seed?: number;
515  maxDisplacement?: number;
516  movementBound?: number;
517  children?: ReactNode;
518}
519
520const DecayCard: React.FC<DecayCardProps> = ({
521  width = 300,
522  height = 400,
523  image = 'https://picsum.photos/300/400?grayscale',
524  baseFrequency = 0.015,
525  numOctaves = 5,
526  seed = 4,
527  maxDisplacement = 400,
528  movementBound = 50,
529  children
530}) => {
531  const svgRef = useRef<HTMLDivElement | null>(null);
532  const displacementMapRef = useRef<SVGFEDisplacementMapElement | null>(null);
533  const cursor = useRef<{ x: number; y: number }>({
534    x: typeof window !== 'undefined' ? window.innerWidth / 2 : 0,
535    y: typeof window !== 'undefined' ? window.innerHeight / 2 : 0
536  });
537  const cachedCursor = useRef<{ x: number; y: number }>({ ...cursor.current });
538  const winsize = useRef<{ width: number; height: number }>({
539    width: typeof window !== 'undefined' ? window.innerWidth : 0,
540    height: typeof window !== 'undefined' ? window.innerHeight : 0
541  });
542
543  useEffect(() => {
544    const lerp = (a: number, b: number, n: number): number => (1 - n) * a + n * b;
545    const map = (x: number, a: number, b: number, c: number, d: number): number => ((x - a) * (d - c)) / (b - a) + c;
546    const distance = (x1: number, x2: number, y1: number, y2: number): number => Math.hypot(x1 - x2, y1 - y2);
547
548    const handleResize = (): void => {
549      winsize.current = {
550        width: window.innerWidth,
551        height: window.innerHeight
552      };
553    };
554
555    const handleMouseMove = (ev: MouseEvent): void => {
556      cursor.current = { x: ev.clientX, y: ev.clientY };
557    };
558
559    window.addEventListener('resize', handleResize);
560    window.addEventListener('mousemove', handleMouseMove);
561
562    const imgValues = {
563      imgTransforms: { x: 0, y: 0, rz: 0 },
564      displacementScale: 0
565    };
566
567    const render = () => {
568      let targetX = lerp(imgValues.imgTransforms.x, map(cursor.current.x, 0, winsize.current.width, -120, 120), 0.1);
569      let targetY = lerp(imgValues.imgTransforms.y, map(cursor.current.y, 0, winsize.current.height, -120, 120), 0.1);
570      let targetRz = lerp(imgValues.imgTransforms.rz, map(cursor.current.x, 0, winsize.current.width, -10, 10), 0.1);
571
572      if (targetX > movementBound) targetX = movementBound + (targetX - movementBound) * 0.2;
573      if (targetX < -movementBound) targetX = -movementBound + (targetX + movementBound) * 0.2;
574      if (targetY > movementBound) targetY = movementBound + (targetY - movementBound) * 0.2;
575      if (targetY < -movementBound) targetY = -movementBound + (targetY + movementBound) * 0.2;
576
577      imgValues.imgTransforms.x = targetX;
578      imgValues.imgTransforms.y = targetY;
579      imgValues.imgTransforms.rz = targetRz;
580
581      if (svgRef.current) {
582        gsap.set(svgRef.current, {
583          x: imgValues.imgTransforms.x,
584          y: imgValues.imgTransforms.y,
585          rotateZ: imgValues.imgTransforms.rz
586        });
587      }
588
589      const cursorTravelledDistance = distance(
590        cachedCursor.current.x,
591        cursor.current.x,
592        cachedCursor.current.y,
593        cursor.current.y
594      );
595      imgValues.displacementScale = lerp(
596        imgValues.displacementScale,
597        map(cursorTravelledDistance, 0, 200, 0, maxDisplacement),
598        0.06
599      );
600
601      if (displacementMapRef.current) {
602        gsap.set(displacementMapRef.current, {
603          attr: { scale: imgValues.displacementScale }
604        });
605      }
606
607      cachedCursor.current = { ...cursor.current };
608
609      rafId = requestAnimationFrame(render);
610    };
611
612    let rafId = requestAnimationFrame(render);
613
614    return () => {
615      cancelAnimationFrame(rafId);
616      window.removeEventListener('resize', handleResize);
617      window.removeEventListener('mousemove', handleMouseMove);
618    };
619  }, [maxDisplacement, movementBound]);
620
621  return (
622    <div ref={svgRef} className="relative" style={{ width: \`\${width}px\`, height: \`\${height}px\` }}>
623      <svg
624        viewBox="-60 -75 720 900"
625        preserveAspectRatio="xMidYMid slice"
626        className="relative w-full h-full block [will-change:transform]"
627      >
628        <filter id="imgFilter">
629          <feTurbulence
630            type="turbulence"
631            baseFrequency={baseFrequency}
632            numOctaves={numOctaves}
633            seed={seed}
634            stitchTiles="stitch"
635            x="0%"
636            y="0%"
637            width="100%"
638            height="100%"
639            result="turbulence1"
640          />
641          <feDisplacementMap
642            ref={displacementMapRef}
643            in="SourceGraphic"
644            in2="turbulence1"
645            scale="0"
646            xChannelSelector="R"
647            yChannelSelector="B"
648            x="0%"
649            y="0%"
650            width="100%"
651            height="100%"
652            result="displacementMap3"
653          />
654        </filter>
655        <g>
656          <image
657            href={image}
658            x="0"
659            y="0"
660            width="600"
661            height="750"
662            filter="url(#imgFilter)"
663            preserveAspectRatio="xMidYMid slice"
664          />
665        </g>
666      </svg>
667      <div className="absolute bottom-[1.2em] left-[1em] tracking-[-0.5px] font-black text-[2.5rem] leading-[1.5em] first-line:text-[6rem]">
668        {children}
669      </div>
670    </div>
671  );
672};
673
674export default DecayCard;
675`,_={dependencies:"gsap",usage:`import DecayCard from './DecayCard';
676
677<DecayCard width={200} height={300} image="https://picsum.photos/300/400?grayscale">
678  <h2>Decay<br/>Card</h2>
679</DecayCard>`,code:k,css:G,tailwind:Z,tsCode:J,tsTailwind:U},F={width:300,height:400,baseFrequency:.015,numOctaves:5,seed:4,maxDisplacement:400,movementBound:50},he=()=>{const{props:w,updateProp:o,resetProps:R,hasChanges:M}=j(F),{width:v,height:x,baseFrequency:f,numOctaves:r,seed:y,maxDisplacement:l,movementBound:g}=w,[a,c]=I(),h=d.useMemo(()=>[{name:"children",type:"ReactNode",default:"",description:"The content (JSX) to be rendered inside the card."},{name:"width",type:"number",default:"300",description:"The width of the card in pixels."},{name:"height",type:"number",default:"400",description:"The height of the card in pixels."},{name:"image",type:"string",default:"https://picsum.photos/300/400?grayscale",description:"Allows setting the background image of the card."},{name:"baseFrequency",type:"number",default:"0.015",description:"Base frequency for the turbulence filter. Lower values create larger, smoother patterns."},{name:"numOctaves",type:"number",default:"5",description:"Number of octaves for the turbulence filter. Higher values add finer detail."},{name:"seed",type:"number",default:"4",description:"Seed value for the turbulence random number generator."},{name:"maxDisplacement",type:"number",default:"400",description:"Maximum displacement scale applied when the cursor moves. Controls the intensity of the decay effect."},{name:"movementBound",type:"number",default:"50",description:"Maximum pixel distance the card can translate from its origin when following the cursor."}],[]);return e.jsx(q,{props:w,defaultProps:F,resetProps:R,hasChanges:M,children:e.jsxs(A,{children:[e.jsxs(L,{children:[e.jsx(E,{position:"relative",className:"demo-container",h:500,overflow:"hidden",children:e.jsx($,{width:v,height:x,baseFrequency:f,numOctaves:r,seed:y,maxDisplacement:l,movementBound:g,children:e.jsxs(X,{mixBlendMode:"overlay",children:["Decay",e.jsx("br",{}),"Card"]})},a)}),e.jsxs(P,{children:[e.jsx(u,{title:"Width",min:100,max:600,step:25,value:v,onChange:t=>{o("width",t),c()}}),e.jsx(u,{title:"Height",min:200,max:600,step:25,value:x,onChange:t=>{o("height",t),c()}}),e.jsx(u,{title:"Base Frequency",min:.001,max:.1,step:.001,value:f,onChange:t=>{o("baseFrequency",t),c()}}),e.jsx(u,{title:"Num Octaves",min:1,max:10,step:1,value:r,onChange:t=>{o("numOctaves",t),c()}}),e.jsx(u,{title:"Seed",min:0,max:100,step:1,value:y,onChange:t=>{o("seed",t),c()}}),e.jsx(u,{title:"Max Displacement",min:50,max:1e3,step:50,value:l,onChange:t=>o("maxDisplacement",t)}),e.jsx(u,{title:"Movement Bound",min:10,max:150,step:5,value:g,onChange:t=>o("movementBound",t)})]}),e.jsx(N,{data:h}),e.jsx(W,{dependencyList:["gsap"]})]}),e.jsx(O,{children:e.jsx(H,{codeObject:_,componentName:"DecayCard"})})]})})};export{he 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.