layershift 0.4.0 → 0.4.2
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/README.md +41 -117
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,40 +4,35 @@
|
|
|
4
4
|
|
|
5
5
|
Embeddable video effects as Web Components. One script tag, one custom element — works in plain HTML, React, Vue, Svelte, Angular, WordPress, and anywhere else.
|
|
6
6
|
|
|
7
|
-
Layershift is a growing collection of visual effects that turn flat video into something interactive.
|
|
7
|
+
Layershift is a growing collection of visual effects that turn flat video into something interactive. Effects are configured via a `filter-config.json` file authored in the [Layershift Editor](https://layershift.io/editor/).
|
|
8
8
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
### `<layershift-parallax>` — Depth-Aware Parallax Video
|
|
12
|
-
|
|
13
|
-
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.
|
|
9
|
+
## Quick Start
|
|
14
10
|
|
|
15
11
|
```html
|
|
16
|
-
<script src="https://
|
|
12
|
+
<script src="https://unpkg.com/layershift"></script>
|
|
17
13
|
|
|
18
|
-
<layershift-
|
|
14
|
+
<layershift-effect
|
|
19
15
|
src="video.mp4"
|
|
20
16
|
depth-src="depth-data.bin"
|
|
21
17
|
depth-meta="depth-meta.json"
|
|
22
|
-
|
|
18
|
+
config="filter-config.json"
|
|
19
|
+
></layershift-effect>
|
|
23
20
|
```
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
**[Live demo →](https://layershift.io)**
|
|
26
23
|
|
|
27
|
-
|
|
24
|
+
## Effects
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
<script src="https://cdn.layershift.io/layershift.js"></script>
|
|
26
|
+
The `<layershift-effect>` element supports multiple effect types, all driven by the same depth data:
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```
|
|
28
|
+
- **Depth Parallax** — per-pixel UV displacement via Parallax Occlusion Mapping
|
|
29
|
+
- **Depth Glow** — depth-driven emissive glow
|
|
30
|
+
- **Color Grade** — depth-aware color grading
|
|
31
|
+
- **Fog / Atmosphere** — depth-based atmospheric haze
|
|
32
|
+
- **Tilt Shift** — miniature/diorama lens effect
|
|
33
|
+
- **Pop-Out** — foreground subjects break out of the frame
|
|
39
34
|
|
|
40
|
-
|
|
35
|
+
Effects are configured in the [Layershift Editor](https://layershift.io/editor/) and exported as a `filter-config.json` file.
|
|
41
36
|
|
|
42
37
|
---
|
|
43
38
|
|
|
@@ -46,7 +41,7 @@ Renders video through an SVG-shaped cutout with depth-aware parallax, emissive i
|
|
|
46
41
|
### Script Tag (IIFE)
|
|
47
42
|
|
|
48
43
|
```html
|
|
49
|
-
<script src="https://
|
|
44
|
+
<script src="https://unpkg.com/layershift"></script>
|
|
50
45
|
```
|
|
51
46
|
|
|
52
47
|
### npm
|
|
@@ -57,7 +52,7 @@ npm install layershift
|
|
|
57
52
|
|
|
58
53
|
```js
|
|
59
54
|
import 'layershift';
|
|
60
|
-
//
|
|
55
|
+
// <layershift-effect> and <layershift-portal> are now registered
|
|
61
56
|
```
|
|
62
57
|
|
|
63
58
|
### TypeScript
|
|
@@ -71,31 +66,21 @@ Add JSX type support for the custom elements:
|
|
|
71
66
|
|
|
72
67
|
---
|
|
73
68
|
|
|
74
|
-
##
|
|
75
|
-
|
|
76
|
-
The `precompute` script needs **FFmpeg** to read video metadata and extract frames.
|
|
69
|
+
## Prepare Your Video
|
|
77
70
|
|
|
78
|
-
|
|
79
|
-
- **Windows:** [FFmpeg downloads](https://ffmpeg.org/download.html) or `winget install FFmpeg`
|
|
80
|
-
- **Linux:** `apt install ffmpeg` / `dnf install ffmpeg`
|
|
71
|
+
Use the [Layershift Editor](https://layershift.io/editor/) to:
|
|
81
72
|
|
|
82
|
-
|
|
73
|
+
1. Import a video or image
|
|
74
|
+
2. Run browser-based depth estimation (no CLI needed)
|
|
75
|
+
3. Configure your effect with the visual editor
|
|
76
|
+
4. Export a consumer package with all assets + config
|
|
83
77
|
|
|
84
|
-
|
|
85
|
-
npm install
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
## Precompute Depth Data
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
npm run precompute
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Generates `depth-data.bin` and `depth-meta.json` from a video using Depth Anything v2.
|
|
78
|
+
The editor produces `depth-data.bin`, `depth-meta.json`, and `filter-config.json` — everything `<layershift-effect>` needs.
|
|
95
79
|
|
|
96
80
|
## Development
|
|
97
81
|
|
|
98
82
|
```bash
|
|
83
|
+
npm install
|
|
99
84
|
npm run dev
|
|
100
85
|
```
|
|
101
86
|
|
|
@@ -126,19 +111,22 @@ Components follow atomic design (Atoms → Molecules → Organisms → Templates
|
|
|
126
111
|
|
|
127
112
|
---
|
|
128
113
|
|
|
129
|
-
## `<layershift-
|
|
114
|
+
## `<layershift-effect>` Reference
|
|
130
115
|
|
|
131
116
|
### Configuration
|
|
132
117
|
|
|
133
118
|
| Attribute | Type | Default | Description |
|
|
134
119
|
|-----------|------|---------|-------------|
|
|
135
|
-
| `src` | string | — | Video
|
|
120
|
+
| `src` | string | — | Video or image URL (required) |
|
|
136
121
|
| `depth-src` | string | — | Depth binary URL (required) |
|
|
137
122
|
| `depth-meta` | string | — | Depth metadata URL (required) |
|
|
123
|
+
| `config` | string | — | Filter config JSON URL |
|
|
138
124
|
| `parallax-x` | number | 0.4 | Horizontal parallax intensity |
|
|
139
125
|
| `parallax-y` | number | 1.0 | Vertical parallax intensity |
|
|
140
126
|
| `parallax-max` | number | 30 | Max pixel offset for nearest layer |
|
|
141
127
|
| `overscan` | number | 0.05 | Extra padding ratio |
|
|
128
|
+
| `quality` | string | auto | Quality tier: `auto`, `high`, `medium`, `low` |
|
|
129
|
+
| `source-type` | string | video | Source type: `video`, `image`, `camera` |
|
|
142
130
|
| `autoplay` | boolean | true | Auto-play on mount |
|
|
143
131
|
| `loop` | boolean | true | Loop playback |
|
|
144
132
|
| `muted` | boolean | true | Muted (required for autoplay) |
|
|
@@ -147,24 +135,24 @@ Components follow atomic design (Atoms → Molecules → Organisms → Templates
|
|
|
147
135
|
|
|
148
136
|
| Event | Detail | When |
|
|
149
137
|
|-------|--------|------|
|
|
150
|
-
| `layershift-
|
|
151
|
-
| `layershift-
|
|
152
|
-
| `layershift-
|
|
153
|
-
| `layershift-
|
|
154
|
-
| `layershift-
|
|
155
|
-
| `layershift-
|
|
138
|
+
| `layershift-effect:ready` | `{ videoWidth, videoHeight, duration }` | Initialization complete |
|
|
139
|
+
| `layershift-effect:play` | `{ currentTime }` | Video starts playing |
|
|
140
|
+
| `layershift-effect:pause` | `{ currentTime }` | Video pauses |
|
|
141
|
+
| `layershift-effect:loop` | `{ loopCount }` | Video loops back to start |
|
|
142
|
+
| `layershift-effect:frame` | `{ currentTime, frameNumber }` | New video frame presented |
|
|
143
|
+
| `layershift-effect:error` | `{ message }` | Initialization error |
|
|
156
144
|
|
|
157
145
|
```js
|
|
158
|
-
const el = document.querySelector('layershift-
|
|
146
|
+
const el = document.querySelector('layershift-effect');
|
|
159
147
|
|
|
160
|
-
el.addEventListener('layershift-
|
|
148
|
+
el.addEventListener('layershift-effect:ready', (e) => {
|
|
161
149
|
console.log(`Video: ${e.detail.videoWidth}x${e.detail.videoHeight}`);
|
|
162
150
|
});
|
|
163
151
|
```
|
|
164
152
|
|
|
165
153
|
### Performance
|
|
166
154
|
|
|
167
|
-
Each `<layershift-
|
|
155
|
+
Each `<layershift-effect>` 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.
|
|
168
156
|
|
|
169
157
|
| Instances | Suitability |
|
|
170
158
|
|-----------|-------------|
|
|
@@ -174,73 +162,9 @@ Each `<layershift-parallax>` instance creates 1 WebGL renderer, 1 Web Worker, 1
|
|
|
174
162
|
|
|
175
163
|
---
|
|
176
164
|
|
|
177
|
-
## `<layershift-portal>` Reference
|
|
178
|
-
|
|
179
|
-
### Required Attributes
|
|
180
|
-
|
|
181
|
-
| Attribute | Type | Description |
|
|
182
|
-
|-----------|------|-------------|
|
|
183
|
-
| `src` | string | Video file URL |
|
|
184
|
-
| `depth-src` | string | Depth binary URL |
|
|
185
|
-
| `depth-meta` | string | Depth metadata URL |
|
|
186
|
-
| `logo-src` | string | SVG file URL for the portal shape |
|
|
187
|
-
|
|
188
|
-
### Key Optional Attributes
|
|
189
|
-
|
|
190
|
-
| Attribute | Type | Default | Description |
|
|
191
|
-
|-----------|------|---------|-------------|
|
|
192
|
-
| `parallax-x` | number | 0.4 | Horizontal parallax intensity |
|
|
193
|
-
| `parallax-y` | number | 0.8 | Vertical parallax intensity |
|
|
194
|
-
| `parallax-max` | number | 30 | Max parallax in pixels |
|
|
195
|
-
| `chamfer-width` | number | 0.025 | Chamfer geometry width (0 = no chamfer) |
|
|
196
|
-
| `chamfer-color` | string | #262630 | Chamfer tint color |
|
|
197
|
-
| `chamfer-specular` | number | 0.3 | Chamfer specular highlight |
|
|
198
|
-
| `rim-intensity` | number | 0.6 | Rim light intensity (0 = off) |
|
|
199
|
-
| `rim-color` | string | #ffffff | Rim light color |
|
|
200
|
-
| `light-direction` | string | -0.5,0.7,-0.3 | 3D light direction as "x,y,z" |
|
|
201
|
-
| `autoplay` | boolean | true | Auto-play on mount |
|
|
202
|
-
| `loop` | boolean | true | Loop playback |
|
|
203
|
-
| `muted` | boolean | true | Muted (required for autoplay) |
|
|
204
|
-
|
|
205
|
-
The portal supports 40+ optional attributes for fine-grained control over the interior scene, chamfer geometry, boundary effects, bevel, volumetric edge wall, and depth-of-field. See `docs/portal/portal-overview.md` for the full reference.
|
|
206
|
-
|
|
207
|
-
### Transparent Background
|
|
208
|
-
|
|
209
|
-
The portal canvas is fully transparent outside the logo shape. Overlay it on any background:
|
|
210
|
-
|
|
211
|
-
```html
|
|
212
|
-
<div style="position: relative; background: #1a1a2e;">
|
|
213
|
-
<layershift-portal
|
|
214
|
-
src="video.mp4"
|
|
215
|
-
depth-src="depth-data.bin"
|
|
216
|
-
depth-meta="depth-meta.json"
|
|
217
|
-
logo-src="logo.svg"
|
|
218
|
-
style="position: absolute; inset: 0;"
|
|
219
|
-
autoplay loop muted
|
|
220
|
-
></layershift-portal>
|
|
221
|
-
</div>
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### Events
|
|
225
|
-
|
|
226
|
-
| Event | Detail | When |
|
|
227
|
-
|-------|--------|------|
|
|
228
|
-
| `layershift-portal:ready` | `{ videoWidth, videoHeight, duration }` | Initialization complete |
|
|
229
|
-
| `layershift-portal:play` | `{ currentTime }` | Video starts playing |
|
|
230
|
-
| `layershift-portal:pause` | `{ currentTime }` | Video pauses |
|
|
231
|
-
| `layershift-portal:loop` | `{ loopCount }` | Video loops back to start |
|
|
232
|
-
| `layershift-portal:frame` | `{ currentTime, frameNumber }` | New video frame presented |
|
|
233
|
-
| `layershift-portal:error` | `{ message }` | Initialization error |
|
|
234
|
-
|
|
235
|
-
### SVG Requirements
|
|
236
|
-
|
|
237
|
-
The `logo-src` SVG should use a `viewBox` attribute and contain filled shapes (`<path>`, `<polygon>`, `<rect>`, `<circle>`, `<ellipse>`). Complex SVGs with multiple paths, compound paths, nested groups, and holes (letters A, R, O, etc.) are supported.
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
165
|
## Frame-Level Sync
|
|
242
166
|
|
|
243
|
-
|
|
167
|
+
`<layershift-effect>` uses `requestVideoFrameCallback` (RVFC) when available to sync depth updates to actual video frame presentation:
|
|
244
168
|
|
|
245
169
|
- Depth work only runs when a new frame is decoded (~24–30fps)
|
|
246
170
|
- Parallax input stays smooth at display refresh rate (60–120fps)
|
package/package.json
CHANGED