Skip to content

umituz/react-native-mascot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@umituz/react-native-mascot

Interactive mascot system for React Native apps - Customizable animated characters with Lottie and SVG support, mood system, and easy integration.

Features

  • Pre-built Templates - Ready-to-use mascot characters
  • Lottie Animations - Professional JSON animations
  • SVG Rendering - Custom vector graphics
  • Mood System - Dynamic personality and emotions
  • State-Based Animations - 6 predefined states (idle, loading, success, error, empty, guide)
  • Auto-Transitions - Automatic state transitions (e.g., loading → success)
  • Size Variants - Built-in small, medium, large sizes
  • Optimized Performance - LRU cache, React.memo, memory leak prevention
  • Interactive - Touch-enabled mascots
  • Animation Queue - Sequence animations
  • Custom Accessories - Add glasses, hats, etc.
  • Dynamic Colors - Customize appearance
  • Type-Safe - Full TypeScript support
  • DDD Architecture - Domain-driven design

Installation

npm install @umituz/react-native-mascot

Dependencies

npm install lottie-react-native react-native-reanimated react-native-svg

Quick Start

Basic Usage

import React from 'react';
import { View } from 'react-native';
import { useMascot, MascotView } from '@umituz/react-native-mascot';

function MyApp() {
  const mascot = useMascot({
    template: 'friendly-bot',
    autoInitialize: true
  });

  return (
    <View>
      <MascotView
        mascot={mascot.mascot}
        size={200}
        onPress={() => mascot.playAnimation('wave')}
      />
    </View>
  );
}

Using Template

import { MascotFactory, MascotView } from '@umituz/react-native-mascot';

function MyScreen() {
  const mascot = MascotFactory.createFromTemplate('cute-pet', {
    appearance: {
      baseColor: '#FFB6C1',
      accentColor: '#FF69B4'
    }
  });

  return <MascotView mascot={mascot} size={150} />;
}

Custom Mascot

import { Mascot, MascotView } from '@umituz/react-native-mascot';

function CustomMascotScreen() {
  const mascot = new Mascot({
    id: 'my-mascot',
    name: 'My Mascot',
    type: 'svg',
    personality: {
      mood: 'happy',
      energy: 0.8,
      friendliness: 0.9,
      playfulness: 0.7
    },
    appearance: {
      baseColor: '#4A90E2',
      accentColor: '#50E3C2',
      accessories: [],
      style: 'cartoon',
      scale: 1
    },
    animations: [],
    interactive: true,
    touchEnabled: true
  });

  return <MascotView mascot={mascot} size={150} />;
}

State-Based Animations (NEW!)

Inspired by production apps like Vivoim Style, the new state-based system provides predefined animation states with auto-transitions:

import { useMascotState } from '@umituz/react-native-mascot';

function StatefulMascot() {
  const mascot = useMascotState({
    initialState: 'idle',
    size: 'medium',
    enableAutoTransition: true,
    onStateChange: (from, to) => console.log(`${from}${to}`),
    onAnimationComplete: (state) => console.log(`Completed: ${state}`)
  });

  return (
    <View>
      {/* Use mascot.state to drive your Lottie animations */}
      {/* mascot.size: 40 (small), 80 (medium), 120 (large), or custom number */}
      {/* mascot.isLooping: true for idle/loading/empty/guide, false for success/error */}
      {/* mascot.duration: animation duration in milliseconds */}
      {/* mascot.speed: animation speed multiplier */}

      <MascotView
        mascot={mascot.mascot}
        size={mascot.size}
      />

      <Button title="Start Loading" onPress={mascot.startLoading} />
      <Button title="Success" onPress={mascot.triggerSuccess} />
      <Button title="Error" onPress={mascot.triggerError} />
      <Button title="Reset" onPress={mascot.reset} />
    </View>
  );
}

Available States:

  • idle - Calm breathing animation (default, loops)
  • loading - Active processing animation (loops)
  • success - Confirmation animation (non-looping, auto-transitions to idle)
  • error - Error acknowledgment (non-looping, auto-transitions to idle)
  • empty - Empty state invitation (loops)
  • guide - Onboarding assistance (loops)

Auto-Transitions:

  • successidle (after 100ms delay)

  • erroridle (after 100ms delay)

  • guideidle (after 200ms delay)

  • loadingsuccess or error (when you call stopLoading(success))

    return ; }


## Available Templates

| Template | Style | Personality |
|----------|-------|-------------|
| `friendly-bot` | Cartoon | Happy & Friendly |
| `cute-pet` | Cartoon | Excited & Playful |
| `wise-owl` | Realistic | Thinking & Calm |
| `pixel-hero` | Pixel Art | Happy & Brave |

## API Reference

### useMascot Hook

