A JSON-driven JavaScript animation library for creating sophisticated image transitions and effects
A JSON-driven JavaScript animation library for creating sophisticated image transitions and effects. Framework-agnostic, lightweight, and easy to use.
- JSON-driven: Define animations declaratively via JSON specifications
- Framework-agnostic: Works with vanilla JS, React, Vue, or any other framework
- Multiple animation modes: Slideshow, fade, pan, lenticular, parallax, zoom
- Augmented Reality (AR): WebXR-powered AR experiences with automatic target generation
- Input-driven animations: Respond to mouse, tilt, scroll inputs
- Extensible: Easy to add custom modes and effects
- Zero dependencies: Core library has no external dependencies
- ES6 modules: Modern JavaScript with tree-shaking support
Default demo (all animation modes):
``bash`
npx liveposteror
npx liveposter demo
Poster viewer (fullscreen vertical viewer with swipe/arrow navigation):
`bash`
npx liveposter poster-viewer/index.html
Serve a single poster spec:
`bash`
npx liveposter path/to/your-poster.json
Serve a poster list (multiple posters in fullscreen layout):
`bash`
npx liveposter path/to/poster-list.json
Serve custom HTML file:
`bash`
npx liveposter path/to/your/file.html
Development mode with hot-reload:
`bashWatch default demo with auto-reload
npx liveposter dev
Launch in fullscreen kiosk mode:
`bash
Default demo in kiosk mode
npx liveposter kioskSpecific poster in kiosk mode
npx liveposter kiosk path/to/your-poster.jsonPoster list in kiosk mode
npx liveposter kiosk path/to/poster-list.json
`Augmented Reality (AR) commands:
`bash
Generate AR target files (.mind) from your images
Automatically processes all JPG, PNG, GIF images in your specs
npx liveposter ar-compile-targets poster.jsonDevelopment server for AR experiences (port 3100)
npx liveposter ar-dev poster.jsonBuild static AR site for deployment
npx liveposter ar-build poster.json --output dist-ar
`This will start a demo server at http://localhost:3000 (AR server runs on port 3100).
$3
The demo server uses port 3000 by default. You can customize the port in three ways (in priority order):
Option 1: Environment variable (highest priority)
`bash
PORT=8080 npx liveposter dev
PORT=8080 npx liveposter start
`Option 2: .env file in current directory
`bash
Create .env in your project directory
echo "PORT=8080" > .env
npx liveposter dev my-poster.json
`Option 3: .env file in package directory
`bash
Create .env in liveposter package directory
echo "PORT=8080" > packages/demo-server/.env
npm run dev
`The server checks these locations in order and uses the first PORT value it finds. If none are set, it defaults to port 3000.
$3
When developing a poster, use the development mode with automatic hot-reload:
Using npx (recommended):
`bash
Watch any poster spec with automatic browser reload
npx liveposter dev path/to/your-poster.jsonWatch a poster list
npx liveposter dev path/to/poster-list.jsonWatch default demo
npx liveposter dev
`The dev mode uses
nodemon to automatically restart the server and reload the browser when you modify:- Poster spec JSON files
- Image assets
- HTML/CSS files
- Any files in the spec's directory
Example workflow:
`bash
1. Create your poster spec anywhere
mkdir ~/my-posters
cd ~/my-posters
cat > my-poster.json << EOF
{
"container": "#poster",
"mode": "diaporama",
"timing": { "duration": 2000, "transition": 500 },
"effects": { "type": "fade", "easing": "ease-in-out" },
"images": [
{ "src": "https://picsum.photos/1080/1920?random=1", "alt": "Image 1" },
{ "src": "https://picsum.photos/1080/1920?random=2", "alt": "Image 2" }
]
}
EOF2. Run dev mode with hot-reload
npx liveposter dev my-poster.json3. Open http://localhost:3000
4. Edit my-poster.json - server auto-restarts and browser automatically refreshes!
`From repository (for library development):
`bash
Watch a specific poster spec
cd packages/demo-server
npm run dev -- path/to/your-poster.jsonWatch a poster list
npm run dev -- path/to/poster-list.json
`$3
Create a
poster-list.json file to display multiple posters in a fullscreen layout:`json
[
"specs/poster1.json",
"specs/poster2.json",
{
"spec": "specs/poster3.json",
"title": "Custom Title",
"description": "Optional description"
}
]
`Paths are resolved relative to the poster list location. The server will:
- Load each spec file
- Resolve image paths relative to each spec's location
- Generate a fullscreen viewer with keyboard navigation (ā/ā arrows)
$3
`bash
npm install @liveposter/core
`$3
`html
rel="stylesheet"
href="node_modules/@liveposter/core/styles/animator.css"
/>
`Available Animation Modes
- hardcut-slideshow: Instant cuts between images
- diaporama: Smooth crossfade transitions
- pan-slideshow: Continuous panning across wide images
- lenticular: Input-driven image switching (simulates lenticular printing)
- parallax-layers: Multiple layers with depth effect
- zoom-slideshow: Ken Burns style zoom effect
Project Structure
This is a monorepo managed with Turborepo containing:
- @liveposter/core: Main animation library (publishable)
- @liveposter/demo-server: Demo server with CLI (
npx liveposter)
- @liveposter/demo-projects: Demo projects (poster-viewer, etc.)Development
$3
`bash
npm install
`$3
Configure the demo server (optional):
`bash
cp packages/demo-server/.env.example packages/demo-server/.env
Edit .env to change PORT (default: 3000)
`$3
`bash
npm run build
`$3
`bash
Development mode (hot reload)
npm run devProduction mode
npm run start
`$3
For digital signage or fullscreen display installations, use the cross-platform kiosk launcher:
Using npx (recommended for production):
`bash
Default demo in kiosk mode
npx liveposter kioskServe a specific poster in kiosk mode
npx liveposter kiosk path/to/your-poster.jsonServe a poster list in kiosk mode
npx liveposter kiosk path/to/poster-list.json
`From repository (for development):
`bash
Default demo
npm run kioskWith custom poster (edit launch-kiosk.js to pass arguments)
node launch-kiosk.js path/to/your-poster.json
`This will:
1. Automatically kill any process using port 3000
2. Start the server with your poster(s)
3. Wait for it to be ready
4. Launch Chrome in fullscreen kiosk mode
5. Works on all platforms (Windows, macOS, Linux) without modification
Manual launch by platform:
macOS:
`bash
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --kiosk --app=http://localhost:3000
`Windows:
`cmd
chrome --kiosk --app=http://localhost:3000
`Linux:
`bash
chromium-browser --kiosk --app=http://localhost:3000
or
google-chrome --kiosk --app=http://localhost:3000
`Additional kiosk mode options:
`bash
Disable gestures and prevent exiting (Linux/macOS)
chromium-browser --kiosk --app=http://localhost:3000 \
--disable-pinch \
--overscroll-history-navigation=0 \
--disable-features=TranslateUI
`Auto-start on boot (Linux/Raspberry Pi):
Create
/etc/systemd/system/liveposter.service:`ini
[Unit]
Description=Liveposter Kiosk
After=network.target[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/liveposter
Environment=DISPLAY=:0
ExecStart=/usr/bin/npm run kiosk
Restart=always
[Install]
WantedBy=graphical.target
`Enable and start:
`bash
sudo systemctl enable liveposter
sudo systemctl start liveposter
`$3
To test the
npx liveposter command before publishing, use npm link:1. Link the package globally:
`bash
cd packages/demo-server
npm link
`2. Test the CLI commands:
`bash
From anywhere on your system
liveposter # Default demo
liveposter demo # Explicit demo command
liveposter poster-viewer/index.html
liveposter path/to/poster.json
liveposter path/to/poster-list.json
`3. Unlink when done:
`bash
npm unlink -g @liveposter/demo-server
`Alternative: Test scripts without npm link
From the repository root:
`bash
Test server directly (without CLI wrapper)
npm run test:demo # Default demo
npm run test:poster-viewer # Poster viewer
npm run test:single-poster # Single poster spec
npm run test:poster-list # Poster listTest CLI wrapper (simulates npx liveposter)
npm run test:cli # Default demo
npm run test:cli:demo # Explicit demo
npm run test:cli:poster-viewer # Poster viewer
npm run test:cli:single # Single spec
npm run test:cli:list # Poster list
`From demo-server package:
`bash
cd packages/demo-serverTest server directly
npm run test:demo
npm run test:poster-viewer
npm run test:single-poster
npm run test:poster-list
npm run test:custom-html
`See DEVELOPMENT.md for detailed development workflow.
$3
`
liveposter/
āāā turbo.json # Turborepo configuration
āāā packages/
ā āāā core/ # @liveposter/core - Main library
ā ā āāā src/ # Source files (ES6 modules)
ā ā āāā styles/ # Base CSS styles
ā ā āāā dist/ # Build output (CJS, ESM, UMD)
ā ā āāā .npmignore # NPM publish configuration
ā ā
ā āāā demo-server/ # Demo server & CLI
ā ā āāā bin/ # CLI entry point (npx liveposter)
ā ā āāā server.js # Express server
ā ā āāā public/ # Default demo files & specs
ā ā
ā āāā demo-projects/ # Demo projects
ā āāā poster-viewer/ # Fullscreen poster viewer
ā ā āāā index.html
ā ā āāā styles.css
ā ā āāā spec.json
ā āāā public/
ā āāā images/ # Placeholder poster images (SVG)
`API
$3
`javascript
const animator = new ImageAnimator(config);// Initialize
await animator.init();
// Control
animator.pause();
animator.resume();
animator.goToSlide(index);
animator.next();
animator.previous();
// Events
animator.on("slideChange", (data) => {
console.log("Current slide:", data.currentIndex);
});
// Cleanup
animator.destroy();
`$3
`javascript
const animator = await ImageAnimator.loadFromFile("config.json", "#container");
`JSON Configuration Schema
See REFERENCE.md for the complete API reference.
Basic structure:
`json
{
"mode": "diaporama",
"loop": true,
"timing": {
"duration": 2000,
"transition": 500
},
"effects": {
"type": "fade",
"easing": "ease-in-out"
},
"images": [{ "src": "image1.jpg" }]
}
`Animation Modes
| Mode | Description | Use Case |
| ------------------- | --------------------- | ------------------------ |
|
hardcut-slideshow | Instant transitions | Fast product showcases |
| diaporama | Crossfade transitions | Classic slideshows |
| pan-slideshow | Continuous panning | Panoramic images |
| zoom-slideshow | Ken Burns zoom effect | Cinematic presentations |
| lenticular | Mouse/tilt-driven | Interactive 3D effect |
| parallax-layers | Multi-layer depth | Interactive depth scenes |Overlay Types
Overlays add visual elements on top of images:
- gridline: Grid overlay (rule of thirds)
- vignette: Edge darkening
- image: Static image overlay
- text: Text overlay
- gradient: Color gradient overlay
Configuration Options
$3
`json
"timing": {
"duration": 3000, // Display duration (ms)
"transition": 500 // Transition duration (ms)
}
`Per-image timing overrides:
`json
"images": [
{
"src": "image1.jpg",
"timing": {
"duration": 5000,
"transition": 1000
}
}
]
`$3
Mode-specific effect parameters:
`json
// Fade
"effects": { "type": "fade", "easing": "ease-in-out" }// Pan
"effects": {
"type": "pan",
"direction": "horizontal",
"easing": "linear"
}
// Zoom
"effects": {
"type": "zoom",
"direction": "in",
"scale": 1.2,
"easing": "ease-out"
}
`$3
-
linear: Constant speed
- ease-in: Accelerates
- ease-out: Decelerates
- ease-in-out: Smooth acceleration and deceleration$3
`json
"overlays": [
{
"type": "gridline",
"rows": 3,
"columns": 3,
"color": "rgba(255, 255, 255, 0.3)",
"lineWidth": 2
},
{
"type": "vignette",
"color": "rgba(0, 0, 0, 0.3)",
"intensity": 0.5
}
]
`Input Types
For interactive modes (lenticular, parallax):
- mouseX / mouseY: Mouse position within container
- tiltX / tiltY: Device orientation (mobile)
- scroll: Scroll position
Input mapping:
`json
"input": {
"type": "mouseX",
"mapping": "eased" // or "direct"
}
``- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
- Mobile: iOS 14+, Android 90+
Contributions are welcome! Please feel free to submit a Pull Request.
MIT
Your Name / Organization
---
Built with ā¤ļø using modern JavaScript