layershift 0.1.0 → 0.1.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.
- package/README.md +1 -1
- package/dist/components/layershift.js +46 -4129
- package/dist/npm/layershift.es.js +623 -20575
- package/dist/types/components/layershift/layershift-element.d.ts +1 -1
- package/dist/types/parallax-renderer.d.ts +44 -66
- package/dist/types/parallax-renderer.d.ts.map +1 -1
- package/package.json +3 -6
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* <layershift-parallax> Web Component
|
|
3
3
|
*
|
|
4
4
|
* A self-contained Custom Element that renders a depth-aware parallax
|
|
5
|
-
* video effect. Encapsulates the entire
|
|
5
|
+
* video effect. Encapsulates the entire WebGL pipeline inside a
|
|
6
6
|
* Shadow DOM — consumers just drop in the tag and provide asset URLs.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Parallax Renderer — GPU-accelerated depth-aware video parallax.
|
|
3
3
|
*
|
|
4
|
-
* Renders a single
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* Renders a single fullscreen quad textured with the source video
|
|
5
|
+
* and a precomputed depth map using pure WebGL 2. A custom fragment
|
|
6
|
+
* shader displaces UV coordinates per-pixel based on the depth value
|
|
7
|
+
* and current mouse/gyro input, creating a continuous parallax effect
|
|
8
|
+
* with no discrete layer banding.
|
|
9
9
|
*
|
|
10
10
|
* ## Rendering pipeline (per frame)
|
|
11
11
|
*
|
|
12
|
-
* 1.
|
|
13
|
-
* providing the color frame at native
|
|
12
|
+
* 1. The video element's current frame is uploaded to the GPU via
|
|
13
|
+
* `gl.texImage2D`, providing the color frame at native resolution.
|
|
14
14
|
*
|
|
15
15
|
* 2. The depth interpolator produces a Uint8Array for the current
|
|
16
16
|
* playback time (interpolated between precomputed 5fps keyframes,
|
|
17
17
|
* bilateral-filtered on the CPU, then quantized to 0-255).
|
|
18
|
-
* This is copied into a single-channel
|
|
18
|
+
* This is copied into a single-channel R8 texture on the GPU.
|
|
19
19
|
*
|
|
20
20
|
* 3. The InputHandler provides a smoothed {x, y} offset in [-1, 1].
|
|
21
21
|
* This is passed to the shader as the uOffset uniform.
|
|
@@ -31,10 +31,8 @@
|
|
|
31
31
|
*
|
|
32
32
|
* ## Texture memory
|
|
33
33
|
*
|
|
34
|
-
* Only 2 textures per frame: 1
|
|
35
|
-
*
|
|
36
|
-
* only when depth changes at ~5fps). This is ~5× less bandwidth
|
|
37
|
-
* than the old 5-layer RGBA system.
|
|
34
|
+
* Only 2 textures per frame: 1 video texture (uploaded from HTMLVideoElement)
|
|
35
|
+
* + 1 depth texture (R8 format, uploaded only when depth changes at ~5fps).
|
|
38
36
|
*/
|
|
39
37
|
import type { ParallaxInput } from './input-handler';
|
|
40
38
|
/** Configuration subset relevant to the parallax renderer. */
|
|
@@ -59,13 +57,16 @@ export declare class ParallaxRenderer {
|
|
|
59
57
|
private static readonly RESIZE_DEBOUNCE_MS;
|
|
60
58
|
/** Compile-time upper bound for the POM for-loop in GLSL. */
|
|
61
59
|
private static readonly MAX_POM_STEPS;
|
|
62
|
-
private readonly
|
|
63
|
-
private
|
|
64
|
-
private
|
|
65
|
-
private
|
|
60
|
+
private readonly canvas;
|
|
61
|
+
private gl;
|
|
62
|
+
private program;
|
|
63
|
+
private uniforms;
|
|
64
|
+
private vao;
|
|
66
65
|
private videoTexture;
|
|
67
66
|
private depthTexture;
|
|
68
|
-
private
|
|
67
|
+
private readonly container;
|
|
68
|
+
private depthWidth;
|
|
69
|
+
private depthHeight;
|
|
69
70
|
private videoAspect;
|
|
70
71
|
private readDepth;
|
|
71
72
|
private readInput;
|
|
@@ -82,8 +83,10 @@ export declare class ParallaxRenderer {
|
|
|
82
83
|
private rvfcSupported;
|
|
83
84
|
private resizeObserver;
|
|
84
85
|
private resizeTimer;
|
|
85
|
-
private
|
|
86
|
-
private
|
|
86
|
+
private uvOffset;
|
|
87
|
+
private uvScale;
|
|
88
|
+
/** Resolved config with all optional shader params filled from defaults. */
|
|
89
|
+
private readonly config;
|
|
87
90
|
/**
|
|
88
91
|
* Create the renderer and attach its canvas to the DOM.
|
|
89
92
|
*
|
|
@@ -92,12 +95,10 @@ export declare class ParallaxRenderer {
|
|
|
92
95
|
* @param config - Parallax-specific settings (strength, POM, overscan).
|
|
93
96
|
* Optional shader parameters are merged with calibrated defaults.
|
|
94
97
|
*/
|
|
95
|
-
/** Resolved config with all optional shader params filled from defaults. */
|
|
96
|
-
private readonly config;
|
|
97
98
|
constructor(parent: HTMLElement, config: ParallaxRendererConfig);
|
|
98
99
|
/**
|
|
99
|
-
* Set up the scene: create
|
|
100
|
-
*
|
|
100
|
+
* Set up the scene: create video texture, depth texture, and set
|
|
101
|
+
* static shader uniforms.
|
|
101
102
|
*
|
|
102
103
|
* Call this once after the video element and depth data are loaded.
|
|
103
104
|
*
|
|
@@ -116,82 +117,59 @@ export declare class ParallaxRenderer {
|
|
|
116
117
|
*
|
|
117
118
|
* When RVFC is not available, falls back to a single RAF loop that
|
|
118
119
|
* does everything (the pre-RVFC behavior).
|
|
119
|
-
*
|
|
120
|
-
* @param readDepth - Called with the current video time.
|
|
121
|
-
* Returns a Uint8Array of depth values (0=near, 255=far) at the
|
|
122
|
-
* depth texture's resolution. The interpolator handles caching
|
|
123
|
-
* so redundant calls (same depth frame) return instantly.
|
|
124
|
-
* @param readInput - Returns the smoothed parallax input {x, y}
|
|
125
|
-
* in [-1, 1].
|
|
126
|
-
* @param onVideoFrame - Optional callback invoked on each new
|
|
127
|
-
* video frame. Receives the accurate media time and the
|
|
128
|
-
* browser's presented-frame counter.
|
|
129
120
|
*/
|
|
130
121
|
start(video: HTMLVideoElement, readDepth: (timeSec: number) => Uint8Array, readInput: () => ParallaxInput, onVideoFrame?: (currentTime: number, frameNumber: number) => void): void;
|
|
131
122
|
/** Stop both render loops and release callbacks. */
|
|
132
123
|
stop(): void;
|
|
133
124
|
/** Stop rendering and release all GPU resources. */
|
|
134
125
|
dispose(): void;
|
|
126
|
+
/** Create the shader program, fullscreen quad VAO, and cache uniform locations. */
|
|
127
|
+
private initGPUResources;
|
|
135
128
|
/** Check whether requestVideoFrameCallback is available. */
|
|
136
129
|
private static isRVFCSupported;
|
|
137
130
|
/**
|
|
138
131
|
* RVFC callback — fires only when the browser presents a new video frame.
|
|
139
132
|
*
|
|
140
|
-
* Handles the
|
|
133
|
+
* Handles the depth texture update, which only needs to happen
|
|
141
134
|
* when the video frame actually changes (~24-30fps, not 60-120fps).
|
|
142
|
-
*
|
|
143
|
-
* Uses `metadata.mediaTime` for more accurate depth reads than
|
|
144
|
-
* `video.currentTime` (which can lag behind the presented frame).
|
|
145
135
|
*/
|
|
146
136
|
private readonly videoFrameLoop;
|
|
147
137
|
/**
|
|
148
138
|
* Main render loop — called every animation frame at display refresh rate.
|
|
149
139
|
*
|
|
150
140
|
* When RVFC is active, this only handles:
|
|
151
|
-
* 1.
|
|
152
|
-
* 2.
|
|
153
|
-
*
|
|
154
|
-
* The depth texture is updated separately by videoFrameLoop at video
|
|
155
|
-
* frame rate. This separation means parallax stays smooth at 60/120fps
|
|
156
|
-
* even though depth only updates at 24-30fps.
|
|
141
|
+
* 1. Uploading the current video frame to the GPU texture.
|
|
142
|
+
* 2. Updating the parallax offset uniform from input (buttery smooth).
|
|
143
|
+
* 3. Rendering the fullscreen quad (single draw call).
|
|
157
144
|
*
|
|
158
145
|
* When RVFC is NOT supported, this falls back to the original behavior:
|
|
159
146
|
* depth update + input update + render all in a single RAF tick.
|
|
160
147
|
*/
|
|
161
148
|
private readonly renderLoop;
|
|
149
|
+
/** Upload fresh depth data to the GPU texture. */
|
|
150
|
+
private updateDepthTexture;
|
|
162
151
|
/**
|
|
163
152
|
* Set up a ResizeObserver on the container element and a fallback
|
|
164
|
-
* window resize listener.
|
|
165
|
-
* of the viewport layout, camera, and plane geometry.
|
|
153
|
+
* window resize listener.
|
|
166
154
|
*/
|
|
167
155
|
private setupResizeHandling;
|
|
168
156
|
/** Debounce resize events to avoid expensive layout recalculations. */
|
|
169
157
|
private readonly scheduleResizeRecalculate;
|
|
170
158
|
/**
|
|
171
|
-
* Recalculate the WebGL canvas size
|
|
172
|
-
*
|
|
159
|
+
* Recalculate the WebGL canvas size and UV transform to match the
|
|
160
|
+
* current container dimensions.
|
|
173
161
|
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* doesn't reveal the plane edges.
|
|
162
|
+
* Cover-fit + overscan is expressed as a UV-space transform (offset + scale)
|
|
163
|
+
* rather than geometry resize. The fullscreen quad stays fixed at -1 to 1.
|
|
177
164
|
*/
|
|
178
165
|
private recalculateViewportLayout;
|
|
179
|
-
/** Read the container's pixel dimensions, with a minimum of
|
|
166
|
+
/** Read the container's pixel dimensions, with a minimum of 1x1. */
|
|
180
167
|
private getViewportSize;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
* proportional to the parallax strength so that maximum displacement
|
|
188
|
-
* never reveals the plane edge.
|
|
189
|
-
*
|
|
190
|
-
* @returns planeWidth/planeHeight in world units (= pixels, since
|
|
191
|
-
* the camera is set up 1:1).
|
|
192
|
-
*/
|
|
193
|
-
private computeCoverPlaneSize;
|
|
194
|
-
/** Dispose the mesh, material, and textures from the scene. */
|
|
195
|
-
private disposeScene;
|
|
168
|
+
private readonly handleContextLost;
|
|
169
|
+
private readonly handleContextRestored;
|
|
170
|
+
/** Dispose textures only. */
|
|
171
|
+
private disposeTextures;
|
|
172
|
+
/** Dispose the shader program and VAO. */
|
|
173
|
+
private disposeGPUResources;
|
|
196
174
|
}
|
|
197
175
|
//# sourceMappingURL=parallax-renderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parallax-renderer.d.ts","sourceRoot":"","sources":["../../src/parallax-renderer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"parallax-renderer.d.ts","sourceRoot":"","sources":["../../src/parallax-renderer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "layershift",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.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",
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"video",
|
|
50
50
|
"depth",
|
|
51
51
|
"web-component",
|
|
52
|
-
"three.js",
|
|
53
52
|
"webgl",
|
|
53
|
+
"webgl2",
|
|
54
54
|
"depth-map",
|
|
55
55
|
"3d-effect"
|
|
56
56
|
],
|
|
@@ -60,10 +60,7 @@
|
|
|
60
60
|
"url": "https://github.com/jeremysykes/layershift/issues"
|
|
61
61
|
},
|
|
62
62
|
"homepage": "https://layershift.io",
|
|
63
|
-
"dependencies": {
|
|
64
|
-
"@types/three": "^0.182.0",
|
|
65
|
-
"three": "^0.182.0"
|
|
66
|
-
},
|
|
63
|
+
"dependencies": {},
|
|
67
64
|
"devDependencies": {
|
|
68
65
|
"@playwright/test": "^1.58.2",
|
|
69
66
|
"@vitest/browser": "^4.0.18",
|