```tsx
const mascot = useMascot({
  config?: MascotConfig,
  template?: string,
  autoInitialize?: boolean
});

Returns:

{
  mascot: Mascot | null,
  isReady: boolean,
  isPlaying: boolean,
  currentAnimation: string | null,
  initialize: (config: MascotConfig) => void,
  initializeFromTemplate: (template: string) => void,
  setMood: (mood: MascotMood) => void,
  setEnergy: (energy: number) => void,
  playAnimation: (animationId: string) => Promise<void>,
  stopAnimation: () => void,
  updateAppearance: (appearance: Partial<MascotAppearance>) => void,
  setBaseColor: (color: string) => void,
  setAccentColor: (color: string) => void,
  addAccessory: (accessory) => void,
  removeAccessory: (accessoryId: string) => void,
  setVisible: (visible: boolean) => void,
  setPosition: (position: { x: number, y: number }) => void
}

MascotView Component

<MascotView
  mascot={mascot}
  animation={animation}
  size={200}
  style={style}
  onPress={() => {}}
  onLongPress={() => {}}
  onAnimationFinish={() => {}}
  resizeMode="contain"
/>

MascotFactory

// Create from template
const mascot = MascotFactory.createFromTemplate('friendly-bot', customizations);

// Create custom
const mascot = MascotFactory.createCustom(config);

// Create simple
const mascot = MascotFactory.createSimple({
  id: 'my-mascot',
  name: 'My Mascot',
  baseColor: '#FF6B6B'
});

Mood System

// Change mascot mood
mascot.setMood('excited');

// Available moods
type MascotMood =
  | 'happy'
  | 'sad'
  | 'excited'
  | 'thinking'
  | 'angry'
  | 'neutral'
  | 'surprised';

Animation Control

// Play animation
await mascot.playAnimation('jump');

// Built-in animations: 'idle', 'wave', 'jump', 'success', 'error', 'dance'

// Stop animation
mascot.stopAnimation();

// With options
await mascot.playAnimation('wave', {
  speed: 1.5,
  loop: false,
  onStart: () => console.log('Started'),
  onFinish: () => console.log('Finished')
});

Customization

Appearance

// Update appearance
mascot.updateAppearance({
  baseColor: '#FF6B6B',
  accentColor: '#4ECDC4',
  scale: 1.2
});

// Set colors
mascot.setBaseColor('#FF6B6B');
mascot.setAccentColor('#4ECDC4');

// Add accessories
mascot.addAccessory({
  id: 'glasses',
  type: 'glasses',
  color: '#333',
  position: { x: 0, y: -10 }
});

// Remove accessory
mascot.removeAccessory('glasses');

Personality

// Set mood
mascot.setMood('happy');

// Set energy (0-1)
mascot.setEnergy(0.9);

// Set friendliness (0-1)
mascot.setFriendliness(1.0);

// Set playfulness (0-1)
mascot.setPlayfulness(0.8);

Context Provider

import { MascotProvider, useMascotContext } from '@umituz/react-native-mascot';

function App() {
  return (
    <MascotProvider template="friendly-bot">
      <MyScreen />
    </MascotProvider>
  );
}

function MyScreen() {
  const { mascot, playAnimation, setMood } = useMascotContext();

  return (
    <>
      <MascotView mascot={mascot} />
      <Button onPress={() => playAnimation('wave')} title="Wave" />
      <Button onPress={() => setMood('excited')} title="Get Excited" />
    </>
  );
}

Examples

Animated Mascot Response

function SuccessScreen() {
  const mascot = useMascot({ template: 'friendly-bot' });

  const handleSuccess = async () => {
    mascot.setMood('happy');
    await mascot.playAnimation('success');
    await mascot.playAnimation('dance');
  };

  return (
    <View>
      <MascotView mascot={mascot.mascot} size={200} />
      <Button onPress={handleSuccess} title="Success!" />
    </View>
  );
}

Interactive Mascot

function InteractiveMascot() {
  const mascot = useMascot({ template: 'cute-pet' });

  return (
    <View>
      <MascotView
        mascot={mascot.mascot}
        size={250}
        onPress={() => mascot.playAnimation('jump')}
        onLongPress={() => mascot.setMood('excited')}
      />
    </View>
  );
}

Custom Animated Mascot

import { useMascotAnimation } from '@umituz/react-native-mascot';

function AnimatedMascot() {
  const mascot = useMascot({ template: 'pixel-hero' });
  const { play, queueAnimation, playSequence } = useMascotAnimation({
    mascot: mascot.mascot
  });

  const performSequence = async () => {
    await playSequence(['wave', 'jump', 'dance']);
  };

  return (
    <View>
      <MascotView mascot={mascot.mascot} />
      <Button onPress={performSequence} title="Perform Sequence" />
    </View>
  );
}

Architecture

This package follows Domain-Driven Design (DDD) principles:

  • Domain Layer: Entities, value objects, interfaces
  • Infrastructure Layer: Repositories, controllers, managers
  • Presentation Layer: Components, hooks, contexts

Contributing

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

License

MIT © Ümit UZ

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors