zuljaman-banner-components 1.1.21 → 1.1.22
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWebGLRenderer.d.ts","sourceRoot":"","sources":["../../../../src/components/BannerRenderer/webgl/useWebGLRenderer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5E,MAAM,MAAM,eAAe,GACvB,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAC5C,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,gBAAgB,CAAC,EAAE,eAAe,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAwBD,wBAAgB,gBAAgB,IAAI,OAAO,CAgB1C;AA+HD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,EACpD,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM;;
|
|
1
|
+
{"version":3,"file":"useWebGLRenderer.d.ts","sourceRoot":"","sources":["../../../../src/components/BannerRenderer/webgl/useWebGLRenderer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5E,MAAM,MAAM,eAAe,GACvB,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAC5C,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,gBAAgB,CAAC,EAAE,eAAe,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAwBD,wBAAgB,gBAAgB,IAAI,OAAO,CAgB1C;AA+HD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,EACpD,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM;;EA6PrB"}
|
|
@@ -153,15 +153,22 @@ function useWebGLRenderer(canvasRef, imageUrl, effects, canvasWidth, canvasHeigh
|
|
|
153
153
|
const renderFrameRef = (0, react_1.useRef)(null);
|
|
154
154
|
const effectsRef = (0, react_1.useRef)(effects);
|
|
155
155
|
effectsRef.current = effects;
|
|
156
|
+
// Keep the latest imageUrl reachable from inside the init/restore handlers
|
|
157
|
+
// (which run outside the imageUrl effect's closure).
|
|
158
|
+
const imageUrlRef = (0, react_1.useRef)(imageUrl);
|
|
159
|
+
imageUrlRef.current = imageUrl;
|
|
156
160
|
// Track whether any effect needs animation (grain animated or refraction with animation)
|
|
157
161
|
const needsAnimation = effects.grainAnimated && (((_a = effects.grainIntensity) !== null && _a !== void 0 ? _a : 0) > 0 ||
|
|
158
162
|
((_b = effects.refractionIntensity) !== null && _b !== void 0 ? _b : 0) > 0);
|
|
159
163
|
// Load image as texture
|
|
160
|
-
const loadTexture = (0, react_1.useCallback)((
|
|
164
|
+
const loadTexture = (0, react_1.useCallback)((_gl, url) => {
|
|
161
165
|
const img = new Image();
|
|
162
166
|
img.crossOrigin = 'anonymous';
|
|
163
167
|
img.onload = () => {
|
|
164
|
-
|
|
168
|
+
// Re-read the current context — the one captured at call time may have
|
|
169
|
+
// been lost (and a new one restored) while the image was downloading.
|
|
170
|
+
const gl = glRef.current;
|
|
171
|
+
if (!gl)
|
|
165
172
|
return;
|
|
166
173
|
let texture = textureRef.current;
|
|
167
174
|
if (!texture) {
|
|
@@ -226,41 +233,92 @@ function useWebGLRenderer(canvasRef, imageUrl, effects, canvasWidth, canvasHeigh
|
|
|
226
233
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
227
234
|
}, []);
|
|
228
235
|
renderFrameRef.current = renderFrame;
|
|
229
|
-
// Initialize WebGL
|
|
236
|
+
// Initialize WebGL lazily.
|
|
237
|
+
//
|
|
238
|
+
// Defer context creation until the canvas enters the viewport, and also
|
|
239
|
+
// re-initialize when a previously-evicted context is needed again. Browsers
|
|
240
|
+
// cap simultaneous WebGL contexts per tab (~16 in Chrome) — pages that mount
|
|
241
|
+
// dozens of banners (e.g. the style gallery) would otherwise exhaust the
|
|
242
|
+
// pool and leave most canvases blank.
|
|
230
243
|
(0, react_1.useEffect)(() => {
|
|
231
244
|
const canvas = canvasRef.current;
|
|
232
245
|
if (!canvas)
|
|
233
246
|
return;
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
247
|
+
const initGL = () => {
|
|
248
|
+
if (glRef.current)
|
|
249
|
+
return true; // already initialized
|
|
250
|
+
const gl = canvas.getContext('webgl', {
|
|
251
|
+
alpha: false,
|
|
252
|
+
antialias: false,
|
|
253
|
+
premultipliedAlpha: false,
|
|
254
|
+
preserveDrawingBuffer: true, // Needed for toBlob() export
|
|
255
|
+
});
|
|
256
|
+
if (!gl) {
|
|
257
|
+
console.warn('WebGL not available, falling back to CSS rendering');
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
glRef.current = gl;
|
|
261
|
+
const program = createProgram(gl);
|
|
262
|
+
if (!program)
|
|
263
|
+
return false;
|
|
264
|
+
programRef.current = program;
|
|
265
|
+
gl.useProgram(program);
|
|
266
|
+
buffersRef.current = setupGeometry(gl, program);
|
|
267
|
+
uniformsRef.current = getUniformLocations(gl, program);
|
|
268
|
+
if (imageUrlRef.current) {
|
|
269
|
+
imageLoadedRef.current = false;
|
|
270
|
+
loadTexture(gl, imageUrlRef.current);
|
|
271
|
+
}
|
|
272
|
+
return true;
|
|
273
|
+
};
|
|
274
|
+
// preventDefault on 'webglcontextlost' is required for 'webglcontextrestored' to fire.
|
|
275
|
+
const handleContextLost = (e) => {
|
|
276
|
+
e.preventDefault();
|
|
277
|
+
glRef.current = null;
|
|
278
|
+
programRef.current = null;
|
|
279
|
+
uniformsRef.current = null;
|
|
280
|
+
textureRef.current = null;
|
|
281
|
+
buffersRef.current = null;
|
|
282
|
+
imageLoadedRef.current = false;
|
|
283
|
+
};
|
|
284
|
+
const handleContextRestored = () => {
|
|
285
|
+
initGL();
|
|
286
|
+
};
|
|
287
|
+
canvas.addEventListener('webglcontextlost', handleContextLost);
|
|
288
|
+
canvas.addEventListener('webglcontextrestored', handleContextRestored);
|
|
289
|
+
let observer = null;
|
|
290
|
+
if (typeof IntersectionObserver === 'undefined') {
|
|
291
|
+
initGL();
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
observer = new IntersectionObserver((entries) => {
|
|
295
|
+
for (const entry of entries) {
|
|
296
|
+
// Re-init whenever the canvas (re)enters view and lacks a live
|
|
297
|
+
// context — covers both first appearance and contexts that were
|
|
298
|
+
// silently dropped while offscreen.
|
|
299
|
+
if (entry.isIntersecting && !glRef.current)
|
|
300
|
+
initGL();
|
|
301
|
+
}
|
|
302
|
+
}, { rootMargin: '200px' });
|
|
303
|
+
observer.observe(canvas);
|
|
243
304
|
}
|
|
244
|
-
glRef.current = gl;
|
|
245
|
-
const program = createProgram(gl);
|
|
246
|
-
if (!program)
|
|
247
|
-
return;
|
|
248
|
-
programRef.current = program;
|
|
249
|
-
gl.useProgram(program);
|
|
250
|
-
buffersRef.current = setupGeometry(gl, program);
|
|
251
|
-
uniformsRef.current = getUniformLocations(gl, program);
|
|
252
305
|
return () => {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
306
|
+
observer === null || observer === void 0 ? void 0 : observer.disconnect();
|
|
307
|
+
canvas.removeEventListener('webglcontextlost', handleContextLost);
|
|
308
|
+
canvas.removeEventListener('webglcontextrestored', handleContextRestored);
|
|
309
|
+
const gl = glRef.current;
|
|
310
|
+
if (gl) {
|
|
311
|
+
if (textureRef.current)
|
|
312
|
+
gl.deleteTexture(textureRef.current);
|
|
313
|
+
if (buffersRef.current) {
|
|
314
|
+
if (buffersRef.current.positionBuffer)
|
|
315
|
+
gl.deleteBuffer(buffersRef.current.positionBuffer);
|
|
316
|
+
if (buffersRef.current.texCoordBuffer)
|
|
317
|
+
gl.deleteBuffer(buffersRef.current.texCoordBuffer);
|
|
318
|
+
}
|
|
319
|
+
if (programRef.current)
|
|
320
|
+
gl.deleteProgram(programRef.current);
|
|
261
321
|
}
|
|
262
|
-
if (programRef.current)
|
|
263
|
-
gl.deleteProgram(programRef.current);
|
|
264
322
|
textureRef.current = null;
|
|
265
323
|
buffersRef.current = null;
|
|
266
324
|
programRef.current = null;
|