Fluid Orb
rare-ui/fluid-orbFreeComponent
An animated WebGL orb with drifting fluid shading. Supports size and color props.
Install it
npx shadcn@latest add https://rareui.com/r/fluid-orb.jsonSource
1'use client'23import React, { useEffect, useRef } from 'react'45import { cn } from '@/lib/utils'67export type FluidOrbProps = React.ComponentProps<'div'> & {8 size?: number9 color?: string10}1112const VERT = `13attribute vec2 a_pos;14void main() {15 gl_Position = vec4(a_pos, 0.0, 1.0);16}17`1819const FRAG = `20#ifdef GL_FRAGMENT_PRECISION_HIGH21precision highp float;22#else23precision mediump float;24#endif2526uniform vec2 u_resolution;27uniform float u_time;28uniform vec3 u_color;2930float hash(vec2 p) {31 return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);32}3334float noise(vec2 p) {35 vec2 i = floor(p);36 vec2 f = fract(p);37 vec2 u = f * f * (3.0 - 2.0 * f);38 return mix(39 mix(hash(i + vec2(0.0, 0.0)), hash(i + vec2(1.0, 0.0)), u.x),40 mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), u.x),41 u.y42 );43}4445float fbm(vec2 p) {46 float v = 0.0;47 float a = 0.6;48 for (int i = 0; i < 3; i++) {49 v += a * noise(p);50 p *= 2.0;51 a *= 0.5;52 }53 return v;54}5556void main() {57 vec2 uv = gl_FragCoord.xy / u_resolution.xy;58 float t = u_time * 0.22;5960 vec2 drift = vec2(61 sin(t) + 0.6 * sin(t * 1.7 + 1.3),62 cos(t * 0.8) + 0.6 * cos(t * 1.3 + 2.1)63 );6465 vec2 p = vec2(uv.x * 1.8, uv.y * 1.0) + drift * 0.7;6667 vec2 q = vec2(fbm(p + drift), fbm(p + vec2(3.2, 1.5) - drift));68 float f = fbm(p + 1.2 * q);6970 float g = clamp(1.0 - uv.y, 0.0, 1.0);71 float anchor = smoothstep(0.0, 0.3, uv.y);72 float shade = clamp(g + (f - 0.5) * 0.8 * anchor, 0.0, 1.0);7374 vec3 white = vec3(0.99, 1.0, 1.0);75 vec3 light = mix(white, u_color, 0.5);76 vec3 dark = u_color;7778 vec3 col = white;79 col = mix(col, light, smoothstep(0.28, 0.52, shade));80 col = mix(col, dark, smoothstep(0.58, 0.88, shade));8182 float edge = smoothstep(0.5, 0.49, distance(uv, vec2(0.5)));8384 gl_FragColor = vec4(col * edge, edge);85}86`8788function hexToRgb(hex: string): [number, number, number] {89 let h = hex.replace('#', '').trim()90 if (h.length === 3) {91 h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2]92 }93 const n = parseInt(h, 16)94 if (h.length !== 6 || Number.isNaN(n)) return [0.1, 0.45, 0.95]95 return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255]96}9798function compile(gl: WebGLRenderingContext, type: number, src: string) {99 const shader = gl.createShader(type)100 if (!shader) return null101 gl.shaderSource(shader, src)102 gl.compileShader(shader)103 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {104 console.error(gl.getShaderInfoLog(shader))105// … truncated
What it pulls in
Other registry items
Files it writes
More from rare-ui
All 13 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Bounce Sidebarbounce-sidebar | rare-ui | Components | Free | 1 dep | |
| Code Blockcode-block | rare-ui | Components | Free | 3 deps | |
| Duration Pickerduration-picker | rare-ui | Components | Free | 5 deps | |
| Emoji Reactionemoji-reaction | rare-ui | Components | Free | 4 deps | |
| Family Drawerfamily drawer | rare-ui | Components | Free | 2 deps | |
| Folder Componentfolder-component | rare-ui | Components | Free | 1 dep | |
| GitHub Activitygithub-activity | rare-ui | Components | Free | 1 dep | |
| Gravity Lettersgravity-letters | rare-ui | Components | Free | no deps |
