UNPKG

reactbits-mcp-server

Version:

MCP Server for React Bits - Access 99+ React components with animations, backgrounds, and UI elements

159 lines (143 loc) 3.77 kB
/* eslint-disable react/no-unknown-property */ import { useMemo } from 'react' import { Canvas, useThree } from '@react-three/fiber' import { shaderMaterial, useTrailTexture } from '@react-three/drei' import * as THREE from 'three' const GooeyFilter = ({ id = "goo-filter", strength = 10, }) => { return ( <svg className='absolute overflow-hidden z-1'> <defs> <filter id={id}> <feGaussianBlur in="SourceGraphic" stdDeviation={strength} result="blur" /> <feColorMatrix in="blur" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" /> <feComposite in="SourceGraphic" in2="goo" operator="atop" /> </filter> </defs> </svg> ) } const DotMaterial = shaderMaterial( { resolution: new THREE.Vector2(), mouseTrail: null, gridSize: 100, pixelColor: new THREE.Color('#ffffff') }, ` varying vec2 vUv; void main() { gl_Position = vec4(position.xy, 0.0, 1.0); } `, ` uniform vec2 resolution; uniform sampler2D mouseTrail; uniform float gridSize; uniform vec3 pixelColor; vec2 coverUv(vec2 uv) { vec2 s = resolution.xy / max(resolution.x, resolution.y); vec2 newUv = (uv - 0.5) * s + 0.5; return clamp(newUv, 0.0, 1.0); } float sdfCircle(vec2 p, float r) { return length(p - 0.5) - r; } void main() { vec2 screenUv = gl_FragCoord.xy / resolution; vec2 uv = coverUv(screenUv); vec2 gridUv = fract(uv * gridSize); vec2 gridUvCenter = (floor(uv * gridSize) + 0.5) / gridSize; float trail = texture2D(mouseTrail, gridUvCenter).r; gl_FragColor = vec4(pixelColor, trail); } ` ) function Scene({ gridSize, trailSize, maxAge, interpolate, easingFunction, pixelColor }) { const size = useThree((s) => s.size) const viewport = useThree((s) => s.viewport) const dotMaterial = useMemo(() => new DotMaterial(), []) dotMaterial.uniforms.pixelColor.value = new THREE.Color(pixelColor) const [trail, onMove] = useTrailTexture({ size: 512, radius: trailSize, maxAge: maxAge, interpolate: interpolate || 0.1, ease: easingFunction || ((x) => x) }) if (trail) { trail.minFilter = THREE.NearestFilter; trail.magFilter = THREE.NearestFilter; trail.wrapS = THREE.ClampToEdgeWrapping; trail.wrapT = THREE.ClampToEdgeWrapping; } const scale = Math.max(viewport.width, viewport.height) / 2 return ( <mesh scale={[scale, scale, 1]} onPointerMove={onMove}> <planeGeometry args={[2, 2]} /> <primitive object={dotMaterial} gridSize={gridSize} resolution={[size.width * viewport.dpr, size.height * viewport.dpr]} mouseTrail={trail} /> </mesh> ) } export default function PixelTrail({ gridSize = 40, trailSize = 0.1, maxAge = 250, interpolate = 5, easingFunction = (x) => x, canvasProps = {}, glProps = { antialias: false, powerPreference: 'high-performance', alpha: true }, gooeyFilter, color = '#ffffff', className = '' }) { return ( <> {gooeyFilter && ( <GooeyFilter id={gooeyFilter.id} strength={gooeyFilter.strength} /> )} <Canvas {...canvasProps} gl={glProps} className={`absolute z-1 ${className}`} style={gooeyFilter && { filter: `url(#${gooeyFilter.id})` }} > <Scene gridSize={gridSize} trailSize={trailSize} maxAge={maxAge} interpolate={interpolate} easingFunction={easingFunction} pixelColor={color} /> </Canvas> </> ) }