JSPM

  • Created
  • Published
  • Downloads 66
  • Score
    100M100P100Q57564F
  • License MIT

A React package for 3D avatar animations with customizable GLB models and actions

Package Exports

  • ryd-avatar
  • ryd-avatar/dist/index.cjs.js
  • ryd-avatar/dist/index.esm.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (ryd-avatar) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

RYD Avatar

RYD Avatar Version Downloads License

The most professional and ultra-customizable React package for 3D avatar animations. Place it anywhere, make it any size, and customize every aspect of its behavior.

🚀 Quick Start📖 Documentation🎨 Examples🔧 API Reference❓ FAQ

✨ Features

  • 🎭 Ultra-Customizable - Place anywhere, make any size, customize everything
  • 🎬 Professional Quality - Studio-grade lighting, shadows, and rendering
  • 🔧 Dynamic Action Management - Add, remove, and modify actions at runtime
  • 🎮 Interactive Controls - Built-in hover, click, and touch interactions
  • 🎨 20+ Size Presets - From tiny icons to fullscreen displays
  • 💡 8 Lighting Presets - Bright, soft, dim, dramatic, minimal, warm, cool, studio
  • 📱 Responsive Design - Auto-adapts to any container or screen size
  • 🎤 TTS Integration - Built-in support for text-to-speech synchronization
  • 📦 Lightweight - 22.4 kB bundle size - you provide your own GLB files
  • React 19 Compatible - Full support for React 16.8+ through React 19
  • 🛡️ Production Ready - Error handling, loading states, and WebGL recovery
  • 🎯 TypeScript Ready - Complete type definitions and IntelliSense support

🚀 Quick Start

Installation

npm install ryd-avatar@latest

Basic Usage

import React, { useEffect } from 'react';
import { RYDAvatar, AvatarProvider, useAvatar } from 'ryd-avatar';

function MyAvatar() {
  const { addAction, playAction } = useAvatar();

  useEffect(() => {
    // Add your GLB files with semantic presets
    addAction('idle', {
      model: '/assets/idle.glb',        // Your GLB file
      animationIndex: 0,
      loop: true,
      speed: 'normal',                  // 'slow', 'normal', 'fast', 'very-fast', 'super-fast'
      scale: 'large',                   // 'tiny', 'small', 'medium', 'large', 'xlarge', 'huge'
      position: 'center',               // 'center', 'left', 'right', 'top', 'bottom', 'floating', 'grounded'
      rotation: 'front-slight',         // 'front', 'left', 'right', 'back', 'tilted', 'dynamic'
      autoPlaySound: false
    });

    // Start with idle animation
    playAction('idle');
  }, [addAction, playAction]);

  return (
    <AvatarProvider>
      <RYDAvatar 
        size="medium" 
        lighting="studio" 
        responsive={true}
        enableHover={true}
      />
    </AvatarProvider>
  );
}

export default MyAvatar;

📖 Documentation

🎨 Semantic Presets

The package uses semantic words instead of numbers, making it incredibly easy to customize:

Size Presets

// Tiny sizes - for icons, badges
<RYDAvatar size="tiny" />          // 48x64px - for icons, badges
<RYDAvatar size="icon" />          // 64x80px - for icons
<RYDAvatar size="badge" />         // 80x100px - for badges

// Small sizes - for buttons, small widgets
<RYDAvatar size="small" />         // 120x160px - for buttons
<RYDAvatar size="button" />        // 150x200px - for buttons
<RYDAvatar size="thumbnail" />     // 180x240px - for thumbnails

// Medium sizes - for cards, sidebars
<RYDAvatar size="medium" />        // 250x320px - for cards
<RYDAvatar size="card" />          // 300x400px - for cards
<RYDAvatar size="sidebar" />       // 350x450px - for sidebars

// Large sizes - for main content areas
<RYDAvatar size="large" />         // 400x500px - for main content
<RYDAvatar size="hero" />          // 500x650px - for hero sections
<RYDAvatar size="banner" />        // 600x750px - for banners

// Extra large sizes
<RYDAvatar size="xlarge" />        // 700x900px - extra large
<RYDAvatar size="fullscreen" />    // 800x1000px - fullscreen
<RYDAvatar size="cinematic" />     // 1000x1200px - cinematic

// Responsive sizes
<RYDAvatar size="mobile" />        // 280x350px - mobile optimized
<RYDAvatar size="tablet" />        // 400x500px - tablet optimized
<RYDAvatar size="desktop" />       // 600x750px - desktop optimized

