layershift 0.1.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/LICENSE +65 -0
- package/README.md +196 -0
- package/dist/components/layershift.js +4296 -0
- package/dist/npm/layershift.es.js +21145 -0
- package/dist/types/components/layershift/global.d.ts +35 -0
- package/dist/types/components/layershift/index.d.ts +11 -0
- package/dist/types/components/layershift/index.d.ts.map +1 -0
- package/dist/types/components/layershift/layershift-element.d.ts +56 -0
- package/dist/types/components/layershift/layershift-element.d.ts.map +1 -0
- package/dist/types/components/layershift/types.d.ts +65 -0
- package/dist/types/components/layershift/types.d.ts.map +1 -0
- package/dist/types/depth-analysis.d.ts +104 -0
- package/dist/types/depth-analysis.d.ts.map +1 -0
- package/dist/types/input-handler.d.ts +22 -0
- package/dist/types/input-handler.d.ts.map +1 -0
- package/dist/types/parallax-renderer.d.ts +197 -0
- package/dist/types/parallax-renderer.d.ts.map +1 -0
- package/dist/types/precomputed-depth.d.ts +81 -0
- package/dist/types/precomputed-depth.d.ts.map +1 -0
- package/dist/types/video-source.d.ts +23 -0
- package/dist/types/video-source.d.ts.map +1 -0
- package/package.json +79 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Jeremy Sykes
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Licensor: Jeremy Sykes
|
|
7
|
+
|
|
8
|
+
Change Date: 2029-01-01
|
|
9
|
+
|
|
10
|
+
Change License: Apache License, Version 2.0
|
|
11
|
+
|
|
12
|
+
On the Change Date specified above, the Business Source License covering this file will change to the Apache License, Version 2.0.
|
|
13
|
+
|
|
14
|
+
Additional Use Grant
|
|
15
|
+
|
|
16
|
+
You may use, reproduce, and distribute this software and its documentation for:
|
|
17
|
+
|
|
18
|
+
1. Non-commercial purposes, including personal projects and educational use
|
|
19
|
+
2. Internal enterprise evaluation and testing purposes
|
|
20
|
+
3. Academic research and educational institutions
|
|
21
|
+
4. Open source projects that are not commercial SaaS offerings
|
|
22
|
+
|
|
23
|
+
You may NOT use this software for:
|
|
24
|
+
|
|
25
|
+
1. Providing this software as a service (SaaS) to third parties
|
|
26
|
+
2. Reselling, redistributing, or sublicensing this software commercially
|
|
27
|
+
3. Including this software in commercial products or services without a separate commercial license
|
|
28
|
+
4. Using this software to compete with the licensor's commercial offerings
|
|
29
|
+
|
|
30
|
+
For commercial use beyond the scope of this license, please contact the licensor to obtain a commercial license.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
Business Source License 1.1
|
|
35
|
+
|
|
36
|
+
Terms
|
|
37
|
+
|
|
38
|
+
The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and use non-production and production use in any form, with the right to sublicense such rights through multiple tiers of sublicensees, solely to the extent of the following:
|
|
39
|
+
|
|
40
|
+
1. You may use, reproduce, and distribute this software and its documentation for non-commercial, personal, educational, and internal enterprise evaluation purposes.
|
|
41
|
+
|
|
42
|
+
2. You may NOT use this software for:
|
|
43
|
+
a. Providing this software as a service (SaaS) to third parties
|
|
44
|
+
b. Reselling, redistributing, or sublicensing this software commercially
|
|
45
|
+
c. Including this software in commercial products or services without a separate commercial license
|
|
46
|
+
d. Using this software to compete with the licensor's commercial offerings
|
|
47
|
+
|
|
48
|
+
3. If you wish to use this software for commercial purposes beyond the scope of this license, you must obtain a separate commercial license from the Licensor.
|
|
49
|
+
|
|
50
|
+
4. This license does not grant you any rights to use the Licensor's trademarks, service marks, or other intellectual property except as necessary to use this software as licensed.
|
|
51
|
+
|
|
52
|
+
5. The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement.
|
|
53
|
+
|
|
54
|
+
6. In no event shall the Licensor be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.
|
|
55
|
+
|
|
56
|
+
Change Date: 2029-01-01
|
|
57
|
+
|
|
58
|
+
Change License: Apache License, Version 2.0
|
|
59
|
+
|
|
60
|
+
On the Change Date specified above, the Business Source License covering this file will change to the Apache License, Version 2.0, as published by the Apache Software Foundation.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
For questions about commercial licensing, please contact:
|
|
65
|
+
Jeremy Sykes
|
package/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Layershift
|
|
2
|
+
|
|
3
|
+
Embeddable video effects as Web Components. One script tag, one custom element — works in plain HTML, React, Vue, Svelte, Angular, WordPress, and anywhere else.
|
|
4
|
+
|
|
5
|
+
Layershift is a growing collection of visual effects that turn flat video into something interactive. Each effect ships as its own custom element under the `layershift-*` namespace.
|
|
6
|
+
|
|
7
|
+
## Effects
|
|
8
|
+
|
|
9
|
+
### `<layershift-parallax>` — Depth-Aware Parallax Video
|
|
10
|
+
|
|
11
|
+
A precomputed depth map drives per-pixel UV displacement with Parallax Occlusion Mapping (POM), so near objects move more than far objects — creating a convincing 3D effect from a single 2D video.
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<script src="https://cdn.layershift.io/layershift.js"></script>
|
|
15
|
+
|
|
16
|
+
<layershift-parallax
|
|
17
|
+
src="video.mp4"
|
|
18
|
+
depth-src="depth-data.bin"
|
|
19
|
+
depth-meta="depth-meta.json"
|
|
20
|
+
></layershift-parallax>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**[Live demo →](https://layershift.io)**
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
The `precompute` script needs **FFmpeg** to read video metadata and extract frames.
|
|
30
|
+
|
|
31
|
+
- **macOS:** `brew install ffmpeg`
|
|
32
|
+
- **Windows:** [FFmpeg downloads](https://ffmpeg.org/download.html) or `winget install FFmpeg`
|
|
33
|
+
- **Linux:** `apt install ffmpeg` / `dnf install ffmpeg`
|
|
34
|
+
|
|
35
|
+
## Setup
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Precompute Depth Data
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm run precompute
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Generates `public/depth-data.bin` and `public/depth-meta.json` from the video in `public/sample.mp4`.
|
|
48
|
+
|
|
49
|
+
## Development
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm run dev
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Build
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Build the landing page
|
|
59
|
+
npm run build
|
|
60
|
+
|
|
61
|
+
# Build the standalone Web Component
|
|
62
|
+
npm run build:component
|
|
63
|
+
|
|
64
|
+
# Package output (video + depth data + component + demo page)
|
|
65
|
+
npm run package
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## `<layershift-parallax>` Reference
|
|
71
|
+
|
|
72
|
+
### Configuration
|
|
73
|
+
|
|
74
|
+
| Attribute | Type | Default | Description |
|
|
75
|
+
|-----------|------|---------|-------------|
|
|
76
|
+
| `src` | string | — | Video file URL (required) |
|
|
77
|
+
| `depth-src` | string | — | Depth binary URL (required) |
|
|
78
|
+
| `depth-meta` | string | — | Depth metadata URL (required) |
|
|
79
|
+
| `parallax-x` | number | 0.4 | Horizontal parallax intensity |
|
|
80
|
+
| `parallax-y` | number | 1.0 | Vertical parallax intensity |
|
|
81
|
+
| `parallax-max` | number | 30 | Max pixel offset for nearest layer |
|
|
82
|
+
| `overscan` | number | 0.05 | Extra padding ratio |
|
|
83
|
+
| `autoplay` | boolean | true | Auto-play on mount |
|
|
84
|
+
| `loop` | boolean | true | Loop playback |
|
|
85
|
+
| `muted` | boolean | true | Muted (required for autoplay) |
|
|
86
|
+
|
|
87
|
+
### Framework Wrappers
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
// React
|
|
91
|
+
import { Layershift } from 'layershift/react'
|
|
92
|
+
|
|
93
|
+
// Vue
|
|
94
|
+
import Layershift from 'layershift/vue'
|
|
95
|
+
|
|
96
|
+
// Svelte
|
|
97
|
+
import Layershift from 'layershift/svelte'
|
|
98
|
+
|
|
99
|
+
// Angular
|
|
100
|
+
import { LayershiftComponent } from 'layershift/angular'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Vue note:** Add `compilerOptions.isCustomElement: (tag) => tag === 'layershift-parallax'` to your Vite or Vue config.
|
|
104
|
+
|
|
105
|
+
**Angular note:** Add `CUSTOM_ELEMENTS_SCHEMA` to your module or component schemas.
|
|
106
|
+
|
|
107
|
+
### Events
|
|
108
|
+
|
|
109
|
+
The `<layershift-parallax>` element dispatches custom events that bubble through the DOM (including Shadow DOM):
|
|
110
|
+
|
|
111
|
+
| Event | Detail | When |
|
|
112
|
+
|-------|--------|------|
|
|
113
|
+
| `layershift-parallax:ready` | `{ videoWidth, videoHeight, duration }` | Initialization complete |
|
|
114
|
+
| `layershift-parallax:play` | `{ currentTime }` | Video starts playing |
|
|
115
|
+
| `layershift-parallax:pause` | `{ currentTime }` | Video pauses |
|
|
116
|
+
| `layershift-parallax:loop` | `{ loopCount }` | Video loops back to start |
|
|
117
|
+
| `layershift-parallax:frame` | `{ currentTime, frameNumber }` | New video frame presented |
|
|
118
|
+
| `layershift-parallax:error` | `{ message }` | Initialization error |
|
|
119
|
+
|
|
120
|
+
```js
|
|
121
|
+
const el = document.querySelector('layershift-parallax');
|
|
122
|
+
|
|
123
|
+
el.addEventListener('layershift-parallax:ready', (e) => {
|
|
124
|
+
console.log(`Video: ${e.detail.videoWidth}x${e.detail.videoHeight}`);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
el.addEventListener('layershift-parallax:frame', (e) => {
|
|
128
|
+
updateTimeline(e.detail.currentTime);
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Frame-Level Sync
|
|
133
|
+
|
|
134
|
+
The renderer uses `requestVideoFrameCallback` (RVFC) when available to sync depth updates to actual video frame presentation:
|
|
135
|
+
|
|
136
|
+
- Depth work only runs when a new frame is decoded (~24–30fps)
|
|
137
|
+
- Parallax input stays smooth at display refresh rate (60–120fps)
|
|
138
|
+
- The `layershift-parallax:frame` event fires at true video frame rate
|
|
139
|
+
- Browsers without RVFC fall back to `requestAnimationFrame` automatically
|
|
140
|
+
|
|
141
|
+
### Performance
|
|
142
|
+
|
|
143
|
+
Each `<layershift-parallax>` instance creates 1 WebGL renderer, 1 Web Worker, 1 hidden `<video>` element, and 2 GPU textures (1 draw call per frame). The bilateral filter runs entirely off the main thread.
|
|
144
|
+
|
|
145
|
+
| Instances | Suitability |
|
|
146
|
+
|-----------|-------------|
|
|
147
|
+
| **1–3** | Smooth on all modern devices including mobile |
|
|
148
|
+
| **4–6** | Great on desktop; mobile may hit browser video decoder limits |
|
|
149
|
+
| **8–12** | Desktop only; consider pausing off-screen instances |
|
|
150
|
+
|
|
151
|
+
The bottleneck is concurrent video decoders, not GPU or Workers. Most mobile browsers cap hardware-decoded `<video>` streams at 4–8.
|
|
152
|
+
|
|
153
|
+
#### Per-Instance Resource Footprint (512x512 depth)
|
|
154
|
+
|
|
155
|
+
| Resource | Cost |
|
|
156
|
+
|----------|------|
|
|
157
|
+
| GPU textures | 2 (VideoTexture + 262 KB depth DataTexture) |
|
|
158
|
+
| Draw calls / frame | 1 |
|
|
159
|
+
| Web Workers | 1 (with sync fallback) |
|
|
160
|
+
| Worker RAM | ~3 MB (processing buffers) |
|
|
161
|
+
| Depth data download | ~13 MB (50 frames at 512x512) |
|
|
162
|
+
| RAF callbacks | 1 (60–120 fps) |
|
|
163
|
+
| RVFC callbacks | 1 (24–30 fps, when supported) |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Controls
|
|
168
|
+
|
|
169
|
+
- **Space** — Play / pause video
|
|
170
|
+
|
|
171
|
+
## Testing
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Unit tests (Vitest)
|
|
175
|
+
npm test
|
|
176
|
+
|
|
177
|
+
# E2E tests (Playwright, requires build first)
|
|
178
|
+
npm run build && npm run build:component && npm run test:e2e
|
|
179
|
+
|
|
180
|
+
# All tests
|
|
181
|
+
npm run build && npm run build:component && npm run test:all
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Roadmap
|
|
185
|
+
|
|
186
|
+
Future effects under the Layershift umbrella:
|
|
187
|
+
|
|
188
|
+
- `<layershift-scroll>` — Scroll-driven video playback
|
|
189
|
+
- `<layershift-reveal>` — Depth-based reveal/mask transitions
|
|
190
|
+
- More to come
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
Business Source License 1.1 — see [LICENSE](./LICENSE) for details.
|
|
195
|
+
|
|
196
|
+
Change date: 2029-01-01 → Apache License 2.0
|