immersive-media-spots 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +30 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
- package/.github/workflows/ci.yml +31 -0
- package/CHANGELOG.md +31 -0
- package/CONTRIBUTING.md +71 -0
- package/LICENSE +21 -0
- package/README.md +115 -0
- package/docs/audio.md +44 -0
- package/docs/dependencies.md +69 -0
- package/docs/diff.md +68 -0
- package/docs/events.md +29 -0
- package/docs/gallery.md +79 -0
- package/docs/hotspots.md +119 -0
- package/docs/model.md +43 -0
- package/docs/pano.md +42 -0
- package/docs/spinner.md +49 -0
- package/docs/video.md +51 -0
- package/docs/viewer.md +95 -0
- package/lib/FullscreenMgr.js +99 -0
- package/lib/ImageReader.js +56 -0
- package/lib/ImsBaseClass.js +324 -0
- package/lib/ResizeController.js +30 -0
- package/lib/createErrorPlaceholder.js +28 -0
- package/lib/dataToImage.js +41 -0
- package/lib/getVariantFit.js +22 -0
- package/lib/globalDataCtx.js +14 -0
- package/lib/imageToData.js +35 -0
- package/lib/ims-button.js +100 -0
- package/lib/ims-preloader.js +37 -0
- package/lib/ims-progress-bar.js +45 -0
- package/lib/ims-range.js +119 -0
- package/lib/imsCtxName.js +2 -0
- package/lib/loadSourceData.js +18 -0
- package/lib/plugins/analytics.js +30 -0
- package/lib/plugins/watermark.js +71 -0
- package/lib/themes/light.css +15 -0
- package/lib/themes/minimal.css +14 -0
- package/lib/tokens.css +35 -0
- package/lib/validateConfig.js +35 -0
- package/lib/version.js +3 -0
- package/package.json +58 -0
- package/playwright.config.js +22 -0
- package/test-results/.last-run.json +4 -0
- package/tests/e2e/audio.spec.js +26 -0
- package/tests/e2e/diff.spec.js +49 -0
- package/tests/e2e/gallery.spec.js +84 -0
- package/tests/e2e/hotspots.spec.js +54 -0
- package/tests/e2e/model.spec.js +23 -0
- package/tests/e2e/pano.spec.js +23 -0
- package/tests/e2e/spinner.spec.js +48 -0
- package/tests/e2e/video.spec.js +26 -0
- package/tests/e2e/viewer.spec.js +108 -0
- package/tests/getVariantFit.test.js +53 -0
- package/tests/validateConfig.test.js +68 -0
- package/types/globals.d.ts +132 -0
- package/video/test-track.vtt +10 -0
- package/wgt/audio/ImsAudioData.js +27 -0
- package/wgt/audio/ims-audio-toolbar.js +53 -0
- package/wgt/audio/index.js +235 -0
- package/wgt/audio/styles.js +34 -0
- package/wgt/audio/template.js +7 -0
- package/wgt/diff/ImsDiffData.js +34 -0
- package/wgt/diff/ims-diff-toolbar.js +68 -0
- package/wgt/diff/index.js +345 -0
- package/wgt/diff/styles.js +59 -0
- package/wgt/diff/template.js +11 -0
- package/wgt/gallery/ImsGalleryData.js +30 -0
- package/wgt/gallery/ims-gallery-toolbar.js +58 -0
- package/wgt/gallery/index.js +273 -0
- package/wgt/gallery/styles.js +45 -0
- package/wgt/gallery/template.js +10 -0
- package/wgt/hotspots/ImsHotspotsData.js +5 -0
- package/wgt/hotspots/index.js +181 -0
- package/wgt/hotspots/styles.js +54 -0
- package/wgt/model/ImsModelData.js +27 -0
- package/wgt/model/ims-model-toolbar.js +37 -0
- package/wgt/model/index.js +220 -0
- package/wgt/model/styles.js +50 -0
- package/wgt/model/template.js +6 -0
- package/wgt/pano/ImsPanoData.js +28 -0
- package/wgt/pano/ims-pano-toolbar.js +37 -0
- package/wgt/pano/index.js +177 -0
- package/wgt/pano/styles.js +51 -0
- package/wgt/pano/template.js +9 -0
- package/wgt/spinner/ImsSpinnerData.js +36 -0
- package/wgt/spinner/ims-spinner-toolbar.js +42 -0
- package/wgt/spinner/index.js +428 -0
- package/wgt/spinner/styles.js +73 -0
- package/wgt/spinner/template.js +11 -0
- package/wgt/video/ImsVideoData.js +24 -0
- package/wgt/video/ims-video-toolbar.js +65 -0
- package/wgt/video/index.js +233 -0
- package/wgt/video/styles.js +60 -0
- package/wgt/video/template.js +22 -0
- package/wgt/viewer/ims-viewer-toolbar.js +38 -0
- package/wgt/viewer/index.js +145 -0
- package/wgt/viewer/styles.js +39 -0
- package/wgt/viewer/template.js +7 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Report a problem with an IMS widget
|
|
4
|
+
labels: bug
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**Widget**: (e.g., ims-spinner, ims-video, ims-pano)
|
|
8
|
+
|
|
9
|
+
**Version**:
|
|
10
|
+
|
|
11
|
+
**Browser**:
|
|
12
|
+
|
|
13
|
+
**Description**:
|
|
14
|
+
A clear description of the bug.
|
|
15
|
+
|
|
16
|
+
**Steps to Reproduce**:
|
|
17
|
+
1.
|
|
18
|
+
2.
|
|
19
|
+
3.
|
|
20
|
+
|
|
21
|
+
**Expected Behavior**:
|
|
22
|
+
|
|
23
|
+
**Actual Behavior**:
|
|
24
|
+
|
|
25
|
+
**Config JSON** (if applicable):
|
|
26
|
+
```json
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Screenshots** (if applicable):
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest a new feature or enhancement
|
|
4
|
+
labels: enhancement
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**Widget**: (e.g., ims-spinner, ims-video, ims-pano, new widget, all)
|
|
8
|
+
|
|
9
|
+
**Description**:
|
|
10
|
+
A clear description of the feature you'd like.
|
|
11
|
+
|
|
12
|
+
**Use Case**:
|
|
13
|
+
Why would this feature be useful?
|
|
14
|
+
|
|
15
|
+
**Proposed Solution** (optional):
|
|
16
|
+
How you'd approach implementing this.
|
|
17
|
+
|
|
18
|
+
**Alternatives Considered** (optional):
|
|
19
|
+
Other approaches you've considered.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
node-version: [20, 22]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: ${{ matrix.node-version }}
|
|
20
|
+
- run: npm install
|
|
21
|
+
- run: npm test
|
|
22
|
+
|
|
23
|
+
typecheck:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- uses: actions/setup-node@v4
|
|
28
|
+
with:
|
|
29
|
+
node-version: 22
|
|
30
|
+
- run: npm install
|
|
31
|
+
- run: npm run types
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Package exports map for clean subpath imports
|
|
12
|
+
- `.npmignore` to reduce published package size
|
|
13
|
+
- CSS custom properties design system for theming
|
|
14
|
+
- TypeScript type definitions for all public APIs and data classes
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- README importmap version mismatch (Symbiote.js 2.x → 3.x)
|
|
18
|
+
|
|
19
|
+
## [0.2.2] - 2024-12-01
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- `ims-video` widget with HLS support, captions, and customizable controls
|
|
23
|
+
- `ims-viewer` universal component with dynamic CDN loading
|
|
24
|
+
- `ims-diff` image comparison widget
|
|
25
|
+
- `ims-gallery` interactive image gallery
|
|
26
|
+
- `ims-pano` 360° panorama viewer
|
|
27
|
+
- `ims-spinner` 360° object viewer
|
|
28
|
+
- Adaptive content loading and DPI support
|
|
29
|
+
- Full-screen display mode
|
|
30
|
+
- Data-to-image steganographic encoding utilities
|
|
31
|
+
- Mobile device compatibility
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Contributing to IMS
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to Interactive Media Spots!
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/rnd-pro/immersive-media-spots.git
|
|
9
|
+
cd immersive-media-spots
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Project Structure
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
lib/ — Shared base classes and utilities
|
|
17
|
+
ImsBaseClass.js — Base class for all widgets
|
|
18
|
+
FullscreenMgr.js — Fullscreen API manager
|
|
19
|
+
ImageReader.js — Image sequence loader with progress
|
|
20
|
+
tokens.css — CSS design tokens
|
|
21
|
+
validateConfig.js — Runtime config validation
|
|
22
|
+
|
|
23
|
+
wgt/ — Widget implementations
|
|
24
|
+
diff/ — Image comparison
|
|
25
|
+
gallery/ — Image gallery
|
|
26
|
+
pano/ — 360° panorama viewer
|
|
27
|
+
spinner/ — 360° object viewer
|
|
28
|
+
video/ — Video player with HLS
|
|
29
|
+
viewer/ — Universal CDN-driven loader
|
|
30
|
+
|
|
31
|
+
tests/ — Unit tests (Node.js test runner)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Widget Anatomy
|
|
35
|
+
|
|
36
|
+
Each widget follows this structure:
|
|
37
|
+
- `index.js` — Component class extending `ImsBaseClass`
|
|
38
|
+
- `template.js` — HTML template
|
|
39
|
+
- `styles.js` — Shadow DOM styles
|
|
40
|
+
- `ImsXxxData.js` — Data schema class
|
|
41
|
+
- `test.html` — Manual test page
|
|
42
|
+
- `test-data.json` — Test fixture data
|
|
43
|
+
|
|
44
|
+
## Running Tests
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm test
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Code Style
|
|
51
|
+
|
|
52
|
+
- Single quotes for strings
|
|
53
|
+
- 2-space indentation
|
|
54
|
+
- Semicolons required
|
|
55
|
+
- ESM only (no `require`)
|
|
56
|
+
- Use `#` for private class fields
|
|
57
|
+
- JSDoc for type annotations
|
|
58
|
+
- Modern CSS nesting
|
|
59
|
+
- No external CSS frameworks
|
|
60
|
+
|
|
61
|
+
## Submitting Changes
|
|
62
|
+
|
|
63
|
+
1. Fork and create a feature branch
|
|
64
|
+
2. Make your changes following the code style above
|
|
65
|
+
3. Add/update tests for new functionality
|
|
66
|
+
4. Ensure `npm test` passes
|
|
67
|
+
5. Submit a PR with a clear description
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 RND-PRO.com (team@rnd-pro.com). All rights reserved.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
[](https://badge.fury.io/js/immersive-media-spots)
|
|
2
|
+
[](https://opensource.org/licenses/MIT)
|
|
3
|
+
|
|
4
|
+
# IMS — Immersive Media Spots
|
|
5
|
+
|
|
6
|
+
<img src="https://rnd-pro.com/svg/ims/index.svg" width="200" alt="IMS: Immersive Media Spots">
|
|
7
|
+
|
|
8
|
+
**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.
|
|
9
|
+
|
|
10
|
+
## ✨ Why IMS?
|
|
11
|
+
|
|
12
|
+
- **One tag — one widget.** Just `<ims-viewer src-data="data.json">` and you're done.
|
|
13
|
+
- **Universal.** Works in any stack: vanilla HTML, React, Vue, Angular, Svelte — anything that renders DOM.
|
|
14
|
+
- **Smart loading.** Adaptive resolution based on viewport & DPI, lazy loading via IntersectionObserver, on-demand dependency imports.
|
|
15
|
+
- **Hypermedia navigation.** Link widgets together with interactive hotspots — let users explore 3D products, then dive into 360° interiors, then watch a demo video, all in one seamless flow.
|
|
16
|
+
- **Themeable.** Full CSS custom properties for colors, sizing, and layout. No CSS framework lock-in.
|
|
17
|
+
- **Lightweight.** Built on [Symbiote.js](https://github.com/nicothed/symbiote.js) — each widget loads only what it needs.
|
|
18
|
+
|
|
19
|
+
## 🧩 Widgets
|
|
20
|
+
|
|
21
|
+
| Widget | Description | Docs |
|
|
22
|
+
|--------|-------------|------|
|
|
23
|
+
| **ims-spinner** | 360° product viewer with frame-by-frame rotation, autoplay, and drag interaction | [docs](./docs/spinner.md) |
|
|
24
|
+
| **ims-gallery** | Touch-friendly image gallery with navigation, looping, and fullscreen | [docs](./docs/gallery.md) |
|
|
25
|
+
| **ims-diff** | Before/after image comparison with a draggable slider | [docs](./docs/diff.md) |
|
|
26
|
+
| **ims-pano** | 360° panorama with inertia-based pan, zoom, and auto-rotation (Three.js) | [docs](./docs/pano.md) |
|
|
27
|
+
| **ims-model** | 3D model viewer for GLTF/GLB with orbit controls and auto-rotation (Three.js) | [docs](./docs/model.md) |
|
|
28
|
+
| **ims-video** | Video player with HLS adaptive streaming, subtitles, and quality switching | [docs](./docs/video.md) |
|
|
29
|
+
| **ims-audio** | Audio player with real-time waveform visualization (Web Audio API) | [docs](./docs/audio.md) |
|
|
30
|
+
| **ims-hotspots** | Interactive overlay spots with state-bound positioning and keyframe animation | [docs](./docs/hotspots.md) |
|
|
31
|
+
| **ims-viewer** | Universal loader — auto-imports any widget by type with version control, manages hotspot navigation and history | [docs](./docs/viewer.md) |
|
|
32
|
+
|
|
33
|
+
## 🚀 Quick Start
|
|
34
|
+
|
|
35
|
+
**1.** Set up [dependencies](./docs/dependencies.md) — 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)
|
|
36
|
+
|
|
37
|
+
**2. Load the viewer** (it pulls widget code on demand):
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/immersive-media-spots@<VERSION>/viewer/+esm"></script>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**3. Use it:**
|
|
44
|
+
|
|
45
|
+
```html
|
|
46
|
+
<ims-viewer src-data="./product.json"></ims-viewer>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
That's it. The viewer reads `imsType` from `product.json` and dynamically imports the right widget.
|
|
50
|
+
|
|
51
|
+
### Direct widget usage
|
|
52
|
+
|
|
53
|
+
Skip the viewer and load a specific widget directly:
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/immersive-media-spots@<VERSION>/spinner/+esm"></script>
|
|
57
|
+
|
|
58
|
+
<ims-spinner src-data="./data.json" autoplay="true"></ims-spinner>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### npm
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm install immersive-media-spots
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 🔗 Hypermedia Navigation
|
|
68
|
+
|
|
69
|
+
Combine `ims-viewer` with `ims-hotspots` to create connected experiences:
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<ims-viewer
|
|
73
|
+
src-data="./exterior-spin.json"
|
|
74
|
+
url-template="./{{imsType}}/index.js"
|
|
75
|
+
hotspots="./exterior-hotspots.json">
|
|
76
|
+
</ims-viewer>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
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](./docs/hotspots.md)
|
|
80
|
+
|
|
81
|
+
## ⚙️ Common Features
|
|
82
|
+
|
|
83
|
+
All widgets share a base architecture that provides:
|
|
84
|
+
|
|
85
|
+
- 🎯 **Adaptive loading** — automatically selects the best resolution variant for the viewport and DPI
|
|
86
|
+
- 🔄 **Lazy loading** — `lazy` attribute defers initialization until the element enters the viewport
|
|
87
|
+
- 🖥️ **Fullscreen** — native Fullscreen API with CSS fallback
|
|
88
|
+
- 📱 **Mobile-ready** — touch gestures, responsive sizing, pointer event support
|
|
89
|
+
- 🎨 **CSS theming** — design tokens for toolbar, colors, spacing, and transitions
|
|
90
|
+
- 🔌 **Plugin system** — extend lifecycle hooks with custom plugins
|
|
91
|
+
- 📡 **Events** — standard lifecycle events: `ims-load`, `ims-ready`, `ims-error` ([→ events docs](./docs/events.md))
|
|
92
|
+
- 🏷️ **Attribute overrides** — override any JSON config property via HTML attributes
|
|
93
|
+
|
|
94
|
+
## 📚 Documentation
|
|
95
|
+
|
|
96
|
+
Full per-widget API reference, config schemas, and CSS custom properties:
|
|
97
|
+
|
|
98
|
+
| | | |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| [Spinner](./docs/spinner.md) | [Gallery](./docs/gallery.md) | [Diff](./docs/diff.md) |
|
|
101
|
+
| [Pano](./docs/pano.md) | [Model](./docs/model.md) | [Video](./docs/video.md) |
|
|
102
|
+
| [Audio](./docs/audio.md) | [Hotspots](./docs/hotspots.md) | [Viewer](./docs/viewer.md) |
|
|
103
|
+
| [Events](./docs/events.md) | [Dependencies](./docs/dependencies.md) | |
|
|
104
|
+
|
|
105
|
+
## 📰 Articles & Demos
|
|
106
|
+
|
|
107
|
+
- [Concept details and live demo](https://rnd-pro.com/pulse/immersive-media-spots/)
|
|
108
|
+
|
|
109
|
+
## Contributing
|
|
110
|
+
|
|
111
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT © [rnd-pro.com](https://rnd-pro.com)
|
package/docs/audio.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# ims-audio
|
|
2
|
+
|
|
3
|
+
Audio player with waveform visualization.
|
|
4
|
+
|
|
5
|
+
## Tag
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<ims-audio src-data="path/to/data.json"></ims-audio>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Attributes
|
|
12
|
+
|
|
13
|
+
| Attribute | Description |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `src-data` | URL to JSON config |
|
|
16
|
+
| `lazy` | Enable lazy loading |
|
|
17
|
+
| `no-preloader` | Disable loading spinner |
|
|
18
|
+
|
|
19
|
+
## Config (`ImsAudioData`)
|
|
20
|
+
|
|
21
|
+
| Property | Type | Default | Description |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| `imsType` | `string` | `'audio'` | Widget type identifier |
|
|
24
|
+
| `srcList` | `string[]` | — | Audio file URL(s) |
|
|
25
|
+
| `autoplay` | `boolean` | `false` | Auto-play on load |
|
|
26
|
+
| `loop` | `boolean` | `false` | Loop playback |
|
|
27
|
+
| `waveformColor` | `string` | — | Waveform fill color |
|
|
28
|
+
| `progressColor` | `string` | — | Progress indicator color |
|
|
29
|
+
| `hideUi` | `boolean` | `false` | Hide toolbar |
|
|
30
|
+
|
|
31
|
+
## Public API
|
|
32
|
+
|
|
33
|
+
| Method | Description |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `play()` | Start playback |
|
|
36
|
+
| `pause()` | Pause playback |
|
|
37
|
+
| `togglePlay()` | Toggle play/pause |
|
|
38
|
+
| `seek(seconds)` | Seek to position in seconds |
|
|
39
|
+
| `setVolume(val)` | Set volume (0–100) |
|
|
40
|
+
| `toggleMute()` | Toggle mute |
|
|
41
|
+
|
|
42
|
+
## Events
|
|
43
|
+
|
|
44
|
+
See [events.md](./events.md) for standard IMS lifecycle events.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
|
|
3
|
+
IMS widgets are designed to keep a minimal footprint. Heavy third-party libraries are **only required by the widgets that actually use them** — if you never render a panorama or 3D model, Three.js is never loaded.
|
|
4
|
+
|
|
5
|
+
## Core
|
|
6
|
+
|
|
7
|
+
| Package | Specifier | Used by |
|
|
8
|
+
|---------|-----------|---------|
|
|
9
|
+
| [Symbiote.js](https://github.com/nicothed/symbiote.js) | `@symbiotejs/symbiote` | All widgets |
|
|
10
|
+
|
|
11
|
+
Symbiote.js is the only mandatory dependency. It provides the reactive web component base class used by every IMS widget.
|
|
12
|
+
|
|
13
|
+
## Optional (per-widget)
|
|
14
|
+
|
|
15
|
+
| Package | Specifier | Used by | Purpose |
|
|
16
|
+
|---------|-----------|---------|---------|
|
|
17
|
+
| [Three.js](https://threejs.org/) | `three` | ims-pano, ims-model | WebGL rendering for 360° panoramas and 3D models |
|
|
18
|
+
| Three.js addons | `three/addons/` | ims-model | GLTFLoader for `.glb`/`.gltf` model files |
|
|
19
|
+
| [hls.js](https://github.com/nicothed/hls.js/) | `hls.js/dist/hls.mjs` | ims-video | HLS adaptive streaming (only when `hlsSrc` is configured) |
|
|
20
|
+
|
|
21
|
+
> **If you only use `ims-spinner`, `ims-gallery`, `ims-diff`, `ims-audio`, or `ims-hotspots` — no optional dependencies are needed at all.**
|
|
22
|
+
|
|
23
|
+
## Setup via importmap
|
|
24
|
+
|
|
25
|
+
The simplest way to provide dependencies is an [importmap](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) — no build step needed:
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<script type="importmap">
|
|
29
|
+
{
|
|
30
|
+
"imports": {
|
|
31
|
+
"@symbiotejs/symbiote": "https://cdn.jsdelivr.net/npm/@symbiotejs/symbiote@3/+esm",
|
|
32
|
+
"three": "https://cdn.jsdelivr.net/npm/three@0.170.0/+esm",
|
|
33
|
+
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/",
|
|
34
|
+
"hls.js/dist/hls.mjs": "https://cdn.jsdelivr.net/npm/hls.js@1.5/+esm"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Only include the entries you actually need. For example, if you only use `ims-spinner`:
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<script type="importmap">
|
|
44
|
+
{
|
|
45
|
+
"imports": {
|
|
46
|
+
"@symbiotejs/symbiote": "https://cdn.jsdelivr.net/npm/@symbiotejs/symbiote@3/+esm"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Bundled setup
|
|
53
|
+
|
|
54
|
+
When using a bundler (Vite, esbuild, Webpack, etc.), install the required packages via npm and let the bundler resolve them:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Core (required)
|
|
58
|
+
npm install @symbiotejs/symbiote
|
|
59
|
+
|
|
60
|
+
# Optional — only if you use the corresponding widgets
|
|
61
|
+
npm install three # ims-pano, ims-model
|
|
62
|
+
npm install hls.js # ims-video with HLS
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The bundler will tree-shake unused widgets and their dependencies automatically.
|
|
66
|
+
|
|
67
|
+
## CDN resolution (ims-viewer)
|
|
68
|
+
|
|
69
|
+
When using `ims-viewer`, widget code is **loaded dynamically** at runtime based on the `imsType` field in the source data. The importmap must be present at page load so that dynamically imported modules can resolve their dependencies correctly.
|
package/docs/diff.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# ims-diff
|
|
2
|
+
|
|
3
|
+
Before/after image comparison with multiple modes.
|
|
4
|
+
|
|
5
|
+
## Tag
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<ims-diff src-data="path/to/data.json"></ims-diff>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Attributes
|
|
12
|
+
|
|
13
|
+
| Attribute | Description |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `src-data` | URL to JSON config |
|
|
16
|
+
| `lazy` | Enable lazy loading |
|
|
17
|
+
| `no-preloader` | Disable loading spinner |
|
|
18
|
+
| `vertical` | Set automatically when orientation is vertical |
|
|
19
|
+
|
|
20
|
+
## Config (`ImsDiffData`)
|
|
21
|
+
|
|
22
|
+
| Property | Type | Default | Description |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
| `imsType` | `string` | `'diff'` | Widget type identifier |
|
|
25
|
+
| `srcList` | `string[]` | — | Image URLs (pairs for comparison) |
|
|
26
|
+
| `mode` | `string` | `'slider'` | Comparison mode: `'slider'` or `'onion'` |
|
|
27
|
+
| `orientation` | `string` | `'horizontal'` | Split orientation: `'horizontal'` or `'vertical'` |
|
|
28
|
+
| `startPosition` | `number` | `50` | Initial slider position (0–100) |
|
|
29
|
+
| `animateSpeed` | `number` | `2000` | Animated sweep duration (ms per full sweep) |
|
|
30
|
+
| `filters` | `string[]` | — | CSS filter strings per image |
|
|
31
|
+
| `hideUi` | `boolean` | `false` | Hide toolbar |
|
|
32
|
+
| `urlTemplate` | `string` | — | URL template with placeholders |
|
|
33
|
+
| `variants` | `string[]` | — | Available size variants |
|
|
34
|
+
|
|
35
|
+
## Comparison Modes
|
|
36
|
+
|
|
37
|
+
### Slider (default)
|
|
38
|
+
Drag to reveal — splits images with a movable divider line. In horizontal mode the split is left/right, in vertical mode it's top/bottom.
|
|
39
|
+
|
|
40
|
+
### Onion-skin
|
|
41
|
+
Overlays the second image on top of the first. Drag controls the opacity (0–1) of the overlay.
|
|
42
|
+
|
|
43
|
+
## Public API
|
|
44
|
+
|
|
45
|
+
| Method | Description |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `setShare(percent)` | Set slider/opacity position (0–100) |
|
|
48
|
+
| `goTo(index)` | Switch to a specific diff pair (0-based) |
|
|
49
|
+
| `setMode(mode)` | Set mode: `'slider'` or `'onion'` |
|
|
50
|
+
| `toggleMode()` | Toggle between slider and onion |
|
|
51
|
+
| `toggleOrientation()` | Toggle horizontal/vertical split |
|
|
52
|
+
| `startAnimate()` | Start animated sweep |
|
|
53
|
+
| `stopAnimate()` | Stop animated sweep |
|
|
54
|
+
| `toggleAnimate()` | Toggle animated sweep |
|
|
55
|
+
|
|
56
|
+
## Toolbar
|
|
57
|
+
|
|
58
|
+
| Button | Action |
|
|
59
|
+
|---|---|
|
|
60
|
+
| Mode | Toggle slider ↔ onion |
|
|
61
|
+
| Orientation | Toggle horizontal ↔ vertical |
|
|
62
|
+
| Play/Pause | Toggle animated sweep |
|
|
63
|
+
| ◀ / ▶ | Previous/next pair (visible when `srcList > 2`) |
|
|
64
|
+
| Fullscreen | Toggle fullscreen |
|
|
65
|
+
|
|
66
|
+
## Events
|
|
67
|
+
|
|
68
|
+
See [events.md](./events.md) for standard IMS lifecycle events.
|
package/docs/events.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Events
|
|
2
|
+
|
|
3
|
+
All IMS widgets emit standard lifecycle events via `CustomEvent`. Enable with `dispatchEvents: true` in config or listen directly on the widget element.
|
|
4
|
+
|
|
5
|
+
## Event Types
|
|
6
|
+
|
|
7
|
+
| Event | Constant | Detail | Description |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `ims-load` | `ImsEvents.LOAD` | `{ progress: number }` | Data loading started |
|
|
10
|
+
| `ims-ready` | `ImsEvents.READY` | `{ srcData }` | Widget initialized and ready |
|
|
11
|
+
| `ims-error` | `ImsEvents.ERROR` | `{ error }` | Loading or initialization error |
|
|
12
|
+
| `ims-resize` | `ImsEvents.RESIZE` | — | Widget resized |
|
|
13
|
+
| `ims-destroy` | `ImsEvents.DESTROY` | — | Widget removed from DOM |
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { ImsEvents } from 'immersive-media-spots';
|
|
19
|
+
|
|
20
|
+
let spinner = document.querySelector('ims-spinner');
|
|
21
|
+
|
|
22
|
+
spinner.addEventListener(ImsEvents.READY, (e) => {
|
|
23
|
+
console.log('Widget ready:', e.detail.srcData);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
spinner.addEventListener(ImsEvents.ERROR, (e) => {
|
|
27
|
+
console.error('Widget error:', e.detail.error);
|
|
28
|
+
});
|
|
29
|
+
```
|
package/docs/gallery.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# ims-gallery
|
|
2
|
+
|
|
3
|
+
Image gallery with navigation, crossfade transitions, and optional captions.
|
|
4
|
+
|
|
5
|
+
## Tag
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<ims-gallery src-data="path/to/data.json"></ims-gallery>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Attributes
|
|
12
|
+
|
|
13
|
+
| Attribute | Description |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `src-data` | URL to JSON config |
|
|
16
|
+
| `lazy` | Enable lazy loading |
|
|
17
|
+
| `no-preloader` | Disable loading spinner |
|
|
18
|
+
|
|
19
|
+
## Config (`ImsGalleryData`)
|
|
20
|
+
|
|
21
|
+
| Property | Type | Default | Description |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| `imsType` | `string` | `'gallery'` | Widget type identifier |
|
|
24
|
+
| `srcList` | `string[]` | — | Image URLs |
|
|
25
|
+
| `captions` | `string[]` | `[]` | Per-image captions (parallel to srcList) |
|
|
26
|
+
| `transitionDuration` | `number` | `300` | Crossfade duration in ms |
|
|
27
|
+
| `autoplayInterval` | `number` | `3000` | Autoplay slide interval in ms |
|
|
28
|
+
| `loop` | `boolean` | `true` | Wrap around at ends |
|
|
29
|
+
| `hideUi` | `boolean` | `false` | Hide toolbar |
|
|
30
|
+
| `urlTemplate` | `string` | — | URL template with placeholders |
|
|
31
|
+
| `variants` | `string[]` | — | Available size variants |
|
|
32
|
+
|
|
33
|
+
## Public API
|
|
34
|
+
|
|
35
|
+
| Method | Description |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `goTo(index)` | Go to image by 0-based index |
|
|
38
|
+
| `next()` | Next image (wraps if `loop: true`) |
|
|
39
|
+
| `prev()` | Previous image (wraps if `loop: true`) |
|
|
40
|
+
| `startAutoplay()` | Start slideshow |
|
|
41
|
+
| `stopAutoplay()` | Stop slideshow |
|
|
42
|
+
| `toggleAutoplay()` | Toggle slideshow |
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
### Crossfade Transitions
|
|
47
|
+
Images crossfade using canvas globalAlpha blending. Duration controlled by `transitionDuration`.
|
|
48
|
+
|
|
49
|
+
### Touch Swipe
|
|
50
|
+
Horizontal swipe on the canvas triggers `next()`/`prev()`. Threshold: 50px.
|
|
51
|
+
|
|
52
|
+
### Image Counter
|
|
53
|
+
Toolbar shows current position (e.g. "3 / 12").
|
|
54
|
+
|
|
55
|
+
### Captions
|
|
56
|
+
Per-image captions from the `captions` config array are set as the widget's `title` attribute (browser tooltip). A `<slot>` element is available for custom caption components:
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<ims-gallery src-data="data.json">
|
|
60
|
+
<my-custom-caption></my-custom-caption>
|
|
61
|
+
</ims-gallery>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Autoplay
|
|
65
|
+
Timer-based auto-advance, toggleable from toolbar.
|
|
66
|
+
|
|
67
|
+
## Toolbar
|
|
68
|
+
|
|
69
|
+
| Button | Action |
|
|
70
|
+
|---|---|
|
|
71
|
+
| ◀ | Previous image |
|
|
72
|
+
| Counter | Shows position |
|
|
73
|
+
| ▶ | Next image |
|
|
74
|
+
| Play/Pause | Toggle autoplay |
|
|
75
|
+
| Fullscreen | Toggle fullscreen |
|
|
76
|
+
|
|
77
|
+
## Events
|
|
78
|
+
|
|
79
|
+
See [events.md](./events.md) for standard IMS lifecycle events.
|