// Aspect ratio specific
<RYDAvatar size="square" />        // 300x300px - square
<RYDAvatar size="wide" />          // 400x200px - wide
<RYDAvatar size="portrait" />      // 200x300px - portrait
<RYDAvatar size="landscape" />     // 400x250px - landscape

// Custom dimensions
<RYDAvatar width={300} height={400} />
<RYDAvatar width="100%" height="auto" aspectRatio="3/4" />

Animation Presets

addAction('dance', {
  speed: 'slow',        // 0.5x - slow motion
  speed: 'normal',      // 1.0x - normal speed
  speed: 'fast',        // 1.5x - fast
  speed: 'very-fast',   // 2.0x - very fast
  speed: 'super-fast',  // 3.0x - super fast
  
  scale: 'tiny',        // 0.5x - very small
  scale: 'small',       // 0.8x - small
  scale: 'medium',      // 1.0x - normal size
  scale: 'large',       // 1.5x - large (default)
  scale: 'xlarge',      // 2.0x - extra large
  scale: 'huge',        // 3.0x - huge
  
  position: 'center',   // Perfect center placement
  position: 'left',     // Left side
  position: 'right',    // Right side  
  position: 'top',      // Top placement
  position: 'bottom',   // Bottom placement
  position: 'floating', // Floating above ground
  position: 'grounded', // Grounded placement
  
  rotation: 'front',        // Facing forward
  rotation: 'left',         // Facing left
  rotation: 'right',        // Facing right
  rotation: 'back',         // Facing back
  rotation: 'tilted',       // Slightly tilted
  rotation: 'dynamic',      // Dynamic movement
  rotation: 'front-slight', // Front with slight tilt
  rotation: 'front-up',     // Front looking up
  rotation: 'front-down',   // Front looking down
});

Lighting Presets

<RYDAvatar lighting="bright" />    // Bright and energetic
<RYDAvatar lighting="soft" />      // Soft and gentle
<RYDAvatar lighting="dim" />       // Dim and subtle
<RYDAvatar lighting="dramatic" />  // Dramatic and bold
<RYDAvatar lighting="minimal" />   // Minimal and clean
<RYDAvatar lighting="warm" />      // Warm and cozy
<RYDAvatar lighting="cool" />      // Cool and professional
<RYDAvatar lighting="studio" />    // High-quality studio lighting

🎯 Ultra-Customizable Features

The package is now ultra-customizable with professional-grade features:

Interactive Controls

<RYDAvatar 
  enableHover={true}              // Enable hover interactions
  onHover={(action) => {          // Hover callback
    console.log('Hover:', action);
  }}
  onClick={() => {                // Click callback
    console.log('Avatar clicked!');
  }}
/>

Responsive Design

<RYDAvatar 
  responsive={true}               // Auto-responsive
  width="100%"                    // Full width
  maxWidth="400px"                // Max width constraint
  aspectRatio="3/4"               // Maintain aspect ratio
/>

Loading & Error States

<RYDAvatar 
  loading={isLoading}             // Show loading state
  loadingComponent={              // Custom loading component
    <div>Loading...</div>
  }
  errorComponent={                // Custom error component
    <div>Error loading avatar</div>
  }
  debug={true}                   // Show debug info
/>

Professional Styling

<RYDAvatar 
  className="my-avatar"           // Custom CSS class
  style={{                       // Custom styles
    borderRadius: '10px',
    boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
    border: '2px solid #007bff',
    margin: '20px'
  }}
  background="#f0f0f0"           // Background color
/>

🎮 Function-Based Control

The package is designed for complete programmatic control:

const {
  // Action control
  playAction,    // Play an action with optional custom sound
  stopAction,    // Stop current action and sound
  pauseAction,   // Pause current action and sound
  resumeAction,  // Resume paused action and sound
  
  // Sound control
  playSound,     // Play custom sound
  stopSound,     // Stop current sound
  
  // Action management
  addAction,     // Add new action
  removeAction,  // Remove action
  updateAction,  // Update existing action
  
  // State
  currentState,  // Current action state
  isPlaying,     // Whether animation is playing
  actions        // All available actions
} = useAvatar();

🎤 TTS Integration

Built-in support for text-to-speech synchronization:

addAction('talking', {
  model: '/assets/talking.glb',
  animationIndex: 0,
  loop: true,
  speed: 'fast',
  scale: 'large',
  position: 'center',
  rotation: 'front-slight',
  
  // Sound configuration
  sound: '/assets/default-tts.mp3',  // Default sound file
  autoPlaySound: true,               // Auto-play when action starts
  soundVolume: 0.8,                  // Volume (0-1)
  soundDelay: 0                      // Delay before playing (ms)
});

