The prompt that made it
as published# PROJECT PROMPT
YOU ARE GIVEN A TASK TO INTEGRATE AN EXISTING REACT COMPONENT IN THE CODEBASE
THE CODEBASE SHOULD SUPPORT:
- SHADCN PROJECT STRUCTURE
- TAILWIND CSS
- TYPESCRIPT
IF IT DOESN'T, PROVIDE INSTRUCTIONS ON HOW TO SETUP PROJECT VIA SHADCN CLI, INSTALL TAILWIND OR TYPESCRIPT.
DETERMINE THE DEFAULT PATH FOR COMPONENTS AND STYLES.
IF DEFAULT PATH FOR COMPONENTS IS NOT /COMPONENTS/UI, PROVIDE INSTRUCTIONS ON WHY IT'S IMPORTANT TO CREATE THIS FOLDER
COPY-PASTE THIS COMPONENT TO /COMPONENTS/UI FOLDER:
```tsx
GRADIENT-SHADER-CARD.TSX
"USE CLIENT"
IMPORT { USEFRAME, USETHREE } FROM "@REACT-THREE/FIBER"
IMPORT { USEREF, USEMEMO, USEIMPERATIVEHANDLE, FORWARDREF } FROM "REACT"
IMPORT * AS THREE FROM "THREE"
INTERFACE RIPPLE {
ID: NUMBER;
X: NUMBER;
Y: NUMBER;
STARTTIME: NUMBER;
}
INTERFACE GRAINYGRADIENTPROPS {
RIPPLES?: RIPPLE[];
ONTIMEUPDATE?: (TIME: NUMBER) => VOID;
}
CONST GRAINYGRADIENT = FORWARDREF<ANY, GRAINYGRADIENTPROPS>(({ RIPPLES = [], ONTIMEUPDATE }, REF) => {
CONST MESH = USEREF<THREE.MESH>(NULL)
CONST { VIEWPORT } = USETHREE()
CONST UNIFORMS = USEMEMO(
() => ({
ITIME: { VALUE: 0.0 },
IRESOLUTION: { VALUE: NEW THREE.VECTOR3() },
// SIMPLEX NOISE UNIFORMS
NOISEINTENSITY: { VALUE: 1.55 },
NOISESCALE: { VALUE: 2.0 },
NOISESPEED: { VALUE: 0.15 },
// WAVE/DOMAIN WARPING NOISE UNIFORMS
WAVENOISEINTENSITY: { VALUE: 1.2 },
WAVENOISESCALE1: { VALUE: 0.5 },
WAVENOISESCALE2: { VALUE: 0.8 },
WAVENOISESCALE3: { VALUE: 1.2 },
WAVENOISESPEED1: { VALUE: 0.24 },
WAVENOISESPEED2: { VALUE: 0.2 },
WAVENOISESPEED3: { VALUE: 0.3 },
// RIPPLE UNIFORMS
RIPPLEPOSITIONS: { VALUE: [] },
RIPPLETIMES: { VALUE: [] },
RIPPLECOUNT: { VALUE: 0 },
}),
[],
)
USEFRAME((STATE) => {
IF (MESH.CURRENT) {
CONST CURRENTTIME = STATE.CLOCK.GETELAPSEDTIME()
UNIFORMS.ITIME.VALUE = CURRENTTIME
UNIFORMS.IRESOLUTION.VALUE.SET(WINDOW.INNERWIDTH, WINDOW.INNERHEIGHT, 1)
// CALL THE TIME UPDATE CALLBACK
IF (ONTIMEUPDATE) {
ONTIMEUPDATE(CURRENTTIME)
}
// UPDATE RIPPLE UNIFORMS
CONST ACTIVERIPPLES = RIPPLES.FILTER(RIPPLE => CURRENTTIME - RIPPLE.STARTTIME < 2.0) // 2 SECOND DURATION
CONST POSITIONS = []
CONST TIMES = []
FOR (LET I = 0; I < MATH.MIN(ACTIVERIPPLES.LENGTH, 10); I++) { // MAX 10 RIPPLES
CONST RIPPLE = ACTIVERIPPLES[I]
// CONVERT TO NORMALIZED COORDINATES (-1 TO 1)
CONST NORMALIZEDX = (RIPPLE.X / 800) * 2 - 1 // 800 IS CARD WIDTH
CONST NORMALIZEDY = 1 - (RIPPLE.Y / 600) * 2 // 600 IS CARD HEIGHT, FLIP Y
POSITIONS.PUSH(NORMALIZEDX, NORMALIZEDY)
TIMES.PUSH(CURRENTTIME - RIPPLE.STARTTIME)
}
UNIFORMS.RIPPLEPOSITIONS.VALUE = POSITIONS
UNIFORMS.RIPPLETIMES.VALUE = TIMES
UNIFORMS.RIPPLECOUNT.VALUE = ACTIVERIPPLES.LENGTH
}
})
CONST MATERIAL = USEMEMO(() => {
RETURN NEW THREE.SHADERMATERIAL({
FRAGMENTSHADER,
VERTEXSHADER,
UNIFORMS,
})
}, [UNIFORMS])
USEIMPERATIVEHANDLE(REF, () => ({
MATERIAL,
UNIFORMS,
GETCURRENTTIME: () => UNIFORMS.ITIME.VALUE
}))
RETURN (
<MESH REF={MESH} SCALE={[VIEWPORT.WIDTH, VIEWPORT.HEIGHT, 1]}>
<PLANEGEOMETRY ARGS={[1, 1]} />
{MATERIAL && <PRIMITIVE OBJECT={MATERIAL} ATTACH="MATERIAL" />}
</MESH>
)
})
GRAINYGRADIENT.DISPLAYNAME = "GRAINYGRADIENT"
EXPORT DEFAULT GRAINYGRADIENT
CONST VERTEXSHADER = `
VARYING VEC2 VUV;
VOID MAIN() {
VUV = UV;
GL_POSITION = PROJECTIONMATRIX * MODELVIEWMATRIX * VEC4(POSITION, 1.0);
}
`
CONST FRAGMENTSHADER = `
UNIFORM VEC3 IRESOLUTION;
UNIFORM FLOAT ITIME;
// SIMPLEX NOISE UNIFORMS
UNIFORM FLOAT NOISEINTENSITY;
UNIFORM FLOAT NOISESCALE;
UNIFORM FLOAT NOISESPEED;
// WAVE/DOMAIN WARPING NOISE UNIFORMS
UNIFORM FLOAT WAVENOISEINTENSITY;
UNIFORM FLOAT WAVENOISESCALE1;
UNIFORM FLOAT WAVENOISESCALE2;
UNIFORM FLOAT WAVENOISESCALE3;
UNIFORM FLOAT WAVENOISESPEED1;
UNIFORM FLOAT WAVENOISESPEED2;
UNIFORM FLOAT WAVENOISESPEED3;
// RIPPLE UNIFORMS
UNIFORM FLOAT RIPPLEPOSITIONS[20]; // MAX 10 RIPPLES * 2 COORDINATES
UNIFORM FLOAT RIPPLETIMES[10]; // MAX 10 RIPPLES
UNIFORM INT RIPPLECOUNT;
VARYING VEC2 VUV;
// GRAIN SETTINGS
#DEFINE BLEND_MODE 2
#DEFINE SPEED 2.0
#DEFINE INTENSITY 0.075
#DEFINE MEAN 0.0
#DEFINE VARIANCE 0.5
// SIMPLE 2D NOISE FUNCTION
VEC2 HASH(VEC2 P) {
P = VEC2(DOT(P, VEC2(127.1, 311.7)), DOT(P, VEC2(269.5, 183.3)));
RETURN -1.0 + 2.0 * FRACT(SIN(P) * 43758.5453123);
}
// GRADIENT NOISE
FLOAT NOISE(VEC2 P) {
VEC2 I = FLOOR(P);
VEC2 F = FRACT(P);
VEC2 U = F * F * (3.0 - 2.0 * F);
RETURN MIX(
MIX(DOT(HASH(I + VEC2(0.0, 0.0)), F - VEC2(0.0, 0.0)),
DOT(HASH(I + VEC2(1.0, 0.0)), F - VEC2(1.0, 0.0)), U.X),
MIX(DOT(HASH(I + VEC2(0.0, 1.0)), F - VEC2(0.0, 1.0)),
DOT(HASH(I + VEC2(1.0, 1.0)), F - VEC2(1.0, 1.0)), U.X),
U.Y
);
}
// 3D SIMPLEX NOISE
VEC3 MOD289(VEC3 X) {
RETURN X - FLOOR(X * (1.0 / 289.0)) * 289.0;
}
VEC4 MOD289(VEC4 X) {
RETURN X - FLOOR(X * (1.0 / 289.0)) * 289.0;
}
VEC4 PERMUTE(VEC4 X) {
RETURN MOD289(((X*34.0)+1.0)*X);
}
VEC4 TAYLORINVSQRT(VEC4 R) {
RETURN 1.79284291400159 - 0.85373472095314 * R;
}
FLOAT SNOISE(VEC3 V) {
CONST VEC2 C = VEC2(1.0/6.0, 1.0/3.0) ;
CONST VEC4 D = VEC4(0.0, 0.5, 1.0, 2.0);
VEC3 I = FLOOR(V + DOT(V, C.YYY) );
VEC3 X0 = V - I + DOT(I, C.XXX) ;
VEC3 G = STEP(X0.YZX, X0.XYZ);
VEC3 L = 1.0 - G;
VEC3 I1 = MIN( G.XYZ, L.ZXY );
VEC3 I2 = MAX( G.XYZ, L.ZXY );
VEC3 X1 = X0 - I1 + C.XXX;
VEC3 X2 = X0 - I2 + C.YYY;
VEC3 X3 = X0 - D.YYY;
I = MOD289(I);
VEC4 P = PERMUTE( PERMUTE( PERMUTE(
I.Z + VEC4(0.0, I1.Z, I2.Z, 1.0 ))
+ I.Y + VEC4(0.0, I1.Y, I2.Y, 1.0 ))
+ I.X + VEC4(0.0, I1.X, I2.X, 1.0 ));
FLOAT N_ = 0.142857142857;
VEC3 NS = N_ * D.WYZ - D.XZX;
VEC4 J = P - 49.0 * FLOOR(P * NS.Z * NS.Z);
VEC4 X_ = FLOOR(J * NS.Z);
VEC4 Y_ = FLOOR(J - 7.0 * X_ );
VEC4 X = X_ *NS.X + NS.YYYY;
VEC4 Y = Y_ *NS.X + NS.YYYY;
VEC4 H = 1.0 - ABS(X) - ABS(Y);
VEC4 B0 = VEC4( X.XY, Y.XY );
VEC4 B1 = VEC4( X.ZW, Y.ZW );
VEC4 S0 = FLOOR(B0)*2.0 + 1.0;
VEC4 S1 = FLOOR(B1)*2.0 + 1.0;
VEC4 SH = -STEP(H, VEC4(0.0));
VEC4 A0 = B0.XZYW + S0.XZYW*SH.XXYY ;
VEC4 A1 = B1.XZYW + S1.XZYW*SH.ZZWW ;
VEC3 P0 = VEC3(A0.XY,H.X);
VEC3 P1 = VEC3(A0.ZW,H.Y);
VEC3 P2 = VEC3(A1.XY,H.Z);
VEC3 P3 = VEC3(A1.ZW,H.W);
VEC4 NORM = TAYLORINVSQRT(VEC4(DOT(P0,P0), DOT(P1,P1), DOT(P2, P2), DOT(P3,P3)));
P0 *= NORM.X;
P1 *= NORM.Y;
P2 *= NORM.Z;
P3 *= NORM.W;
VEC4 M = MAX(0.6 - VEC4(DOT(X0,X0), DOT(X1,X1), DOT(X2,X2), DOT(X3,X3)), 0.0);
M = M * M;
RETURN 42.0 * DOT( M*M, VEC4( DOT(P0,X0), DOT(P1,X1),
DOT(P2,X2), DOT(P3,X3) ) );
}
// DOMAIN WARPING FUNCTION WITH UNIFORMS
VEC2 WARP(VEC2 P) {
FLOAT N1 = NOISE(P * WAVENOISESCALE1 + VEC2(ITIME * WAVENOISESPEED1, 0.0));
FLOAT N2 = NOISE(P * WAVENOISESCALE1 + VEC2(0.0, ITIME * WAVENOISESPEED2));
FLOAT N3 = NOISE(P * WAVENOISESCALE2 + VEC2(ITIME * -WAVENOISESPEED3, ITIME * WAVENOISESPEED3)) * 0.5;
FLOAT N4 = NOISE(P * WAVENOISESCALE3 + VEC2(ITIME * WAVENOISESPEED3, -ITIME * WAVENOISESPEED3)) * 0.3;
RETURN P + VEC2(N1 + N3, N2 + N4) * WAVENOISEINTENSITY;
}
// SIMPLIFIED RIPPLE FUNCTION - SINGLE CLEAN EXPANDING RING
FLOAT CALCULATERIPPLES(VEC2 UV) {
FLOAT RIPPLEEFFECT = 0.0;
FOR (INT I = 0; I < RIPPLECOUNT && I < 10; I++) {
VEC2 RIPPLEPOS = VEC2(RIPPLEPOSITIONS[I * 2], RIPPLEPOSITIONS[I * 2 + 1]);
FLOAT RIPPLETIME = RIPPLETIMES[I];
// CALCULATE DISTANCE FROM RIPPLE CENTER
FLOAT DIST = DISTANCE(UV, RIPPLEPOS);
// CREATE SINGLE EXPANDING RING
FLOAT RIPPLERADIUS = RIPPLETIME * 1.0; // SPEED OF EXPANSION
FLOAT RIPPLEWIDTH = 0.05; // THINNER RING FOR CLEANER LOOK
// CREATE A SINGLE RING USING SMOOTHSTEP FOR SOFT EDGES
FLOAT RING = SMOOTHSTEP(RIPPLERADIUS + RIPPLEWIDTH, RIPPLERADIUS, DIST) *
SMOOTHSTEP(RIPPLERADIUS - RIPPLEWIDTH, RIPPLERADIUS, DIST);
// FADE OUT OVER TIME
FLOAT FADEOUT = 1.0 - SMOOTHSTEP(0.0, 2.0, RIPPLETIME);
// SINGLE CLEAN WAVE PATTERN
FLOAT WAVE = SIN(DIST * 15.0 - RIPPLETIME * 8.0) * 0.5 + 0.5;
RIPPLEEFFECT += RING * FADEOUT * WAVE * 0.3;
}
RETURN RIPPLEEFFECT;
}
// GRAIN FUNCTIONS
VEC3 CHANNEL_MIX(VEC3 A, VEC3 B, VEC3 W) {
RETURN VEC3(MIX(A.R, B.R, W.R), MIX(A.G, B.G, W.G), MIX(A.B, B.B, W.B));
}
FLOAT GAUSSIAN(FLOAT Z, FLOAT U, FLOAT O) {
RETURN (1.0 / (O * SQRT(2.0 * 3.1415))) * EXP(-(((Z - U) * (Z - U)) / (2.0 * (O * O))));
}
VEC3 SCREEN(VEC3 A, VEC3 B, FLOAT W) {
RETURN MIX(A, VEC3(1.0) - (VEC3(1.0) - A) * (VEC3(1.0) - B), W);
}
VEC3 OVERLAY(VEC3 A, VEC3 B, FLOAT W) {
RETURN MIX(A, CHANNEL_MIX(
2.0 * A * B,
VEC3(1.0) - 2.0 * (VEC3(1.0) - A) * (VEC3(1.0) - B),
STEP(VEC3(0.5), A)
), W);
}
VEC3 SOFT_LIGHT(VEC3 A, VEC3 B, FLOAT W) {
RETURN MIX(A, POW(A, POW(VEC3(2.0), 2.0 * (VEC3(0.5) - B))), W);
}
// CONVERT HEX COLORS TO RGB
VEC3 HEXTORGB(FLOAT R, FLOAT G, FLOAT B) {
RETURN VEC3(R / 255.0, G / 255.0, B / 255.0);
}
// MULTI-COLOR GRADIENT FUNCTION
VEC3 MULTICOLORGRADIENT(FLOAT T) {
// DEFINE YOUR COLOR PALETTE
VEC3 COLORS[7];
COLORS[0] = HEXTORGB(250.0, 212.0, 251.0); // FAD4FB - LIGHT PURPLE/PINK
COLORS[1] = HEXTORGB(250.0, 200.0, 225.0); // FAC8E1 - PINK
COLORS[2] = HEXTORGB(250.0, 182.0, 21.0); // FAB615 - YELLOW/GOLD
COLORS[3] = HEXTORGB(252.0, 104.0, 30.0); // FC681E - ORANGE
COLORS[4] = HEXTORGB(13.0, 93.0, 244.0); // 0D5DF4 - BLUE
COLORS[5] = HEXTORGB(11.0, 74.0, 187.0); // 0B4ABB - DARKER BLUE
COLORS[6] = HEXTORGB(23.0, 14.0, 7.0); // 170E07 - VERY DARK BROWN/BLACK
// CLAMP T TO [0, 1]
T = CLAMP(T, 0.0, 1.0);
// CALCULATE WHICH SEGMENT WE'RE IN
FLOAT SCALEDT = T * 6.0; // 6 SEGMENTS BETWEEN 7 COLORS
INT INDEX = INT(FLOOR(SCALEDT));
FLOAT LOCALT = FRACT(SCALEDT);
// HANDLE EDGE CASE
IF (INDEX >= 6) {
RETURN COLORS[6];
}
// INTERPOLATE BETWEEN ADJACENT COLORS
FLOAT SMOOTHT = SMOOTHSTEP(0.0, 1.0, LOCALT);
RETURN MIX(COLORS[INDEX], COLORS[INDEX + 1], SMOOTHT);
}
// APPLY GRAIN TO COLOR
VEC3 APPLYGRAIN(VEC3 COLOR, VEC2 UV) {
FLOAT T = ITIME * SPEED;
FLOAT SEED = DOT(UV, VEC2(12.9898, 78.233));
FLOAT GRAINNOISE = FRACT(SIN(SEED) * 43758.5453 + T);
GRAINNOISE = GAUSSIAN(GRAINNOISE, MEAN, VARIANCE * VARIANCE);
VEC3 GRAIN = VEC3(GRAINNOISE) * (1.0 - COLOR);
FLOAT W = INTENSITY;
#IF BLEND_MODE == 0
COLOR += GRAIN * W;
#ELIF BLEND_MODE == 1
COLOR = SCREEN(COLOR, GRAIN, W);
#ELIF BLEND_MODE == 2
COLOR = OVERLAY(COLOR, GRAIN, W);
#ELIF BLEND_MODE == 3
COLOR = SOFT_LIGHT(COLOR, GRAIN, W);
#ELIF BLEND_MODE == 4
COLOR = MAX(COLOR, GRAIN * W);
#ENDIF
RETURN COLOR;
}
VOID MAINIMAGE(OUT VEC4 O, IN VEC2 I) {
VEC2 UV = (I - 0.5 * IRESOLUTION.XY) / IRESOLUTION.Y;
// APPLY DOMAIN WARPING TO THE UV COORDINATES USING UNIFORMS
VEC2 WARPEDUV = WARP(UV);
// ADD SUBTLE SIMPLEX NOISE USING UNIFORMS
FLOAT SIMPLEXNOISE = SNOISE(VEC3(WARPEDUV * NOISESCALE, ITIME * NOISESPEED)) * NOISEINTENSITY;
WARPEDUV += SIMPLEXNOISE;
// CREATE MULTIPLE WAVE PATTERNS WITH DIFFERENT FREQUENCIES
FLOAT PHASE1 = ITIME * 0.6;
FLOAT PHASE2 = ITIME * 0.4;
// CREATE ARCHED WAVE BY USING BOTH X AND Y COORDINATES
FLOAT DISTANCEFROMCENTER = LENGTH(WARPEDUV - VEC2(0.0, 0.0));
FLOAT ARCHFACTOR = 1.0 - DISTANCEFROMCENTER * 0.5;
// PRIMARY WAVE WITH ARCH
FLOAT WAVE1 = SIN(WARPEDUV.X * 3.0 + PHASE1) * 0.5 * ARCHFACTOR;
// SECONDARY WAVE WITH DIFFERENT FREQUENCY AND ARCH
FLOAT WAVE2 = SIN(WARPEDUV.X * 5.0 - PHASE2) * 0.3 * ARCHFACTOR;
// TERTIARY WAVE THAT CREATES VERTICAL ARCHING
FLOAT WAVE3 = SIN(WARPEDUV.Y * 4.0 + PHASE1 * 0.7) * 0.15;
// ADD A PARABOLIC ARCH EFFECT
FLOAT PARABOLICARCH = -POW(WARPEDUV.X, 2.0) * 0.2;
// COMBINE WAVES WITH BREATHING EFFECT AND ARCH
FLOAT BREATHING = SIN(ITIME * 0.5) * 0.1 + 0.9;
FLOAT COMBINEDWAVE = (WAVE1 + WAVE2 + WAVE3 + PARABOLICARCH) * BREATHING * 0.3;
// CALCULATE RIPPLE EFFECTS (NOW SIMPLIFIED TO SINGLE CLEAN RINGS)
FLOAT RIPPLES = CALCULATERIPPLES(UV);
// ADJUST UV FOR VERTICAL GRADIENT WITH CENTERED RIDGE AND RIPPLES
FLOAT GRADIENTPOS = (VUV.Y + COMBINEDWAVE * 0.3 + RIPPLES * 0.2);
// USE THE MULTI-COLOR GRADIENT
FLOAT SMOOTHGRADIENTPOS = SMOOTHSTEP(0.0, 1.0, CLAMP(1.0 - GRADIENTPOS, 0.0, 1.0));
VEC3 COLOR = MULTICOLORGRADIENT(SMOOTHGRADIENTPOS);
// ADD SUBTLE RIPPLE BRIGHTNESS EFFECT
COLOR += VEC3(RIPPLES * 0.3);
// APPLY GRAIN EFFECT
O = VEC4(APPLYGRAIN(COLOR, VUV), 1.0);
}
VOID MAIN() {
VEC2 FRAGCOORD = VUV * IRESOLUTION.XY;
MAINIMAGE(GL_FRAGCOLOR, FRAGCOORD);
}
`
DEMO.TSX
IMPORT { CANVAS } FROM "@REACT-THREE/FIBER";
IMPORT { MOTION } FROM "FRAMER-MOTION";
IMPORT { USESTATE, USEREF } FROM "REACT";
IMPORT GRAINYGRADIENT FROM "@/COMPONENTS/UI/GRADIENT-SHADER-CARD";
INTERFACE RIPPLE {
ID: NUMBER;
X: NUMBER;
Y: NUMBER;
STARTTIME: NUMBER;
}
EXPORT DEFAULT FUNCTION APP() {
CONST [RIPPLES, SETRIPPLES] = USESTATE<RIPPLE[]>([]);
CONST [CURRENTTIME, SETCURRENTTIME] = USESTATE(0);
CONST CARDREF = USEREF<HTMLDIVELEMENT>(NULL);
CONST RIPPLEIDREF = USEREF(0);
CONST HANDLETIMEUPDATE = (TIME: NUMBER) => {
SETCURRENTTIME(TIME);
};
CONST HANDLECLICK = (E: REACT.MOUSEEVENT<HTMLDIVELEMENT>) => {
IF (!CARDREF.CURRENT) RETURN;
CONST RECT = CARDREF.CURRENT.GETBOUNDINGCLIENTRECT();
CONST X = E.CLIENTX - RECT.LEFT;
CONST Y = E.CLIENTY - RECT.TOP;
CONST NEWRIPPLE: RIPPLE = {
ID: RIPPLEIDREF.CURRENT++,
X,
Y,
STARTTIME: CURRENTTIME, // USE THE SYNCHRONIZED TIME
};
SETRIPPLES(PREV => [...PREV, NEWRIPPLE]);
// REMOVE RIPPLE AFTER ANIMATION COMPLETES
SETTIMEOUT(() => {
SETRIPPLES(PREV => PREV.FILTER(RIPPLE => RIPPLE.ID !== NEWRIPPLE.ID));
}, 2000);
};
RETURN (
<DIV
CLASSNAME="MIN-H-SCREEN W-FULL FLEX ITEMS-CENTER JUSTIFY-CENTER P-8"
STYLE={{ BACKGROUNDCOLOR: "#F9F9F9" }}
>
<MOTION.DIV
REF={CARDREF}
CLASSNAME="W-[800PX] H-[600PX] OVERFLOW-HIDDEN RELATIVE CURSOR-POINTER"
STYLE={{
BORDERRADIUS: "48PX",
FILTER:
"DROP-SHADOW(0PX 206PX 82PX RGBA(0, 0, 0, 0.01)) DROP-SHADOW(0PX 116PX 69PX RGBA(0, 0, 0, 0.05)) DROP-SHADOW(0PX 51PX 51PX RGBA(0, 0, 0, 0.09)) DROP-SHADOW(0PX 13PX 28PX RGBA(0, 0, 0, 0.1))",
}}
WHILEHOVER={{ SCALE: 1.02 }}
TRANSITION={{
TYPE: "SPRING",
STIFFNESS: 300,
DAMPING: 30,
MASS: 0.8,
}}
ONCLICK={HANDLECLICK}
>
<CANVAS
CAMERA={{ POSITION: [0, 0, 1] }}
GL={{ PRESERVEDRAWINGBUFFER: TRUE }}
>
<GRAINYGRADIENT RIPPLES={RIPPLES} ONTIMEUPDATE={HANDLETIMEUPDATE} />
</CANVAS>
</MOTION.DIV>
</DIV>
);
}
```
INSTALL NPM DEPENDENCIES:
```bash
THREE, @REACT-THREE/FIBER
```
## IMPLEMENTATION GUIDELINES
1. ANALYZE THE COMPONENT STRUCTURE AND IDENTIFY ALL REQUIRED DEPENDENCIES
2. REVIEW THE COMPONENT'S ARGUMENS AND STATE
3. IDENTIFY ANY REQUIRED CONTEXT PROVIDERS OR HOOKS AND INSTALL THEM
4. QUESTIONS TO ASK
- WHAT DATA/PROPS WILL BE PASSED TO THIS COMPONENT?
- ARE THERE ANY SPECIFIC STATE MANAGEMENT REQUIREMENTS?
- ARE THERE ANY REQUIRED ASSETS (IMAGES, ICONS, ETC.)?
- WHAT IS THE EXPECTED RESPONSIVE BEHAVIOR?
- WHAT IS THE BEST PLACE TO USE THIS COMPONENT IN THE APP?
## STEPS TO INTEGRATE
0. COPY PASTE ALL THE CODE ABOVE IN THE CORRECT DIRECTORIES
1. INSTALL EXTERNAL DEPENDENCIES
2. FILL IMAGE ASSETS WITH UNSPLASH STOCK IMAGES YOU KNOW EXIST
3. USE LUCIDE-REACT ICONS FOR SVGS OR LOGOS IF COMPONENT REQUIRES THEMAdds a render step. Works best with the HyperFrames or Remotion skills installed. Free, no sign-up.
Prompt by @pulkitxm. Prompts belong to their creators.