KUJI (くじ) means "lottery" in Japanese. An interactive 3D lottery application with animated robot characters, cinematic effects, and smooth transitions.
🎮 Live Demo | 📖 Read this in other languages: 한국어 | 日本語
Concept image generated by Google Gemini (Nano Banana)
- 🎭 3D Animated Characters - Interactive robot models with random animations
- 🎲 Random Lottery System - Fair selection with dramatic reveals
- ✨ Particle Effects - Gold bursts, sparkles, and firework celebrations
- 📸 Unique Avatars - DiceBear integration for each character
- 💾 Auto-Save - LocalStorage persistence for progress tracking
- 📱 Responsive Design - Works on desktop and mobile
- 🎬 Cinematic Transitions - Smooth camera movements and lighting effects
- 📊 Progress Tracking - Real-time statistics display
- 🌐 Multi-Language Support - English, Japanese (日本語), Korean (한국어) with URL parameter support
KUJIKUJI supports three languages with automatic detection and persistence:
- 🇺🇸 English (default)
- 🇯🇵 Japanese (日本語)
- 🇰🇷 Korean (한국어)
Click the language dropdown (🌐) in the top-right corner of any page and select your preferred language. Your choice is automatically saved to localStorage.
You can set the language directly via URL parameters:
# English
http://localhost:8000/index.html?lang=en
# Japanese
http://localhost:8000/index.html?lang=ja
# Korean
http://localhost:8000/index.html?lang=ko
This works on both index.html and select.html pages.
- Translation Files:
locales/translations.json- JSON-based translation system - i18n Module:
js/i18n.js- Handles language loading, switching, and DOM updates - Persistence: Language preference is saved to localStorage as
preferredLanguage - Dynamic Updates: All text content updates instantly when language changes
- Attributes: Uses
data-i18nanddata-i18n-placeholderattributes for automatic translation
Choose one of three input methods:
- Number Generation: Enter a number (1-50) to auto-generate characters named "User 1", "User 2", etc.
- Text Paste: Copy and paste names from Excel or a text file (one name per line)
- Manual Addition: Click the "+ Add" button to add characters one by one
Each character gets a unique robot avatar from DiceBear. You can edit names or delete characters before starting.
- Click the "Start" button to proceed to the 3D scene
- Characters are randomly arranged in a circular pattern
- The camera smoothly descends to reveal all characters
- Watch as characters perform random animations
-
Click the "GO" button to randomly select a character
-
Enjoy the dramatic reveal:
- Background darkens
- Spotlight focuses on the winner
- Particle effects burst
- Character performs emotes
- Name card flips to reveal identity
-
Click "RETURN" to go back to the overview
-
Repeat until all characters are selected
- Progress is tracked in the top-left corner
- When all characters are selected, you'll be prompted to restart
- All data persists in localStorage between sessions
- A modern web browser with WebGL support
- LocalStorage enabled
- Local web server (or use the methods below)
- Clone the repository:
git clone https://github.com/siriz/kujikuji.git
cd kujikuji- Serve the files using a local web server:
Option 1: Using Python
# Python 3
python -m http.server 8000
# Python 2
python -m SimpleHTTPServer 8000Option 2: Using Node.js
npx http-serverOption 3: Using VS Code
- Install the "Live Server" extension
- Right-click on
index.htmland select "Open with Live Server"
- Open your browser and navigate to:
http://localhost:8000
kujikuji/
├── index.html # Character input screen (entry point)
├── select.html # Main 3D lottery selection scene
├── test/
│ └── robot.html # Debug tool for avatar positioning
├── css/
│ ├── main.css # Global stylesheet
│ ├── select.css # Select page specific styles
│ └── language-selector.css # Language selector dropdown styles
├── js/
│ ├── main.js # Main 3D scene logic
│ ├── storage.js # LocalStorage data management
│ ├── utils.js # Utility functions (positioning, collision detection)
│ ├── particles.js # Particle effect system
│ └── i18n.js # Internationalization system
├── locales/
│ └── translations.json # Multi-language translations (en/ja/ko)
├── libs/
│ ├── gsap/
│ │ └── gsap.min.js # GSAP animation library (local)
│ └── threejs/ # Three.js library files
│ ├── build/
│ │ └── three.module.js
│ └── jsm/ # Three.js addons and utilities
│ ├── controls/ # OrbitControls
│ ├── loaders/ # GLTFLoader, FontLoader
│ ├── geometries/ # TextGeometry
│ └── libs/ # Stats, GUI
│ ├── models/ # 3D model files
│ │ └── gltf/
│ │ └── RobotExpressive/
│ └── fonts/ # Font files for 3D text
│ └── optimer_bold.typeface.json
├── models/ # 3D model files
│ └── gltf/
│ └── RobotExpressive/
└── fonts/ # Font files for 3D text
└── optimer_bold.typeface.json
- Three.js - 3D graphics library
- GSAP - Animation library
- DiceBear API - Avatar generation
- WebGL - Hardware-accelerated 3D rendering
- LocalStorage - Client-side data persistence
- i18n System - JSON-based internationalization (en/ja/ko)
See the License section below for detailed third-party library information and licenses.
For developers who want to adjust the robot avatar positioning, we provide a debug tool:
Location: test/robot.html
Features:
- Real-time avatar position adjustment (X, Y, Z with 0.001 precision)
- Rotation controls (X, Y, Z with 0.1° precision)
- 50-state undo/redo system
- Visual wireframe helpers for Head_3 bone
- Interactive controls with immediate feedback
Usage:
# Start local server (if not already running)
python -m http.server 8000
# Open in browser
http://localhost:8000/test/robot.htmlUse the sliders and input fields to fine-tune the avatar plane position and rotation. Changes can be undone/redone using the buttons or keyboard shortcuts (Ctrl+Z / Ctrl+Y).
- Open
index.html - Use any of the three input methods
- Characters are automatically saved to localStorage
Edit js/particles.js to customize particle effects. Available effects:
Colorful confetti pieces exploding from the center like fireworks:
ParticleEffects.createConfettiBurst(scene, position, {
particleCount: 150,
explosionForce: 0.4,
duration: 4.5
});Confetti falling gently from the sky with swaying motion:
ParticleEffects.createConfettiRain(scene, camera, {
particleCount: 120,
duration: 6,
fallSpeed: 0.025
});Combined effect with burst + rain for maximum celebration:
ParticleEffects.createConfettiCelebration(scene, position, camera);Rising golden particles with spiral motion:
ParticleEffects.createSelectionEffect(scene, position, {
particleCount: 100, // More particles
color: 0xFF0000, // Red particles
duration: 3 // Longer animation
});Explosive particle bursts with gravity:
ParticleEffects.createFireworkEffect(scene, position, {
particleCount: 120,
explosionForce: 0.3
});A dedicated demo page is available to test all confetti effects:
Location: test/confetti-demo.html
Features:
- 💥 Confetti Burst: Firework-style explosion
- 🌧️ Confetti Rain: Gentle falling motion
- 🎊 Full Celebration: Combined burst + rain
- ✨ Classic Effects: Original particle system
Usage:
# Open in browser
http://localhost:8000/test/confetti-demo.htmlClick the colorful buttons to trigger different effects. You can click multiple times to layer effects for spectacular celebrations!
Modify js/utils.js → generatePositions():
- Adjust
minDistancefor spacing - Change layer spacing
- Modify circular/spiral patterns
{
"characters": [
{
"id": "unique-id",
"name": "Character Name",
"avatarSeed": "random-seed",
"selected": false,
"selectedAt": null,
"createdAt": "2025-10-26T..."
}
],
"selectedCharacters": [],
"createdAt": "2025-10-26T...",
"updatedAt": "2025-10-26T..."
}- Export: Click the "Export Data" button to download JSON backup
- Reset: Clear all data and start fresh
- Persist: Data automatically saves after each action
The robots support various animation states:
- States: Idle, Walking, Running, Dance, Sitting, Standing, Death
- Emotes: Jump, Yes, No, Wave, Punch, ThumbsUp
Characters randomly perform these animations when not selected.
- Chrome (recommended)
- Firefox
- Safari
- Edge
- Opera
Note: Requires WebGL support. Some older browsers or devices may not be compatible.
Contributions are welcome! Feel free to:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
This project uses the following external libraries and assets, each with their own licenses:
- Location:
libs/threejs/ - License: MIT License
- URL: https://threejs.org/
- Copyright: Copyright © 2010-2024 Three.js authors
- Location:
libs/gsap/ - License: GreenSock Standard License (free for most use cases)
- URL: https://greensock.com/licensing/
- Note: Commercial projects may require a license
- Location:
libs/models/gltf/RobotExpressive/ - Source: Three.js Examples
- License: MIT License (as part of Three.js examples)
- URL: https://github.com/mrdoob/three.js/tree/master/examples/models/gltf
- Location:
libs/fonts/ - License: MgOpen License (Free for commercial and non-commercial use)
- URL: http://www.ellak.gr/fonts/MgOpen/
- Copyright: Copyright (c) 2004 by MAGENTA Ltd.
- Note: Free to use, copy, merge, publish, and distribute
- Service: Avatar generation (external API)
- License: Free for personal and commercial use
- URL: https://www.dicebear.com/
- Style Used: bottts-neutral
All third-party components retain their original licenses. Please refer to their respective license files in the libs/ directory for full license texts.
- Three.js team for the amazing 3D library and examples
- GSAP team for the smooth animation framework
- Robot model from Three.js examples (RobotExpressive)
- MgOpen Fonts project for beautiful typefaces
- DiceBear for the avatar generation API
siriz - @siriz
Project Link: https://github.com/siriz/kujikuji
Made with ❤️ and Three.js