// Custom TTS integration
const handleTTS = async (text) => {
  const audioUrl = await generateTTS(text); // Your TTS function
  playAction('talking', audioUrl); // Play action with custom sound
};

🎨 Examples

Professional Header Avatar

<RYDAvatar 
  size="icon" 
  lighting="cool" 
  style={{ width: '60px', height: '80px' }}
/>

Hero Section Avatar

<RYDAvatar 
  size="hero" 
  lighting="studio" 
  enableHover={true}
  responsive={true}
/>

Interactive Card Avatar

<RYDAvatar 
  size="card" 
  lighting="warm" 
  enableHover={true}
  onHover={(action) => console.log('Hover:', action)}
  style={{ borderRadius: '10px' }}
/>

Responsive Avatar

<RYDAvatar 
  size="medium" 
  lighting="soft" 
  responsive={true}
  width="100%"
  maxWidth="400px"
/>

Custom Sized Avatar

<RYDAvatar 
  width={300} 
  height={400} 
  lighting="dramatic"
  aspectRatio="3/4"
/>

Multiple Actions

function AvatarController() {
  const { addAction, playAction } = useAvatar();

  useEffect(() => {
    addAction('idle', {
      model: '/assets/idle.glb',
      animationIndex: 0,
      loop: true,
      speed: 'normal',
      scale: 'large',
      position: 'center',
      rotation: 'front-slight'
    });

    addAction('dance', {
      model: '/assets/dance.glb',
      animationIndex: 0,
      loop: true,
      speed: 'fast',
      scale: 'large',
      position: 'center',
      rotation: 'dynamic'
    });

    addAction('celebration', {
      model: '/assets/celebration.glb',
      animationIndex: 0,
      loop: false,
      speed: 'very-fast',
      scale: 'xlarge',
      position: 'floating',
      rotation: 'dynamic',
      sound: '/assets/celebration.mp3',
      autoPlaySound: true
    });

    // Start with idle
    playAction('idle');
  }, [addAction, playAction]);

  return (
    <div>
      <RYDAvatar size="main" lighting="soft" />
      
      <div style={{ marginTop: '20px' }}>
        <button onClick={() => playAction('idle')}>Idle</button>
        <button onClick={() => playAction('dance')}>Dance</button>
        <button onClick={() => playAction('celebration')}>Celebrate</button>
      </div>
    </div>
  );
}

Dynamic Action Management

const { addAction, removeAction, updateAction } = useAvatar();

// Add new action at runtime
addAction('yoga', {
  model: '/assets/yoga.glb',
  animationIndex: 0,
  loop: true,
  speed: 'slow',
  scale: 'large',
  position: 'center',
  rotation: 'front-slight'
});

// Update existing action
updateAction('dance', { speed: 'super-fast', scale: 'huge' });

// Remove action
removeAction('yoga');

Real-World Usage Examples

Header Avatar

function Header() {
  return (
    <header style={{ display: 'flex', alignItems: 'center', padding: '1rem' }}>
      <h1>My App</h1>
      <div style={{ marginLeft: 'auto' }}>
        <RYDAvatar 
          size="icon"
          style={{ width: '60px', height: '80px' }}
        />
      </div>
    </header>
  );
}

User Profile Card

function UserCard() {
  return (
    <div className="user-card">
      <RYDAvatar 
        size="card"
        lighting="warm"
        enableHover={true}
        onHover={(action) => {
          if (action === 'enter') {
            // Show user details
          }
        }}
      />
      <h3>John Doe</h3>
      <p>Software Developer</p>
    </div>
  );
}

Landing Page Hero

function HeroSection() {
  return (
    <section className="hero">
      <h1>Welcome to Our Platform</h1>
      <p>Meet your AI assistant</p>
      <RYDAvatar 
        size="hero"
        lighting="studio"
        style={{ 
          width: '500px', 
          height: '650px',
          margin: '2rem auto'
        }}
      />
    </section>
  );
}

Responsive Grid

function AvatarGrid() {
  return (
    <div style={{ 
      display: 'grid', 
      gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', 
      gap: '1rem' 
    }}>
      <RYDAvatar size="small" />
      <RYDAvatar size="small" />
      <RYDAvatar size="small" />
    </div>
  );
}

🔧 API Reference

Components

RYDAvatar

The main avatar component.

Props:

  • className (string): Custom CSS class
  • style (object): Custom styles (width, height, etc.)
  • width (string|number): Container width (px, %, or preset)
  • height (string|number): Container height (px, %, or preset)
  • size (string): Size preset ('tiny', 'small', 'medium', 'large', 'hero', 'fullscreen', etc.)
  • lighting (string|object): Lighting preset ('bright', 'soft', 'dim', 'dramatic', 'minimal', 'warm', 'cool', 'studio') or custom configuration
  • enableShadows (boolean): Enable contact shadows (default: true)
  • enableLights (boolean): Enable default lighting (default: true)
  • camera (object): Camera configuration
  • responsive (boolean): Enable responsive behavior (default: true)
  • aspectRatio (string): CSS aspect ratio (e.g., '3/4', '16/9', '1/1')
  • autoResize (boolean): Auto-resize based on container (default: false)
  • background (string): Background color or 'transparent' (default: 'transparent')
  • enableHover (boolean): Enable hover interactions (default: false)
  • onHover (function): Hover callback
  • onClick (function): Click callback
  • loading (boolean): Show loading state (default: false)
  • loadingComponent (ReactNode): Custom loading component
  • errorComponent (ReactNode): Custom error component
  • debug (boolean): Enable debug mode (default: false)

AvatarProvider

Context provider for avatar state management.

Props:

  • children (ReactNode): Child components
  • customActions (object): Custom action configurations
  • defaultState (string): Default avatar state
  • onStateChange (function): Callback when state changes
  • onAnimationComplete (function): Callback when animation completes

Hooks

useAvatar()

Hook for controlling avatar actions and state.

Returns:

  • currentState (string): Current avatar state
  • isPlaying (boolean): Whether animation is playing
  • actions (object): Available actions
  • playAction (function): Play specific action
  • stopAction (function): Stop current action
  • pauseAction (function): Pause current action
  • resumeAction (function): Resume current action
  • playSound (function): Play custom sound
  • stopSound (function): Stop current sound
  • addAction (function): Add new action
  • removeAction (function): Remove action
  • updateAction (function): Update existing action
  • hasAction (function): Check if action exists
  • getCurrentAction (function): Get current action config
  • getAvailableActions (function): Get all available actions

Action Configuration

Each action is configured with the following properties:

{
  model: string,                    // Path to GLB model file
  animationIndex: number,           // Index of animation in GLB file
  loop: boolean,                    // Whether animation should loop
  speed: number|string,             // Animation speed (number or preset)
  scale: number|string,             // Model scale (number or preset)
  position: [x, y, z]|string,       // Model position (array or preset)
  rotation: [x, y, z]|string,       // Model rotation (array or preset)
  sound: string|Audio,              // Sound file path or Audio object
  autoPlaySound: boolean,           // Whether to auto-play sound
  soundVolume: number,              // Sound volume (0-1)
  soundDelay: number,               // Delay before playing sound (ms)
  label: string,                    // Display label
  icon: string,                     // Emoji or icon
  color: string                     // Color theme
}

❓ FAQ

Q: Do I need to provide my own GLB files?

A: Yes! The package is lightweight and doesn't include any GLB files. You need to provide your own GLB models with animations.

Q: What GLB file format is supported?

A: Any GLB file with animations. The package uses Three.js GLTFLoader, so it supports the standard GLB format.

Q: How do I find the right animation index?

A: Most GLB files have the main animation at index 0. If that doesn't work, try indices 1, 2, 3, etc. You can also use browser dev tools to inspect the GLB file.

Q: Why is my animation not playing?

A: Common issues:

  • Wrong animation index (try 1, 2, 3 instead of 0)
  • Animation speed too slow (try 'fast' or 'very-fast')
  • GLB file doesn't contain animations
  • WebGL context issues (try refreshing the page)

Q: Is this compatible with React 19?

A: Yes! The package supports React 16.8+ through React 19. There may be some version warnings with React 19, but they don't affect functionality.

Q: Can I use this in production?

A: Absolutely! The package is production-ready and includes WebGL context recovery, error handling, and performance optimizations.

Q: How do I handle WebGL context loss?

A: The package automatically handles WebGL context loss and recovery. If you encounter issues, try refreshing the page or using the restart functionality.

🛠️ Requirements

  • React 16.8.0, 17.x, 18.x, or 19.x
  • Three.js compatible browser
  • WebGL support
  • Your own GLB files with animations

📦 Dependencies

  • @react-three/fiber: React renderer for Three.js
  • @react-three/drei: Useful helpers for react-three-fiber
  • three: 3D graphics library

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🆘 Support

🌟 Star History

Star History Chart


Made with ❤️ by the RYD Team

⭐ Star this repo🐛 Report Bug💡 Request Feature