High-performance, framework-agnostic NPM library that renders cinematic experiences from JSON specifications targeting 60-120fps performance
npm install cinematic-renderer2dHigh-performance, framework-agnostic NPM library that renders cinematic experiences from JSON specifications targeting 60-120fps performance across web frameworks.
Try it Live! - Explore examples and create your own cinematic experiences
- š High Performance: Targets 60-120fps with optimized rendering backends and precompiled animations
- šÆ Framework Agnostic: Works with React, Angular, Vue, Next.js, or plain JavaScript
- šØ Multiple Backends: DOM, Canvas2D rendering with future WebGL support
- š± Adaptive Quality: Automatic performance optimization based on device capabilities and FPS monitoring
- šµ Audio Integration: Synchronized audio tracks with fade effects, multi-track support, and WebAudio API
- š§ TypeScript: Full type safety with comprehensive interfaces and definitions
- š¦ Tree Shakeable: ESM/CJS dual output with optimized bundles and tree-shaking
- š Layer System: Extensible plugin architecture for custom visual elements
- š¬ CLI Tools: Validation and preview tools for development workflow
- š„ Camera System: Viewport transformations with zoom, pan, and rotation
- š Light Layers: Cinematic lighting with radial, spot, ambient, and vignette modes
- š Scene Transitions: Smooth transitions with crossfade, slide, zoom, wipe, dissolve, and blur
- šØ Enhanced Animations: Looping, yoyo, keyframes, stagger effects, and randomization
- š Advanced Audio: Per-track control, fade in/out, crossfading, and multi-track mixing
- ā” Performance Monitor: Auto quality adjustment based on real-time FPS monitoring
- š«ļø New Layer Types: Fog, enhanced vignette, parallax groups, and glow effects
- š State Machine: Well-defined renderer and scene states with lifecycle management
- š¦ Asset Preloader: Intelligent preloading with caching and priority loading
- š· Shape Layers (NEW): Native geometric shapes (circles, rectangles, stars, polygons) with full animation support
``bash`
npm install cinematic-renderer2d
š Complete Documentation - Interactive documentation landing page
š® Live Playground - Try examples and create your own
`typescript
import { CinematicRenderer2D } from 'cinematic-renderer2d';
const renderer = new CinematicRenderer2D({
container: document.getElementById('cinematic-container'),
spec: {
schemaVersion: '1.0.0',
engine: {
targetFps: 60,
quality: 'auto',
debug: false
},
events: [{
id: 'intro',
name: 'Introduction',
scenes: ['scene1']
}],
scenes: [{
id: 'scene1',
name: 'Opening Scene',
duration: 5000,
layers: [{
id: 'background',
type: 'gradient',
zIndex: 1,
config: {
opacity: 1,
colors: ['#000000', '#333333']
},
animations: [{
property: 'opacity',
from: 0,
to: 1,
startMs: 0,
endMs: 1000,
easing: 'ease-in-out'
}]
}]
}]
}
});
// Mount and start playback
await renderer.mount();
renderer.play();
// Event handling
renderer.on('play', () => console.log('Playback started'));
renderer.on('pause', () => console.log('Playback paused'));
renderer.on('end', () => console.log('Playback completed'));
`
// Navigation and Control
`typescript
// Playback control
renderer.play();
renderer.pause();
renderer.stop();
// Navigation
renderer.seek(2500); // Seek to 2.5 seconds
renderer.goToEvent('intro');
renderer.goToScene('scene1');
// Quality control
renderer.setQuality('high'); // 'low', 'medium', 'high', 'ultra', 'auto'
// Camera control (NEW)
renderer.setCameraState({ zoom: 2.0, x: 100, y: 50, rotation: 45 });
renderer.addCameraAnimation({
property: 'zoom',
from: 1.0,
to: 2.0,
startMs: 0,
endMs: 2000,
easing: 'ease-in-out'
});
renderer.resetCamera();
// Audio control (NEW)
renderer.setMasterVolume(0.8);
const volume = renderer.getMasterVolume();
// Performance monitoring (NEW)
const fps = renderer.getCurrentFps();
const metrics = renderer.getPerformanceMetrics();
// Debug mode (NEW)
renderer.toggleDebug();
renderer.showDebug();
renderer.hideDebug();
// Cleanup
renderer.destroy();
`
`tsx
import { CinematicPlayer } from 'cinematic-renderer2d/react';
function App() {
const [isPlaying, setIsPlaying] = useState(false);
return (
autoplay={true}
onPlay={() => setIsPlaying(true)}
onPause={() => setIsPlaying(false)}
onEnd={() => setIsPlaying(false)}
onError={(error) => console.error('Playback error:', error)}
/>
);
}
`
#### React Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| spec | CinematicSpec | required | JSON specification for the cinematic experience |autoplay
| | boolean | false | Start playback automatically when mounted |quality
| | QualityLevel | 'auto' | Quality level: 'low', 'medium', 'high', 'ultra', 'auto' |debug
| | boolean | false | Enable debug overlay with performance metrics |onPlay
| | () => void | - | Called when playback starts |onPause
| | () => void | - | Called when playback pauses |onStop
| | () => void | - | Called when playback stops |onEnd
| | () => void | - | Called when playback completes |onError
| | (error: Error) => void | - | Called when an error occurs |
`typescript
import { CinematicPlayerComponent } from 'cinematic-renderer2d/angular';
@Component({
selector: 'app-root',
template:
[autoplay]="true"
[quality]="'auto'"
[debug]="false"
(play)="onPlay()"
(pause)="onPause()"
(end)="onEnd()"
(error)="onError($event)">
`
})
export class AppComponent {
cinematicSpec: CinematicSpec = {
// Your specification here
};
onPlay() { console.log('Playing'); }
onPause() { console.log('Paused'); }
onEnd() { console.log('Ended'); }
onError(error: Error) { console.error('Error:', error); }
}
#### Angular Inputs/Outputs
Inputs:
- spec: CinematicSpec - JSON specification (required)autoplay: boolean
- - Auto-start playback (default: false)quality: QualityLevel
- - Quality level (default: 'auto')debug: boolean
- - Enable debug mode (default: false)
Outputs:
- play: EventEmitter - Playback startedpause: EventEmitter
- - Playback pausedstop: EventEmitter
- - Playback stoppedend: EventEmitter
- - Playback completederror: EventEmitter
- - Error occurred
`typescript
interface CinematicSpec {
schemaVersion: string; // Currently '1.0.0'
engine: EngineConfig; // Engine configuration
events: CinematicEvent[]; // High-level sequences
scenes: CinematicScene[]; // Individual scenes
assets?: AssetDefinition[]; // Optional assets
}
interface EngineConfig {
targetFps?: number; // Target frame rate (default: 60)
quality?: QualityLevel; // Quality level (default: 'auto')
debug?: boolean; // Debug mode (default: false)
autoplay?: boolean; // Auto-start (default: false)
}
`
`typescript
interface CinematicEvent {
id: string; // Unique identifier
name: string; // Display name
scenes: string[]; // Scene IDs in order
transitions?: TransitionSpec[]; // Optional transitions
}
interface CinematicScene {
id: string; // Unique identifier
name: string; // Display name
duration: number; // Duration in milliseconds
layers: LayerSpec[]; // Visual layers
audio?: AudioTrackSpec[]; // Optional audio tracks
}
`
`typescript
interface LayerSpec {
id: string; // Unique identifier
type: LayerType; // Layer type (see Layer Types)
zIndex: number; // Rendering order
config: LayerConfig; // Layer-specific configuration
animations?: AnimationTrackSpec[]; // Optional animations
}
interface AnimationTrackSpec {
property: string; // Property to animate
from: any; // Starting value
to: any; // Ending value
startMs: number; // Start time in milliseconds
endMs: number; // End time in milliseconds
easing?: EasingType; // Easing function (default: 'ease')
loop?: boolean; // Loop animation (default: false)
yoyo?: boolean; // Reverse on loop (default: false)
}
`
#### Gradient Layer
`json`
{
"type": "gradient",
"config": {
"colors": ["#ff0000", "#0000ff"],
"direction": "to bottom",
"opacity": 1
}
}
#### Image Layer
`json`
{
"type": "image",
"config": {
"src": "path/to/image.jpg",
"width": "100%",
"height": "100%",
"objectFit": "cover"
}
}
#### Text Block Layer
`json`
{
"type": "textBlock",
"config": {
"text": "Hello World",
"fontSize": "24px",
"color": "#ffffff",
"textAlign": "center"
}
}
#### Vignette Layer
`json`
{
"type": "vignette",
"config": {
"intensity": 0.5,
"color": "#000000",
"radius": "50%"
}
}
#### Light Layer (NEW)
`json`
{
"type": "light",
"config": {
"mode": "spot",
"position": { "x": 50, "y": 50 },
"radius": 200,
"intensity": 0.8,
"color": "#ffffff",
"angle": 45,
"direction": 90,
"blendMode": "screen"
}
}
#### Fog Layer (NEW)
`json`
{
"type": "fog",
"config": {
"density": 0.5,
"color": "#cccccc",
"speed": 1,
"direction": "horizontal",
"opacity": 0.7
}
}
#### Glow Effect Layer (NEW)
`json`
{
"type": "glowEffect",
"config": {
"position": { "x": 50, "y": 50 },
"radius": 100,
"intensity": 0.8,
"color": "#ffff00",
"blur": 20
}
}
#### Shape Layer (NEW) š·
`json`
{
"type": "shape",
"config": {
"shapeType": "circle",
"radius": 50,
"x": "50%",
"y": "50%",
"fillColor": "#ff6b6b",
"strokeColor": "#ffffff",
"strokeWidth": 2,
"opacity": 0.8,
"rotation": 0,
"scaleX": 1,
"scaleY": 1
}
}
Supported Shape Types:
- rectangle - Configurable width and heightsquare
- - Configurable sizecircle
- - Configurable radiusellipse
- - Configurable radiusX and radiusYtriangle
- - Custom verticestrapezoid
- - Configurable top/bottom widths and heightpolygon
- - Configurable sides (ā„3) and radiusstar
- - Configurable points (ā„3), inner/outer radius
All shape properties are fully animatable!
#### Particles Layer
`json`
{
"type": "particles",
"config": {
"count": 100,
"size": 2,
"color": "#ffffff",
"speed": 1,
"direction": "up"
}
}
#### Starfield Layer
`json`
{
"type": "starfield",
"config": {
"density": 0.5,
"twinkle": true,
"colors": ["#ffffff", "#ffffcc"]
}
}
#### Parallax Group Layer (NEW)
`json`
{
"type": "parallaxGroup",
"config": {
"layers": ["layer1", "layer2", "layer3"],
"depth": 0.5,
"scrollSpeed": 1.2
}
}
Supported easing functions:
- Linear: linearease
- Standard: , ease-in, ease-out, ease-in-outease-in-sine
- Sine: , ease-out-sine, ease-in-out-sineease-in-quad
- Quadratic: , ease-out-quad, ease-in-out-quadease-in-cubic
- Cubic: , ease-out-cubic, ease-in-out-cubicease-in-quart
- Quartic: , ease-out-quart, ease-in-out-quartease-in-quint
- Quintic: , ease-out-quint, ease-in-out-quintease-in-expo
- Exponential: , ease-out-expo, ease-in-out-expoease-in-circ
- Circular: , ease-out-circ, ease-in-out-circease-in-back
- Back: , ease-out-back, ease-in-out-backease-in-elastic
- Elastic: , ease-out-elastic, ease-in-out-elasticease-in-bounce
- Bounce: , ease-out-bounce, ease-in-out-bouncecubic-bezier(x1,y1,x2,y2)
- Custom:
`json`
{
"animations": [
{
"property": "opacity",
"from": 0,
"to": 1,
"startMs": 0,
"endMs": 1000,
"easing": "ease-in-out"
},
{
"property": "transform.scale",
"from": 0.5,
"to": 1.2,
"startMs": 500,
"endMs": 1500,
"easing": "ease-out-back"
},
{
"property": "config.color",
"from": "#ff0000",
"to": "#0000ff",
"startMs": 0,
"endMs": 2000,
"easing": "linear"
},
{
"property": "transform.rotation",
"from": 0,
"to": 360,
"startMs": 0,
"endMs": 2000,
"easing": "linear",
"loop": true,
"yoyo": false
}
]
}
`json`
{
"keyframes": [
{
"property": "opacity",
"keyframes": [
{ "time": 0, "value": 0, "easing": "ease-in" },
{ "time": 500, "value": 1, "easing": "ease-out" },
{ "time": 1500, "value": 1, "easing": "ease-in" },
{ "time": 2000, "value": 0 }
]
}
]
}
`json`
{
"transitions": [
{
"fromScene": "scene1",
"toScene": "scene2",
"type": "crossfade",
"duration": 1000,
"easing": "ease-in-out"
},
{
"fromScene": "scene2",
"toScene": "scene3",
"type": "slide",
"duration": 800,
"easing": "ease-out",
"direction": "left"
},
{
"fromScene": "scene3",
"toScene": "scene4",
"type": "zoom",
"duration": 1200,
"easing": "ease-in-out",
"direction": "in"
}
]
}
`typescript
interface AudioTrackSpec {
id: string; // Unique identifier
type: AudioTrackType; // Track type
src: string; // Audio file path/URL
startMs: number; // Start time in milliseconds
endMs?: number; // End time (optional)
volume?: number; // Volume 0-1 (default: 1)
fadeIn?: number; // Fade in duration (default: 0)
fadeOut?: number; // Fade out duration (default: 0)
loop?: boolean; // Loop track (default: false)
}
type AudioTrackType = 'voiceover' | 'ambience' | 'transition' | 'music' | 'sfx';
`
`json`
{
"audio": [
{
"id": "background-music",
"type": "ambience",
"src": "audio/ambient.mp3",
"startMs": 0,
"volume": 0.6,
"fadeIn": 1000,
"loop": true
},
{
"id": "narrator",
"type": "voiceover",
"src": "audio/narration.mp3",
"startMs": 2000,
"volume": 1.0,
"fadeIn": 500,
"fadeOut": 500
}
]
}
The library automatically adapts performance based on device capabilities:
- Ultra: Maximum quality, all effects enabled
- High: High quality with some optimizations
- Medium: Balanced quality and performance
- Low: Optimized for performance, reduced effects
- Auto: Automatically adjusts based on device performance
1. Layer Count: Keep layers under 20 per scene for optimal performance
2. Animation Complexity: Prefer transform and opacity animations over layout changes
3. Asset Optimization: Use compressed images and audio files
4. Canvas Particles: Limit particle count based on target devices
5. Audio Tracks: Use compressed audio formats (MP3, AAC)
`typescript`
// The library automatically detects and optimizes for:
// - Device pixel ratio for sharp rendering
// - Available memory for asset caching
// - CPU capabilities for animation complexity
// - Network conditions for asset loading
// - Battery status for power-efficient rendering
The CLI is included with the package:
`bash`
npx cinematic-cli --help
#### Validate Specification
`bashBasic validation
npx cinematic-cli validate --file spec.json
#### Generate Preview
`bash
Generate HTML preview
npx cinematic-cli preview --file spec.jsonSave to specific file
npx cinematic-cli preview --file spec.json --output preview.html
`TypeScript Support
$3
`typescript
import type {
CinematicRenderer2D,
CinematicSpec,
CinematicEvent,
CinematicScene,
LayerSpec,
AnimationTrackSpec,
AudioTrackSpec,
QualityLevel,
LayerType,
EasingType
} from 'cinematic-renderer2d';
`$3
`typescript
import type { ICinematicLayer, LayerMountContext, FrameContext } from 'cinematic-renderer2d';class CustomLayer implements ICinematicLayer {
id: string;
type: string;
zIndex: number;
constructor(config: any) {
this.id = config.id;
this.type = config.type;
this.zIndex = config.zIndex;
}
mount(ctx: LayerMountContext): void {
// Initialize layer
}
update(ctx: FrameContext): void {
// Update layer per frame
}
destroy(): void {
// Cleanup resources
}
}
`Examples
$3
`json
{
"schemaVersion": "1.0.0",
"engine": {
"targetFps": 60,
"quality": "auto",
"debug": false
},
"events": [
{
"id": "intro",
"name": "Introduction Sequence",
"scenes": ["fade-in", "title-reveal", "fade-out"]
}
],
"scenes": [
{
"id": "fade-in",
"name": "Fade In",
"duration": 2000,
"layers": [
{
"id": "background",
"type": "gradient",
"zIndex": 1,
"config": {
"colors": ["#000000", "#1a1a1a"],
"direction": "to bottom"
},
"animations": [
{
"property": "opacity",
"from": 0,
"to": 1,
"startMs": 0,
"endMs": 2000,
"easing": "ease-in-out"
}
]
}
]
},
{
"id": "title-reveal",
"name": "Title Reveal",
"duration": 3000,
"layers": [
{
"id": "title",
"type": "textBlock",
"zIndex": 2,
"config": {
"text": "Welcome to CinematicRenderer2D",
"fontSize": "48px",
"color": "#ffffff",
"textAlign": "center"
},
"animations": [
{
"property": "transform.scale",
"from": 0.5,
"to": 1,
"startMs": 0,
"endMs": 1000,
"easing": "ease-out-back"
},
{
"property": "opacity",
"from": 0,
"to": 1,
"startMs": 0,
"endMs": 800,
"easing": "ease-out"
}
]
}
],
"audio": [
{
"id": "title-sound",
"type": "sfx",
"src": "audio/title-reveal.mp3",
"startMs": 500,
"volume": 0.8,
"fadeIn": 200
}
]
}
]
}
`Development
$3
`
src/
āāā core/ # Core engine and interfaces
ā āāā CinematicRenderer2D.ts
ā āāā LayerRegistry.ts
ā āāā Scheduler.ts
ā āāā interfaces/
āāā types/ # TypeScript definitions
ā āāā CinematicSpec.ts
ā āāā CompiledSpec.ts
ā āāā AssetTypes.ts
āāā parsing/ # JSON specification parsing
ā āāā SpecParser.ts
āāā animation/ # Animation system
ā āāā AnimationCompiler.ts
āāā rendering/ # Rendering backends
ā āāā RenderBackend.ts
ā āāā dom/
ā āāā canvas2d/
āāā assets/ # Asset management
ā āāā AssetManager.ts
āāā audio/ # Audio system
ā āāā AudioSystem.ts
āāā performance/ # Performance monitoring
ā āāā QualitySystem.ts
āāā debug/ # Debug tools
ā āāā DebugOverlay.ts
āāā cli/ # CLI tools
ā āāā index.ts
āāā adapters/ # Framework adapters
āāā react/
āāā angular/
`$3
`bash
npm run dev # Start development playground
npm run build # Build library for production
npm run build:check # Build and validate output
npm run test # Run test suite
npm run test:ui # Run tests with UI
npm run test:coverage # Run tests with coverage
npm run lint # Lint code
npm run lint:fix # Fix linting issues
npm run typecheck # Type checking
npm run preview # Preview built playground
npm run changeset # Create changeset for release
npm run version # Update version with changesets
npm run release # Publish to NPM
`$3
The project uses comprehensive testing with:
- Unit Tests: Specific functionality testing
- Property-Based Tests: Universal behavior validation
- Integration Tests: End-to-end workflow testing
- Build Tests: Distribution package validation
`bash
Run all tests
npm testRun specific test file
npm test -- src/core/Scheduler.test.tsRun tests in watch mode
npm test -- --watchRun with coverage
npm run test:coverage
`Browser Support
- Modern Browsers: Chrome 80+, Firefox 75+, Safari 13+, Edge 80+
- Node.js: 16.0.0+ (for CLI tools)
- ES Modules: Full ESM support with CJS fallback
- TypeScript: 4.5+ for full type support
Performance Benchmarks
Typical performance on modern devices:
- Desktop: 120fps with 50+ layers
- Mobile: 60fps with 20+ layers
- Bundle Size: ~83KB minified + gzipped
- Memory Usage: <50MB for complex scenes
- Startup Time: <100ms initialization
Troubleshooting
$3
Build Errors
`bash
Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
`Type Errors
`bash
Ensure TypeScript is up to date
npm install typescript@latest --save-dev
npm run typecheck
`Performance Issues
- Reduce layer count per scene
- Use 'low' or 'medium' quality settings
- Optimize asset file sizes
- Enable debug mode to monitor FPS
$3
Enable debug mode to monitor performance:
`typescript
const renderer = new CinematicRenderer2D({
container: element,
spec: {
// ... your spec
engine: { debug: true }
}
});
`Debug overlay shows:
- Current FPS and frame time
- Active layers and their status
- Memory usage statistics
- Quality level and adaptations
Contributing
This project follows semantic versioning and uses changesets for release management.
$3
`bash
git clone https://github.com/rvshekhar10/cinematicRenderer2D.git
cd cinematic-renderer2d
npm install
npm run dev
`$3
`bash
Make your changes
npm run changeset # Document your changes
npm run test # Ensure tests pass
npm run build # Verify build works
``See our publishing guides:
- š Quick Publish Guide - Fast 5-minute guide
- š Complete Publishing Guide - Detailed instructions
- ā
Publishing Checklist - Step-by-step checklist
MIT License - see LICENSE file for details.
- š Documentation: This README and TypeScript definitions
- š Issues: GitHub Issues
- š¬ Discussions: GitHub Discussions
- š§ Email: support@cinematicrenderer2d.com