ashish rajwani

Botanical background

Shaders

About

Botanical background mouse hover effects

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Botanical background to your project and fits it to your theme.

Code

How Botanical background is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

import React, { useEffect, useRef } from 'react';

/**
 * FLASH UI - Botanical Digitalism Background
 * A high-performance WebGL background replicating lush tropical foliage.
 * 
 * CSS Variable Exposure:
 * --bg-primary: #022c22 (Shadows)
 * --bg-secondary: #064e3b (Mid-tones)
 * --bg-accent: #4ade80 (Highlights/Interactive Glow)
 */

const BotanicalBackground = () => {
  const canvasRef = useRef(null);
  const mouseRef = useRef({ x: 0, y: 0 });

  useEffect(() => {
    const canvas = canvasRef.current;
    const gl = canvas.getContext('webgl');
    if (!gl) return;

    const vsSource = `
      attribute vec2 position;
      void main() {
        gl_Position = vec4(position, 0.0, 1.0);
      }
    `;

    const fsSource = `
      precision highp float;
      uniform float u_time;
      uniform vec2 u_resolution;
      uniform vec2 u_mouse;

      vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
      float snoise(vec2 v){
        const vec4 C = vec4(0.211324865405187, 0.366025403784439,
                 -0.577350269189626, 0.024390243902439);
        vec2 i  = floor(v + dot(v, C.yy) );
        vec2 x0 = v -   i + dot(i, C.xx);
        vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
        vec4 x12 = x0.xyxy + C.xxzz;
        x12.xy -= i1;
        i = mod(i, 289.0);
        vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
              + i.x + vec3(0.0, i1.x, 1.0 ));
        vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),
          dot(x12.zw,x12.zw)), 0.0);
        m = m*m; m = m*m;
        vec3 x = 2.0 * fract(p * C.www) - 1.0;
        vec3 h = abs(x) - 0.5;
        vec3 ox = floor(x + 0.5);
        vec3 a0 = x - ox;
        m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
        vec3 g;
        g.x  = a0.x  * x0.x  + h.x  * x0.y;
        g.yz = a0.yz * x12.xz + h.yz * x12.yw;
        return 130.0 * dot(m, g);
      }

      void main() {
        vec2 uv = gl_FragCoord.xy / u_resolution.xy;
        uv.x *= u_resolution.x / u_resolution.y;
        vec2 mouse = u_mouse / u_resolution.xy;
        mouse.x *= u_resolution.x / u_resolution.y;

        float t = u_time * 0.15;
        vec2 drift = vec2(sin(t), cos(t * 0.7)) * 0.05;
        
        float dist = distance(uv, mouse);
        vec2 interaction = (uv - mouse) * (0.1 / (dist + 0.4));

        float n1 = snoise((uv + drift - interaction) * 2.2);
        float n2 = snoise((uv * 4.5 + n1 * 0.6));
        
        float veins = smoothstep(0.88, 1.0, sin((uv.x + uv.y + n1 * 0.25) * 180.0)) * 0.25;

        vec3 colorA = vec3(0.01, 0.17, 0.13); // Deepest Green
        vec3 colorB = vec3(0.04, 0.35, 0.25); // Mid Forest
        vec3 colorC = vec3(0.35, 0.85, 0.45); // Bright Lime

        vec3 finalColor = mix(colorA, colorB, n1 * 0.5 + 0.5);
        finalColor = mix(finalColor, colorC, pow(max(0.0, n2), 2.5));
        finalColor += veins * (n2 + 0.4);
        
        float flare = smoothstep(0.45, 0.0, dist);
        finalColor += colorC * flare * 0.25;

        gl_FragColor = vec4(finalColor * (1.0 - length(uv - 0.5) * 0.5), 1.0);
      }
    `;

    const createShader = (type, source) => {
      const shader = gl.createShader(type);
      gl.shaderSource(shader, source);
      gl.compileShader(shader);
      return shader;
    };

    const program = gl.createProgram();
    gl.attachShader(program, createShader(gl.VERTEX_SHADER, vsSource));
    gl.attachShader(program, createShader(gl.FRAGMENT_SHADER, fsSource));
    gl.linkProgram(program);
    gl.useProgram(program);

    const vertices = new Float32Array([-1,-1, 1,-1, -1,1, -1,1, 1,-1, 1,1]);
    gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
    
    const pos = gl.getAttribLocation(program, "position");
    gl.enableVertexAttribArray(pos);
    gl.vertexAttribPointer(pos, 2, gl.FLOAT, false, 0, 0);

    const timeLoc = gl.getUniformLocation(program, "u_time");
    const resLoc = gl.getUniformLocation(program, "u_resolution");
    const mouseLoc = gl.getUniformLocation(program, "u_mouse");

    const handleMouseMove = (e) => {
      mouseRef.current = { x: e.clientX, y: window.innerHeight - e.clientY };
    };

    window.addEventListener('mousemove', handleMouseMove);

    let animationFrame;
    const render = (time) => {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      gl.viewport(0, 0, canvas.width, canvas.height);
      
      gl.uniform1f(timeLoc, time * 0.001);
      gl.uniform2f(resLoc, canvas.width, canvas.height);
      gl.uniform2f(mouseLoc, mouseRef.current.x, mouseRef.current.y);
      
      gl.drawArrays(gl.TRIANGLES, 0, 6);
      animationFrame = requestAnimationFrame(render);
    };

    animationFrame = requestAnimationFrame(render);

    return () => {
      cancelAnimationFrame(animationFrame);
      window.removeEventListener('mousemove', handleMouseMove);
    };
  }, []);

  return (
    <div className="fixed inset-0 z-[-1] overflow-hidden bg-[#022c22]">
      <canvas 
        ref={canvasRef} 
        className="w-full h-full block" 
        style={{ filter: 'contrast(1.1) brightness(1.05)' }}
      />
    </div>
  );
};

export default BotanicalBackground;

More by ashish rajwani

View all
  • ASMR background

    ASMR background

    684
  • animated pattern cloud

    animated pattern cloud

    616
  • Balloons Pop background

    Balloons Pop background

    362
  • realistic fog background

    realistic fog background

    309
  • 3d animated stars background

    3d animated stars background

    3
  • Matrix background

    Matrix background

    1
  • tab pages

    tab pages

    1
  • sleek text input

    sleek text input

More in Shaders

View all
  • Glass Fold

    Glass Fold

    212
  • Neural Noise

    Neural Noise

    717
  • Water Caustic

    Water Caustic

    44
  • Shader Background

    Shader Background

    2K
  • Wave

    Wave

    686
  • Stripe like gradient-shader

    Stripe like gradient-shader

    265
  • Black Hole

    Black Hole

    22
  • Shader Lines

    Shader Lines

    2.3K