layershift 0.2.0 → 0.2.1

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.
Files changed (2) hide show
  1. package/README.md +119 -60
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -20,10 +20,55 @@ A precomputed depth map drives per-pixel UV displacement with Parallax Occlusion
20
20
  ></layershift-parallax>
21
21
  ```
22
22
 
23
+ ### `<layershift-portal>` — Logo Depth Portal
24
+
25
+ Renders video through an SVG-shaped cutout with depth-aware parallax, emissive interior compositing, geometric chamfer lighting, and dimensional boundary effects. The canvas background is fully transparent, so the portal can be overlaid on any HTML content.
26
+
27
+ ```html
28
+ <script src="https://cdn.layershift.io/layershift.js"></script>
29
+
30
+ <layershift-portal
31
+ src="video.mp4"
32
+ depth-src="depth-data.bin"
33
+ depth-meta="depth-meta.json"
34
+ logo-src="logo.svg"
35
+ ></layershift-portal>
36
+ ```
37
+
23
38
  **[Live demo →](https://layershift.io)**
24
39
 
25
40
  ---
26
41
 
42
+ ## Install
43
+
44
+ ### Script Tag (IIFE)
45
+
46
+ ```html
47
+ <script src="https://cdn.layershift.io/layershift.js"></script>
48
+ ```
49
+
50
+ ### npm
51
+
52
+ ```bash
53
+ npm install layershift
54
+ ```
55
+
56
+ ```js
57
+ import 'layershift';
58
+ // Both <layershift-parallax> and <layershift-portal> are now registered
59
+ ```
60
+
61
+ ### TypeScript
62
+
63
+ Add JSX type support for the custom elements:
64
+
65
+ ```json
66
+ // tsconfig.json
67
+ { "compilerOptions": { "types": ["layershift/global"] } }
68
+ ```
69
+
70
+ ---
71
+
27
72
  ## Prerequisites
28
73
 
29
74
  The `precompute` script needs **FFmpeg** to read video metadata and extract frames.
@@ -44,7 +89,7 @@ npm install
44
89
  npm run precompute
45
90
  ```
46
91
 
47
- Generates `public/depth-data.bin` and `public/depth-meta.json` from the video in `public/sample.mp4`.
92
+ Generates `depth-data.bin` and `depth-meta.json` from a video using Depth Anything v2.
48
93
 
49
94
  ## Development
50
95
 
@@ -58,11 +103,11 @@ npm run dev
58
103
  # Build the landing page
59
104
  npm run build
60
105
 
61
- # Build the standalone Web Component
106
+ # Build the standalone Web Component (IIFE)
62
107
  npm run build:component
63
108
 
64
- # Package output (video + depth data + component + demo page)
65
- npm run package
109
+ # Build the npm package (ESM + IIFE + types)
110
+ npm run build:package
66
111
  ```
67
112
 
68
113
  ---
@@ -84,30 +129,8 @@ npm run package
84
129
  | `loop` | boolean | true | Loop playback |
85
130
  | `muted` | boolean | true | Muted (required for autoplay) |
86
131
 
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
132
  ### Events
108
133
 
109
- The `<layershift-parallax>` element dispatches custom events that bubble through the DOM (including Shadow DOM):
110
-
111
134
  | Event | Detail | When |
112
135
  |-------|--------|------|
113
136
  | `layershift-parallax:ready` | `{ videoWidth, videoHeight, duration }` | Initialization complete |
@@ -123,21 +146,8 @@ const el = document.querySelector('layershift-parallax');
123
146
  el.addEventListener('layershift-parallax:ready', (e) => {
124
147
  console.log(`Video: ${e.detail.videoWidth}x${e.detail.videoHeight}`);
125
148
  });
126
-
127
- el.addEventListener('layershift-parallax:frame', (e) => {
128
- updateTimeline(e.detail.currentTime);
129
- });
130
149
  ```
131
150
 
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
151
  ### Performance
142
152
 
143
153
  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.
@@ -148,25 +158,82 @@ Each `<layershift-parallax>` instance creates 1 WebGL renderer, 1 Web Worker, 1
148
158
  | **4–6** | Great on desktop; mobile may hit browser video decoder limits |
149
159
  | **8–12** | Desktop only; consider pausing off-screen instances |
150
160
 
