liveposter
v0.0.15
Published
A JSON-driven JavaScript animation library for creating sophisticated image transitions and effects
Downloads
1,322
Maintainers
Readme
🎬 Liveposter
A JSON-driven JavaScript animation library for creating sophisticated image transitions and effects. Framework-agnostic, lightweight, and easy to use.
Features
- 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
Quick Start
Try the Demo
Default demo (all animation modes):
npx liveposter
# or
npx liveposter demoPoster viewer (fullscreen vertical viewer with swipe/arrow navigation):
npx liveposter poster-viewer/index.htmlServe a single poster spec:
npx liveposter path/to/your-poster.jsonServe a poster list (multiple posters in fullscreen layout):
npx liveposter path/to/poster-list.jsonServe custom HTML file:
npx liveposter path/to/your/file.htmlDevelopment mode with hot-reload:
# Watch default demo with auto-reload
npx liveposter dev
# Watch a single poster spec with auto-reload
npx liveposter dev path/to/your-poster.json
# Watch a poster list with auto-reload
npx liveposter dev path/to/poster-list.jsonLaunch in fullscreen kiosk mode:
# Default demo in kiosk mode
npx liveposter kiosk
# Specific poster in kiosk mode
npx liveposter kiosk path/to/your-poster.json
# Poster list in kiosk mode
npx liveposter kiosk path/to/poster-list.jsonAugmented Reality (AR) commands:
# Generate AR target files (.mind) from your images
# Automatically processes all JPG, PNG, GIF images in your specs
npx liveposter ar-compile-targets poster.json
# Development server for AR experiences (port 3100)
npx liveposter ar-dev poster.json
# Build static AR site for deployment
npx liveposter ar-build poster.json --output dist-arThis will start a demo server at http://localhost:3000 (AR server runs on port 3100).
Port Configuration
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)
PORT=8080 npx liveposter dev
PORT=8080 npx liveposter startOption 2: .env file in current directory
# Create .env in your project directory
echo "PORT=8080" > .env
npx liveposter dev my-poster.jsonOption 3: .env file in package directory
# Create .env in liveposter package directory
echo "PORT=8080" > packages/demo-server/.env
npm run devThe server checks these locations in order and uses the first PORT value it finds. If none are set, it defaults to port 3000.
Development Workflow
When developing a poster, use the development mode with automatic hot-reload:
Using npx (recommended):
# Watch any poster spec with automatic browser reload
npx liveposter dev path/to/your-poster.json
# Watch a poster list
npx liveposter dev path/to/poster-list.json
# Watch default demo
npx liveposter devThe 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:
# 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" }
]
}
EOF
# 2. Run dev mode with hot-reload
npx liveposter dev my-poster.json
# 3. Open http://localhost:3000
# 4. Edit my-poster.json - server auto-restarts and browser automatically refreshes!From repository (for library development):
# Watch a specific poster spec
cd packages/demo-server
npm run dev -- path/to/your-poster.json
# Watch a poster list
npm run dev -- path/to/poster-list.jsonPoster List Format
Create a poster-list.json file to display multiple posters in a fullscreen layout:
[
"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)
Installation
npm install @liveposter/coreBasic Usage
<!DOCTYPE html>
<html>
<head>
<link
rel="stylesheet"
href="node_modules/@liveposter/core/styles/animator.css"
/>
</head>
<body>
<div id="slideshow"></div>
<script type="module">
import ImageAnimator from "@liveposter/core";
const config = {
container: "#slideshow",
mode: "diaporama",
loop: true,
timing: {
duration: 2000,
transition: 500,
},
effects: {
type: "fade",
easing: "ease-in-out",
},
images: [
{ src: "image1.jpg", alt: "Image 1" },
{ src: "image2.jpg", alt: "Image 2" },
{ src: "image3.jpg", alt: "Image 3" },
],
};
const animator = new ImageAnimator(config);
await animator.init();
</script>
</body>
</html>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
Install Dependencies
npm installConfiguration
Configure the demo server (optional):
cp packages/demo-server/.env.example packages/demo-server/.env
# Edit .env to change PORT (default: 3000)Build the Library
npm run buildRun Demo Server
# Development mode (hot reload)
npm run dev
# Production mode
npm run startKiosk Mode Deployment
For digital signage or fullscreen display installations, use the cross-platform kiosk launcher:
Using npx (recommended for production):
# Default demo in kiosk mode
npx liveposter kiosk
# Serve a specific poster in kiosk mode
npx liveposter kiosk path/to/your-poster.json
# Serve a poster list in kiosk mode
npx liveposter kiosk path/to/poster-list.jsonFrom repository (for development):
# Default demo
npm run kiosk
# With custom poster (edit launch-kiosk.js to pass arguments)
node launch-kiosk.js path/to/your-poster.jsonThis will:
- Automatically kill any process using port 3000
- Start the server with your poster(s)
- Wait for it to be ready
- Launch Chrome in fullscreen kiosk mode
- Works on all platforms (Windows, macOS, Linux) without modification
Manual launch by platform:
macOS:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --kiosk --app=http://localhost:3000Windows:
chrome --kiosk --app=http://localhost:3000Linux:
chromium-browser --kiosk --app=http://localhost:3000
# or
google-chrome --kiosk --app=http://localhost:3000Additional kiosk mode options:
# Disable gestures and prevent exiting (Linux/macOS)
chromium-browser --kiosk --app=http://localhost:3000 \
--disable-pinch \
--overscroll-history-navigation=0 \
--disable-features=TranslateUIAuto-start on boot (Linux/Raspberry Pi):
Create /etc/systemd/system/liveposter.service:
[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.targetEnable and start:
sudo systemctl enable liveposter
sudo systemctl start liveposterTesting the CLI Locally
To test the npx liveposter command before publishing, use npm link:
1. Link the package globally:
cd packages/demo-server
npm link2. Test the CLI commands:
# 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.json3. Unlink when done:
npm unlink -g @liveposter/demo-serverAlternative: Test scripts without npm link
From the repository root:
# 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 list
# Test 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 listFrom demo-server package:
cd packages/demo-server
# Test 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-htmlSee DEVELOPMENT.md for detailed development workflow.
Workspace Structure
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
ImageAnimator
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();Loading from External JSON
const animator = await ImageAnimator.loadFromFile("config.json", "#container");JSON Configuration Schema
See REFERENCE.md for the complete API reference.
Basic structure:
{
"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
Timing
"timing": {
"duration": 3000, // Display duration (ms)
"transition": 500 // Transition duration (ms)
}Per-image timing overrides:
"images": [
{
"src": "image1.jpg",
"timing": {
"duration": 5000,
"transition": 1000
}
}
]Effects
Mode-specific effect parameters:
// 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"
}Easing Functions
linear: Constant speedease-in: Acceleratesease-out: Deceleratesease-in-out: Smooth acceleration and deceleration
Overlays
"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:
"input": {
"type": "mouseX",
"mapping": "eased" // or "direct"
}Browser Support
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
- Mobile: iOS 14+, Android 90+
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
Author
Your Name / Organization
Built with ❤️ using modern JavaScript
