excalidraw/docs/threejs-libraries.md
2025-09-22 21:47:06 -06:00

5.7 KiB

Three.js Libraries for Advanced Liquid Glass Effects

React Three Fiber Ecosystem

1. React Three Fiber (@react-three/fiber)

Purpose: React bindings for Three.js Why Perfect for Excalidraw: Integrates seamlessly with your existing React architecture

import { Canvas } from '@react-three/fiber'

function GlassMenu() {
  return (
    <Canvas>
      <LiquidGlassMesh />
    </Canvas>
  )
}

2. Drei (@react-three/drei)

Purpose: Pre-built components and utilities for R3F Key Components for Glass Effects:

  • MeshTransmissionMaterial - Realistic glass/liquid refraction
  • Text - 3D text with glass properties
  • Float - Floating/hovering animations
  • Environment - HDRI environments for realistic reflections
import { MeshTransmissionMaterial, Float } from '@react-three/drei'

function GlassMenuItem() {
  return (
    <Float speed={2} rotationIntensity={0.1} floatIntensity={0.2}>
      <mesh>
        <boxGeometry args={[2, 0.5, 0.1]} />
        <MeshTransmissionMaterial
          transmission={0.9}
          roughness={0.1}
          thickness={0.5}
          ior={1.5}
          chromaticAberration={0.02}
        />
      </mesh>
    </Float>
  )
}

3. React Spring Three (@react-spring/three)

Purpose: Physics-based animations Perfect for: Mercury-like surface tension behavior

import { useSpring, animated } from '@react-spring/three'

function MercuryDroplet({ separated }) {
  const { position, scale } = useSpring({
    position: separated ? [2, 0, 0] : [0, 0, 0],
    scale: separated ? 0.8 : 1,
    config: { tension: 280, friction: 60 } // Mercury-like physics
  })
  
  return (
    <animated.mesh position={position} scale={scale}>
      {/* Glass geometry */}
    </animated.mesh>
  )
}

Shader Libraries

4. Three.js Shader Material

Purpose: Custom glass displacement shaders Implementation: Advanced refraction and chromatic aberration

// Fragment shader for liquid glass
uniform float time;
uniform float displacement;
uniform vec3 aberrationStrength;

varying vec2 vUv;

void main() {
  // Displacement calculation
  vec2 distortedUv = vUv + sin(vUv * 10.0 + time) * displacement;
  
  // Chromatic aberration
  float r = texture2D(backgroundTexture, distortedUv + aberrationStrength.r).r;
  float g = texture2D(backgroundTexture, distortedUv + aberrationStrength.g).g;
  float b = texture2D(backgroundTexture, distortedUv + aberrationStrength.b).b;
  
  gl_FragColor = vec4(r, g, b, 0.8);
}

5. Lamina (Shader Material Builder)

Purpose: Visual shader editor for complex effects Benefits: No GLSL knowledge required, visual node editor

import { DiscardMaterial } from 'lamina'

<mesh>
  <DiscardMaterial
    baseMaterial={MeshPhysicalMaterial}
    onBeforeCompile={(shader) => {
      // Custom glass modifications
    }}
  />
</mesh>

Physics and Interaction Libraries

6. use-gesture (@use-gesture/react)

Purpose: Advanced gesture handling Perfect for: Drag-to-separate droplet interactions

import { useDrag } from '@use-gesture/react'

function DraggableMenuItem() {
  const [{ x, y }, api] = useSpring(() => ({ x: 0, y: 0 }))
  
  const bind = useDrag(({ offset: [ox, oy], active }) => {
    api.start({ x: ox, y: oy, immediate: active })
    
    // Surface tension - snap back when released
    if (!active) {
      api.start({ x: 0, y: 0, config: { tension: 300, friction: 30 } })
    }
  })
  
  return (
    <animated.div {...bind()} style={{ x, y }}>
      {/* Menu item content */}
    </animated.div>
  )
}

7. Cannon.js Physics (use-cannon)

Purpose: Realistic physics simulation For Advanced Effects: True fluid dynamics simulation

import { useBox, useSphere, Physics } from '@react-three/cannon'

function PhysicsGlassMenu() {
  return (
    <Physics>
      <MainGlassContainer />
      <FloatingMenuItem />
    </Physics>
  )
}

Phase 1: CSS Prototype (Current)

  • Use the CSS version I provided above
  • Test user interactions and visual appeal
  • Validate performance on your target devices

Phase 2: Basic Three.js Integration

npm install @react-three/fiber @react-three/drei @react-spring/three

Phase 3: Advanced Glass Materials

// Advanced glass menu component
function AdvancedGlassMenu() {
  return (
    <Canvas>
      <Environment preset="studio" />
      <GlassMenuContainer>
        {menuItems.map((item, index) => (
          <GlassMenuItem key={index} {...item} />
        ))}
      </GlassMenuContainer>
    </Canvas>
  )
}

Phase 4: Mercury Physics

  • Implement surface tension using React Spring
  • Add gesture-based separation with use-gesture
  • Fine-tune physics parameters for mercury-like behavior

Integration with Excalidraw Architecture

Vite Configuration Updates

// vite.config.mts additions
export default {
  // ... existing config
  optimizeDeps: {
    include: ['@react-three/fiber', '@react-three/drei']
  },
  resolve: {
    alias: {
      // Ensure Three.js uses single instance
      'three': 'three'
    }
  }
}

Performance Considerations

  • WebGL Fallback: Graceful degradation to CSS version
  • Bundle Size: Tree-shake unused Three.js features
  • Mobile Support: Simplified effects for touch devices
  • Accessibility: Maintain keyboard navigation

Next Steps for Your Implementation

  1. Start with CSS prototype (provided above)
  2. Test in your Excalidraw environment
  3. Choose Three.js approach based on complexity needs:
    • Simple: Just MeshTransmissionMaterial
    • Advanced: Custom shaders + physics
  4. Implement progressive enhancement
  5. A/B test with users for optimal mercury physics settings