Simple web components that turn static pages into immersive, interactive media experiences. Drop a single HTML tag — get a full-featured 360° spinner, panorama viewer, image comparison slider, or video player.
- One tag — one widget. Just
<ims-viewer src-data="data.json">and you're done. - Universal. Works in any stack: vanilla HTML, React, Vue, Angular, Svelte — anything that renders DOM.
- Smart loading. Adaptive resolution based on viewport & DPI, lazy loading via IntersectionObserver, on-demand dependency imports.
- Hypermedia navigation. Link widgets together with interactive hotspots — let users explore 3D products, then dive into 360°, then watch a video, all in one seamless flow.
- Themeable. Full CSS custom properties for colors, sizing, and layout. No CSS framework lock-in.
- Lightweight. Built on Symbiote.js — each widget loads only what it needs.
| Widget | Description | Docs |
|---|---|---|
| ims-spinner | 360° product viewer with frame-by-frame rotation, autoplay, and drag interaction | docs |
| ims-gallery | Touch-friendly image gallery with navigation, looping, and fullscreen | docs |
| ims-diff | Before/after image comparison with a draggable slider | docs |
| ims-pano | 360° panorama with inertia-based pan, zoom, and auto-rotation (Three.js) | docs |
| ims-model | 3D model viewer for GLTF/GLB with orbit controls and auto-rotation (Three.js) | docs |
| ims-video | Video player with HLS adaptive streaming, subtitles, and quality switching | docs |
| ims-audio | Audio player with real-time waveform visualization (Web Audio API) | docs |
| ims-map | Interactive map with markers | docs |
| ims-hotspots | Interactive overlay spots with state-bound positioning and keyframe animation | docs |
| ims-viewer | Universal loader — auto-imports any widget by type with version control, manages hotspot navigation and history | docs |
1. Set up dependencies — add an importmap or install via npm (only Symbiote.js is required; Three.js and hls.js are needed only for the widgets that use them)
2. Load the viewer (it pulls widget code on demand):
<script type="module" src="https://cdn.jsdelivr.net/npm/immersive-media-spots@<VERSION>/viewer/+esm"></script>3. Use it:
<ims-viewer src-data="./product.json"></ims-viewer>That's it. The viewer reads imsType from product.json and dynamically imports the right widget.
Every data JSON can include a version field that locks the widget import to an exact library release. This guarantees that previously published pages keep working even after new IMS versions are released with breaking changes.
The viewer resolves the CDN URL as immersive-media-spots@1.4.2/spinner/+esm. You can also override the version via the HTML attribute:
<ims-viewer src-data="./product.json" version="1.4.2"></ims-viewer>If neither is set, latest is used. For production deployments, always pin the version in your data files.
Skip the viewer and load a specific widget directly:
<script type="module" src="https://cdn.jsdelivr.net/npm/immersive-media-spots@<VERSION>/spinner/+esm"></script>
<ims-spinner src-data="./data.json" autoplay="true"></ims-spinner>npm install immersive-media-spotsCombine ims-viewer with ims-hotspots to create connected experiences:
<ims-viewer
src-data="./exterior-spin.json"
url-template="./{{imsType}}/index.js"
hotspots="./exterior-hotspots.json">
</ims-viewer>Hotspots link widgets together — click a spot on a 360° product to open a detail gallery, then jump to a panoramic interior, all with animated back navigation. → Hotspots docs
All widgets share a base architecture that provides:
- Adaptive loading — automatically selects the best resolution variant for the viewport and DPI
- Lazy loading —
lazyattribute defers initialization until the element enters the viewport - Fullscreen — native Fullscreen API with CSS fallback
- Mobile-ready — touch gestures, responsive sizing, pointer event support
- CSS theming — design tokens for toolbar, colors, spacing, and transitions
- Plugin system — extend lifecycle hooks with custom plugins (→ plugins docs)
- Events — standard lifecycle events:
ims-load,ims-ready,ims-error(→ events docs) - Attribute overrides — override any JSON config property via HTML attributes
- All docs
- Dependencies — import maps and CDN setup
- Events — lifecycle events reference
- Fullscreen — fullscreen API and CSS fallback
- Plugins — extending widgets with custom plugins
Contributions are welcome! Please feel free to submit a Pull Request.
MIT © rnd-pro.com