151
- The bottleneck is concurrent video decoders, not GPU or Workers. Most mobile browsers cap hardware-decoded `<video>` streams at 4–8.
161
+ ---
162
+
163
+ ## `<layershift-portal>` Reference
164
+
165
+ ### Required Attributes
166
+
167
+ | Attribute | Type | Description |
168
+ |-----------|------|-------------|
169
+ | `src` | string | Video file URL |
170
+ | `depth-src` | string | Depth binary URL |
171
+ | `depth-meta` | string | Depth metadata URL |
172
+ | `logo-src` | string | SVG file URL for the portal shape |
173
+
174
+ ### Key Optional Attributes
175
+
176
+ | Attribute | Type | Default | Description |
177
+ |-----------|------|---------|-------------|
178
+ | `parallax-x` | number | 0.4 | Horizontal parallax intensity |
179
+ | `parallax-y` | number | 0.8 | Vertical parallax intensity |
180
+ | `parallax-max` | number | 30 | Max parallax in pixels |
181
+ | `chamfer-width` | number | 0.025 | Chamfer geometry width (0 = no chamfer) |
182
+ | `chamfer-color` | string | #262630 | Chamfer tint color |
183
+ | `chamfer-specular` | number | 0.3 | Chamfer specular highlight |
184
+ | `rim-intensity` | number | 0.6 | Rim light intensity (0 = off) |
185
+ | `rim-color` | string | #ffffff | Rim light color |
186
+ | `light-direction` | string | -0.5,0.7,-0.3 | 3D light direction as "x,y,z" |
187
+ | `autoplay` | boolean | true | Auto-play on mount |
188
+ | `loop` | boolean | true | Loop playback |
189
+ | `muted` | boolean | true | Muted (required for autoplay) |
190
+
191
+ 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.
152
192
 
153
- #### Per-Instance Resource Footprint (512x512 depth)
193
+ ### Transparent Background
154
194
 
155
- | Resource | Cost |
156
- |----------|------|
157
- | GPU textures | 2 (video texture + 262 KB depth texture) |
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) |
195
+ The portal canvas is fully transparent outside the logo shape. Overlay it on any background:
196
+
197
+ ```html
198
+ <div style="position: relative; background: #1a1a2e;">
199
+ <layershift-portal
200
+ src="video.mp4"
201
+ depth-src="depth-data.bin"
202
+ depth-meta="depth-meta.json"
203
+ logo-src="logo.svg"
204
+ style="position: absolute; inset: 0;"
205
+ autoplay loop muted
206
+ ></layershift-portal>
207
+ </div>
208
+ ```
209
+
210
+ ### Events
211
+
212
+ | Event | Detail | When |
213
+ |-------|--------|------|
214
+ | `layershift-portal:ready` | `{ videoWidth, videoHeight, duration }` | Initialization complete |
215
+ | `layershift-portal:play` | `{ currentTime }` | Video starts playing |
216
+ | `layershift-portal:pause` | `{ currentTime }` | Video pauses |
217
+ | `layershift-portal:loop` | `{ loopCount }` | Video loops back to start |
218
+ | `layershift-portal:frame` | `{ currentTime, frameNumber }` | New video frame presented |
219
+ | `layershift-portal:error` | `{ message }` | Initialization error |
220
+
221
+ ### SVG Requirements
222
+
223
+ 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.
164
224
 
165
225
  ---
166
226
 
167
- ## Controls
227
+ ## Frame-Level Sync
168
228
 
169
- - **Space** Play / pause video
229
+ Both effects use `requestVideoFrameCallback` (RVFC) when available to sync depth updates to actual video frame presentation:
230
+
231
+ - Depth work only runs when a new frame is decoded (~24–30fps)
232
+ - Parallax input stays smooth at display refresh rate (60–120fps)
233
+ - Frame events fire at true video frame rate
234
+ - Browsers without RVFC fall back to `requestAnimationFrame` automatically
235
+
236
+ ---
170
237
 
171
238
  ## Testing
172
239
 
@@ -181,14 +248,6 @@ npm run build && npm run build:component && npm run test:e2e
181
248
  npm run build && npm run build:component && npm run test:all
182
249
  ```
183
250
 
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
251
  ## License
193
252
 
194
253
  Business Source License 1.1 — see [LICENSE](./LICENSE) for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "layershift",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Embeddable video effects as Web Components. Drop-in parallax, depth-aware motion, and more.",
5
5
  "type": "module",
6
6
  "main": "dist/components/layershift.js",