@razorpay/blade 12.92.0 → 12.93.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.
Files changed (112) hide show
  1. package/assets/spark/bottom-frame.jpg +0 -0
  2. package/assets/spark/colorama-center-gradient-map.jpg +0 -0
  3. package/assets/spark/colorama-gradient-map-blue.jpg +0 -0
  4. package/assets/spark/colorama-gradient-map-green.jpg +0 -0
  5. package/assets/spark/ray-pulse.mp4 +0 -0
  6. package/assets/spark/spark-base-video.mp4 +0 -0
  7. package/assets/spark/success-animation-circle.mp4 +0 -0
  8. package/build/lib/native/components/Spark/RazorSenseGradient/FluidGradient.js +9 -0
  9. package/build/lib/native/components/Spark/RazorSenseGradient/FluidGradient.js.map +1 -0
  10. package/build/lib/native/components/Spark/RazorSenseGradient/FluidGradientMount.js +18 -0
  11. package/build/lib/native/components/Spark/RazorSenseGradient/FluidGradientMount.js.map +1 -0
  12. package/build/lib/native/components/Spark/RazorSenseGradient/shader.js +69 -0
  13. package/build/lib/native/components/Spark/RazorSenseGradient/shader.js.map +1 -0
  14. package/build/lib/native/components/Spark/RazorSenseGradient/useFluidGradient.js +7 -0
  15. package/build/lib/native/components/Spark/RazorSenseGradient/useFluidGradient.js.map +1 -0
  16. package/build/lib/native/components/Spark/RzpGlass/PerformanceManager.js +7 -0
  17. package/build/lib/native/components/Spark/RzpGlass/PerformanceManager.js.map +1 -0
  18. package/build/lib/native/components/Spark/RzpGlass/RzpGlass.js +13 -0
  19. package/build/lib/native/components/Spark/RzpGlass/RzpGlass.js.map +1 -0
  20. package/build/lib/native/components/Spark/RzpGlass/RzpGlassMount.js +28 -0
  21. package/build/lib/native/components/Spark/RzpGlass/RzpGlassMount.js.map +1 -0
  22. package/build/lib/native/components/Spark/RzpGlass/presets.js +4 -0
  23. package/build/lib/native/components/Spark/RzpGlass/presets.js.map +1 -0
  24. package/build/lib/native/components/Spark/RzpGlass/rzpGlassShader.js +920 -0
  25. package/build/lib/native/components/Spark/RzpGlass/rzpGlassShader.js.map +1 -0
  26. package/build/lib/native/components/Spark/RzpGlass/utils.js +4 -0
  27. package/build/lib/native/components/Spark/RzpGlass/utils.js.map +1 -0
  28. package/build/lib/native/components/Spark/RzpGlass/webgl-utils.js +7 -0
  29. package/build/lib/native/components/Spark/RzpGlass/webgl-utils.js.map +1 -0
  30. package/build/lib/native/components/index.js +2 -0
  31. package/build/lib/native/components/index.js.map +1 -1
  32. package/build/lib/web/development/_virtual/flatten.js +1 -1
  33. package/build/lib/web/development/_virtual/flatten3.js +1 -1
  34. package/build/lib/web/development/components/Dropdown/FilterChipSelectInput.web.js +23 -15
  35. package/build/lib/web/development/components/Dropdown/FilterChipSelectInput.web.js.map +1 -1
  36. package/build/lib/web/development/components/SideNav/SideNav.web.js +21 -21
  37. package/build/lib/web/development/components/SideNav/SideNav.web.js.map +1 -1
  38. package/build/lib/web/development/components/SideNav/SideNavItems/SideNavLink.web.js +4 -4
  39. package/build/lib/web/development/components/SideNav/SideNavItems/SideNavLink.web.js.map +1 -1
  40. package/build/lib/web/development/components/Spark/RazorSenseGradient/FluidGradient.js +92 -0
  41. package/build/lib/web/development/components/Spark/RazorSenseGradient/FluidGradient.js.map +1 -0
  42. package/build/lib/web/development/components/Spark/RazorSenseGradient/FluidGradientMount.js +110 -0
  43. package/build/lib/web/development/components/Spark/RazorSenseGradient/FluidGradientMount.js.map +1 -0
  44. package/build/lib/web/development/components/Spark/RazorSenseGradient/index.js +2 -0
  45. package/build/lib/web/development/components/Spark/RazorSenseGradient/index.js.map +1 -0
  46. package/build/lib/web/development/components/Spark/RazorSenseGradient/shader.js +18 -0
  47. package/build/lib/web/development/components/Spark/RazorSenseGradient/shader.js.map +1 -0
  48. package/build/lib/web/development/components/Spark/RazorSenseGradient/useFluidGradient.js +34 -0
  49. package/build/lib/web/development/components/Spark/RazorSenseGradient/useFluidGradient.js.map +1 -0
  50. package/build/lib/web/development/components/Spark/RzpGlass/PerformanceManager.js +455 -0
  51. package/build/lib/web/development/components/Spark/RzpGlass/PerformanceManager.js.map +1 -0
  52. package/build/lib/web/development/components/Spark/RzpGlass/RzpGlass.js +263 -0
  53. package/build/lib/web/development/components/Spark/RzpGlass/RzpGlass.js.map +1 -0
  54. package/build/lib/web/development/components/Spark/RzpGlass/RzpGlassMount.js +908 -0
  55. package/build/lib/web/development/components/Spark/RzpGlass/RzpGlassMount.js.map +1 -0
  56. package/build/lib/web/development/components/Spark/RzpGlass/index.js +24 -0
  57. package/build/lib/web/development/components/Spark/RzpGlass/index.js.map +1 -0
  58. package/build/lib/web/development/components/Spark/RzpGlass/presets.js +151 -0
  59. package/build/lib/web/development/components/Spark/RzpGlass/presets.js.map +1 -0
  60. package/build/lib/web/development/components/Spark/RzpGlass/rzpGlassShader.js +5 -0
  61. package/build/lib/web/development/components/Spark/RzpGlass/rzpGlassShader.js.map +1 -0
  62. package/build/lib/web/development/components/Spark/RzpGlass/utils.js +77 -0
  63. package/build/lib/web/development/components/Spark/RzpGlass/utils.js.map +1 -0
  64. package/build/lib/web/development/components/Spark/RzpGlass/webgl-utils.js +200 -0
  65. package/build/lib/web/development/components/Spark/RzpGlass/webgl-utils.js.map +1 -0
  66. package/build/lib/web/development/components/Spark/index.js +3 -0
  67. package/build/lib/web/development/components/Spark/index.js.map +1 -0
  68. package/build/lib/web/development/components/index.js +3 -0
  69. package/build/lib/web/development/components/index.js.map +1 -1
  70. package/build/lib/web/development/node_modules/es-toolkit/dist/array/flatten.js +1 -1
  71. package/build/lib/web/development/node_modules/es-toolkit/dist/compat/array/flatten.js +1 -1
  72. package/build/lib/web/development/node_modules/es-toolkit/dist/compat/array/sortBy.js +2 -2
  73. package/build/lib/web/development/node_modules/es-toolkit/dist/compat/object/omit.js +2 -2
  74. package/build/lib/web/production/components/Dropdown/FilterChipSelectInput.web.js +23 -15
  75. package/build/lib/web/production/components/Dropdown/FilterChipSelectInput.web.js.map +1 -1
  76. package/build/lib/web/production/components/SideNav/SideNav.web.js +21 -21
  77. package/build/lib/web/production/components/SideNav/SideNav.web.js.map +1 -1
  78. package/build/lib/web/production/components/SideNav/SideNavItems/SideNavLink.web.js +4 -4
  79. package/build/lib/web/production/components/SideNav/SideNavItems/SideNavLink.web.js.map +1 -1
  80. package/build/lib/web/production/components/Spark/RazorSenseGradient/FluidGradient.js +92 -0
  81. package/build/lib/web/production/components/Spark/RazorSenseGradient/FluidGradient.js.map +1 -0
  82. package/build/lib/web/production/components/Spark/RazorSenseGradient/FluidGradientMount.js +110 -0
  83. package/build/lib/web/production/components/Spark/RazorSenseGradient/FluidGradientMount.js.map +1 -0
  84. package/build/lib/web/production/components/Spark/RazorSenseGradient/index.js +2 -0
  85. package/build/lib/web/production/components/Spark/RazorSenseGradient/index.js.map +1 -0
  86. package/build/lib/web/production/components/Spark/RazorSenseGradient/shader.js +18 -0
  87. package/build/lib/web/production/components/Spark/RazorSenseGradient/shader.js.map +1 -0
  88. package/build/lib/web/production/components/Spark/RazorSenseGradient/useFluidGradient.js +34 -0
  89. package/build/lib/web/production/components/Spark/RazorSenseGradient/useFluidGradient.js.map +1 -0
  90. package/build/lib/web/production/components/Spark/RzpGlass/PerformanceManager.js +455 -0
  91. package/build/lib/web/production/components/Spark/RzpGlass/PerformanceManager.js.map +1 -0
  92. package/build/lib/web/production/components/Spark/RzpGlass/RzpGlass.js +263 -0
  93. package/build/lib/web/production/components/Spark/RzpGlass/RzpGlass.js.map +1 -0
  94. package/build/lib/web/production/components/Spark/RzpGlass/RzpGlassMount.js +908 -0
  95. package/build/lib/web/production/components/Spark/RzpGlass/RzpGlassMount.js.map +1 -0
  96. package/build/lib/web/production/components/Spark/RzpGlass/index.js +24 -0
  97. package/build/lib/web/production/components/Spark/RzpGlass/index.js.map +1 -0
  98. package/build/lib/web/production/components/Spark/RzpGlass/presets.js +151 -0
  99. package/build/lib/web/production/components/Spark/RzpGlass/presets.js.map +1 -0
  100. package/build/lib/web/production/components/Spark/RzpGlass/rzpGlassShader.js +5 -0
  101. package/build/lib/web/production/components/Spark/RzpGlass/rzpGlassShader.js.map +1 -0
  102. package/build/lib/web/production/components/Spark/RzpGlass/utils.js +77 -0
  103. package/build/lib/web/production/components/Spark/RzpGlass/utils.js.map +1 -0
  104. package/build/lib/web/production/components/Spark/RzpGlass/webgl-utils.js +200 -0
  105. package/build/lib/web/production/components/Spark/RzpGlass/webgl-utils.js.map +1 -0
  106. package/build/lib/web/production/components/Spark/index.js +3 -0
  107. package/build/lib/web/production/components/Spark/index.js.map +1 -0
  108. package/build/lib/web/production/components/index.js +3 -0
  109. package/build/lib/web/production/components/index.js.map +1 -1
  110. package/build/types/components/index.d.ts +297 -1
  111. package/build/types/components/index.native.d.ts +297 -1
  112. package/package.json +2 -1
@@ -0,0 +1,908 @@
1
+ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
2
+ import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
3
+ import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
4
+ import _createClass from '@babel/runtime/helpers/createClass';
5
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
6
+ import _regeneratorRuntime from '@babel/runtime/regenerator';
7
+ import { rzpGlassVertexShader, rzpGlassFragmentShader } from './rzpGlassShader.js';
8
+ import { DEFAULT_CONFIG } from './presets.js';
9
+ import { isSafari, bestGuessBrowserZoom, loadImage, loadVideo } from './utils.js';
10
+ import { createProgram, setupFullscreenQuad, Texture } from './webgl-utils.js';
11
+ import { LEVEL_RENDER_SETTINGS, WebGLPerformanceController } from './PerformanceManager.js';
12
+
13
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
+ // Reference resolution for zoom-independent displacement
16
+ var REF_RESOLUTION = {
17
+ width: 3000,
18
+ height: 2000
19
+ };
20
+
21
+ // Default max pixel count (1920 * 1080 * 4 = 8,294,400 pixels)
22
+ var DEFAULT_MAX_PIXEL_COUNT = 1920 * 1080 * 4;
23
+
24
+ // Default styles for the shader container
25
+ var defaultStyle = "@layer rzp-glass {\n :where([data-rzp-glass]) {\n isolation: isolate;\n position: relative;\n overflow: hidden;\n\n & canvas {\n contain: strict;\n display: block;\n position: absolute;\n z-index: -1;\n border-radius: inherit;\n }\n }\n}";
26
+
27
+ /** Map of config keys to uniform names */
28
+ var CONFIG_TO_UNIFORM = {
29
+ enableDisplacement: 'uEnableDisplacement',
30
+ enableColorama: 'uEnableColorama',
31
+ enableBloom: 'uEnableBloom',
32
+ enableLightSweep: 'uEnableLightSweep',
33
+ inputMin: 'uInputMin',
34
+ inputMax: 'uInputMax',
35
+ modifyGamma: 'uModifyGamma',
36
+ posterizeLevels: 'uPosterizeLevels',
37
+ cycleRepetitions: 'uCycleRepetitions',
38
+ phaseShift: 'uPhaseShift',
39
+ cycleSpeed: 'uCycleSpeed',
40
+ wrapMode: 'uWrapMode',
41
+ reverse: 'uReverse',
42
+ blendWithOriginal: 'uBlendWithOriginal',
43
+ lightIntensity: 'uLightIntensity',
44
+ lightStartFrame: 'uLightStartFrame',
45
+ numSegments: 'uNumSegments',
46
+ slitAngle: 'uSlitAngle',
47
+ displacementX: 'uDisplacementX',
48
+ displacementY: 'uDisplacementY',
49
+ enableCenterElement: 'uEnableCenterElement',
50
+ centerAnimDuration: 'uCenterAnimDuration',
51
+ ccBlackPoint: 'uCCBlackPoint',
52
+ ccWhitePoint: 'uCCWhitePoint',
53
+ ccMidtoneGamma: 'uCCMidtoneGamma',
54
+ ccGamma: 'uCCGamma',
55
+ ccContrast: 'uCCContrast',
56
+ zoom: 'uZoom',
57
+ // panX and panY are combined into uPan (vec2) in setUniformValues
58
+ // backgroundColor is handled separately (needs clear color update)
59
+ edgeFeather: 'uEdgeFeather'
60
+ };
61
+ var RzpGlassMount = /*#__PURE__*/function () {
62
+ function RzpGlassMount(parentElement, assets) {
63
+ var _this = this,
64
+ _visualViewport2;
65
+ var config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
66
+ var frame = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
67
+ var _minPixelRatio = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
68
+ var _maxPixelCount = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : DEFAULT_MAX_PIXEL_COUNT;
69
+ _classCallCheck(this, RzpGlassMount);
70
+ _defineProperty(this, "program", null);
71
+ _defineProperty(this, "uniformLocations", {});
72
+ _defineProperty(this, "uniformCache", {});
73
+ // Textures
74
+ _defineProperty(this, "videoTexture", null);
75
+ _defineProperty(this, "gradientMapTexture", null);
76
+ _defineProperty(this, "gradientMap2Texture", null);
77
+ _defineProperty(this, "centerGradientMapTexture", null);
78
+ // Gradient map blend animation state
79
+ _defineProperty(this, "currentGradientMapBlend", 0);
80
+ // Video element
81
+ _defineProperty(this, "video", null);
82
+ _defineProperty(this, "videoFrameCallbackId", null);
83
+ // Animation state (paper-shader style)
84
+ _defineProperty(this, "rafId", null);
85
+ /** Last render time in seconds */
86
+ _defineProperty(this, "lastRenderTime", 0);
87
+ /** Frame count (increments every frame) */
88
+ _defineProperty(this, "currentFrame", 0);
89
+ // Video-specific animation state
90
+ /** Time for independent light animation (accumulates deltaTime) */
91
+ _defineProperty(this, "independentLightTime", 0);
92
+ /** Last video animation time (for detecting jumps) */
93
+ _defineProperty(this, "lastVideoTime", 0);
94
+ // State flags
95
+ _defineProperty(this, "hasBeenDisposed", false);
96
+ _defineProperty(this, "isInitialized", false);
97
+ _defineProperty(this, "resolutionChanged", true);
98
+ // Visible UV bounds (where container clips the canvas)
99
+ // vec4(minX, minY, maxX, maxY) - portion of canvas UV that's visible
100
+ _defineProperty(this, "visibleUvBounds", [0, 0, 1, 1]);
101
+ // Resize handling
102
+ _defineProperty(this, "resizeObserver", null);
103
+ _defineProperty(this, "renderScale", 1);
104
+ _defineProperty(this, "parentWidth", 0);
105
+ _defineProperty(this, "parentHeight", 0);
106
+ _defineProperty(this, "parentDevicePixelWidth", 0);
107
+ _defineProperty(this, "parentDevicePixelHeight", 0);
108
+ _defineProperty(this, "devicePixelsSupported", false);
109
+ _defineProperty(this, "isSafariBrowser", isSafari());
110
+ // Performance monitoring
111
+ _defineProperty(this, "performanceController", null);
112
+ _defineProperty(this, "handleVisualViewportChange", function () {
113
+ var _this$resizeObserver;
114
+ // Restart resize observer to get fresh callback on zoom change
115
+ (_this$resizeObserver = _this.resizeObserver) === null || _this$resizeObserver === void 0 || _this$resizeObserver.disconnect();
116
+ _this.setupResizeObserver();
117
+ });
118
+ _defineProperty(this, "handleResize", function () {
119
+ var _visualViewport$scale, _visualViewport;
120
+ // Container dimensions (use stored values or fallback to clientWidth/Height)
121
+ var containerWidth = _this.parentWidth || _this.parentElement.clientWidth;
122
+ var containerHeight = _this.parentHeight || _this.parentElement.clientHeight;
123
+ var containerAspect = containerWidth / containerHeight;
124
+
125
+ // "Cover" behavior: fill container while maintaining aspect ratio (crop overflow)
126
+ var canvasWidth;
127
+ var canvasHeight;
128
+ var targetAspectRatio = _this.config.aspectRatio;
129
+ if (containerAspect > targetAspectRatio) {
130
+ // Container is wider than target - fit to width, crop top/bottom
131
+ canvasWidth = containerWidth;
132
+ canvasHeight = containerWidth / targetAspectRatio;
133
+ } else {
134
+ // Container is taller than target - fit to height, crop left/right
135
+ canvasHeight = containerHeight;
136
+ canvasWidth = containerHeight * targetAspectRatio;
137
+ }
138
+
139
+ // Center the canvas (overflow will be hidden by parent)
140
+ var offsetX = (containerWidth - canvasWidth) / 2;
141
+ var offsetY = (containerHeight - canvasHeight) / 2;
142
+
143
+ // Calculate visible UV bounds (where container clips the canvas)
144
+ // When canvas overflows container, we need to know which portion is visible
145
+ var visibleMinX = -offsetX / canvasWidth;
146
+ var visibleMaxX = (containerWidth - offsetX) / canvasWidth;
147
+ var visibleMinY = -offsetY / canvasHeight;
148
+ var visibleMaxY = (containerHeight - offsetY) / canvasHeight;
149
+ _this.visibleUvBounds = [visibleMinX, visibleMinY, visibleMaxX, visibleMaxY];
150
+
151
+ // Set display size (CSS pixels)
152
+ _this.canvasElement.style.width = "".concat(canvasWidth, "px");
153
+ _this.canvasElement.style.height = "".concat(canvasHeight, "px");
154
+ _this.canvasElement.style.left = "".concat(offsetX, "px");
155
+ _this.canvasElement.style.top = "".concat(offsetY, "px");
156
+
157
+ // Calculate target pixel dimensions for rendering
158
+ var targetPixelWidth = 0;
159
+ var targetPixelHeight = 0;
160
+ var dpr = Math.max(1, window.devicePixelRatio);
161
+ var pinchZoom = (_visualViewport$scale = (_visualViewport = visualViewport) === null || _visualViewport === void 0 ? void 0 : _visualViewport.scale) !== null && _visualViewport$scale !== void 0 ? _visualViewport$scale : 1;
162
+ if (_this.devicePixelsSupported) {
163
+ // Use real pixel size if we know it, but maintain aspect ratio
164
+ // Calculate the scale ratio from parent to canvas (for aspect ratio correction)
165
+ var canvasToParentRatioX = canvasWidth / containerWidth;
166
+ var canvasToParentRatioY = canvasHeight / containerHeight;
167
+ var scaleToMeetMinPixelRatio = Math.max(1, _this.minPixelRatio / dpr);
168
+ // Apply aspect ratio correction to device pixel dimensions
169
+ targetPixelWidth = _this.parentDevicePixelWidth * canvasToParentRatioX * scaleToMeetMinPixelRatio * pinchZoom;
170
+ targetPixelHeight = _this.parentDevicePixelHeight * canvasToParentRatioY * scaleToMeetMinPixelRatio * pinchZoom;
171
+ } else {
172
+ // Approximate using devicePixelRatio
173
+ var targetRenderScale = Math.max(dpr, _this.minPixelRatio) * pinchZoom;
174
+ if (_this.isSafariBrowser) {
175
+ // Safari reports physical devicePixelRatio, need to factor in zoom manually
176
+ var zoomLevel = bestGuessBrowserZoom();
177
+ targetRenderScale *= Math.max(1, zoomLevel);
178
+ }
179
+ targetPixelWidth = Math.round(canvasWidth) * targetRenderScale;
180
+ targetPixelHeight = Math.round(canvasHeight) * targetRenderScale;
181
+ }
182
+
183
+ // Prevent total rendered pixels from exceeding maxPixelCount
184
+ var maxPixelCountHeadroom = Math.sqrt(_this.maxPixelCount) / Math.sqrt(targetPixelWidth * targetPixelHeight);
185
+ var scaleToMeetMaxPixelCount = Math.min(1, maxPixelCountHeadroom);
186
+ var newWidth = Math.round(targetPixelWidth * scaleToMeetMaxPixelCount);
187
+ var newHeight = Math.round(targetPixelHeight * scaleToMeetMaxPixelCount);
188
+ var newRenderScale = newWidth / Math.round(canvasWidth);
189
+ if (_this.canvasElement.width !== newWidth || _this.canvasElement.height !== newHeight || _this.renderScale !== newRenderScale) {
190
+ _this.renderScale = newRenderScale;
191
+ _this.canvasElement.width = newWidth;
192
+ _this.canvasElement.height = newHeight;
193
+ _this.resolutionChanged = true;
194
+ _this.gl.viewport(0, 0, newWidth, newHeight);
195
+
196
+ // Only render immediately when the loop isn't running — if it is,
197
+ // resolutionChanged=true is enough and the next RAF picks it up.
198
+ // Calling render() while the loop is active spawns a duplicate RAF chain.
199
+ if (_this.rafId === null) {
200
+ _this.render(performance.now());
201
+ }
202
+ }
203
+ });
204
+ _defineProperty(this, "handleDocumentVisibilityChange", function () {
205
+ if (document.hidden) {
206
+ var _this$video;
207
+ // Pause render loop when tab is hidden
208
+ _this.stopRenderLoop();
209
+ (_this$video = _this.video) === null || _this$video === void 0 || _this$video.pause();
210
+ } else {
211
+ // Resume render loop when tab is visible
212
+ _this.startRenderLoop();
213
+ // Only resume video if not paused
214
+ if (!_this.config.paused) {
215
+ var _this$video2;
216
+ (_this$video2 = _this.video) === null || _this$video2 === void 0 || _this$video2.play()["catch"](function () {});
217
+ }
218
+ }
219
+ });
220
+ _defineProperty(this, "render", function (currentTime) {
221
+ if (_this.hasBeenDisposed) return;
222
+
223
+ // ALWAYS schedule next frame first (like the original loop)
224
+ _this.rafId = requestAnimationFrame(_this.render);
225
+ if (_this.program === null) {
226
+ console.warn('Tried to render before program was initialized');
227
+ return;
228
+ }
229
+ var gl = _this.gl;
230
+ var video = _this.video;
231
+
232
+ // Always clear canvas to transparent (even before video is ready)
233
+ gl.clear(gl.COLOR_BUFFER_BIT);
234
+
235
+ // Calculate delta time in seconds (framerate independent)
236
+ var currentTimeSeconds = currentTime * 0.001; // Convert ms to seconds
237
+ var deltaTime = currentTimeSeconds - _this.lastRenderTime;
238
+ _this.lastRenderTime = currentTimeSeconds;
239
+ _this.currentFrame++; // Increment frame count every frame
240
+
241
+ var usingStaticImage = !video && _this.videoTexture !== null;
242
+
243
+ // Skip rendering if video isn't ready (canvas stays transparent).
244
+ // Static-image mode bypasses this guard since there's no video element.
245
+ if (!usingStaticImage) {
246
+ if (!video || video.readyState < video.HAVE_CURRENT_DATA) {
247
+ return;
248
+ }
249
+
250
+ // Update video texture (fallback for browsers without requestVideoFrameCallback)
251
+ if (!('requestVideoFrameCallback' in video) && _this.videoTexture) {
252
+ _this.videoTexture.update(video);
253
+ }
254
+
255
+ // Handle video looping within start/end time range (only when not paused)
256
+ if (!_this.config.paused) {
257
+ if (video.currentTime < _this.config.startTime || video.currentTime >= _this.config.endTime) {
258
+ video.currentTime = _this.config.startTime;
259
+ }
260
+ }
261
+ }
262
+
263
+ // Animation time: driven by video position for video mode, real elapsed time for static image
264
+ var videoAnimTime = usingStaticImage ? currentTimeSeconds : video.currentTime - _this.config.startTime;
265
+
266
+ // Update center animation time (always accumulate real time for smooth animation)
267
+ if (_this.config.animateLightIndependently || usingStaticImage) {
268
+ _this.independentLightTime += deltaTime;
269
+ } else {
270
+ var videoTimeDelta = videoAnimTime - _this.lastVideoTime;
271
+ var isVideoJump = Math.abs(videoTimeDelta) > 0.1 || videoTimeDelta < -0.01;
272
+ if (isVideoJump) {
273
+ _this.independentLightTime = videoAnimTime;
274
+ } else {
275
+ _this.independentLightTime += deltaTime;
276
+ }
277
+ }
278
+ _this.lastVideoTime = videoAnimTime;
279
+
280
+ // Use program and set per-frame uniforms
281
+ gl.useProgram(_this.program);
282
+
283
+ // Time uniforms
284
+ gl.uniform1f(_this.uniformLocations.uTime, currentTimeSeconds);
285
+ // When animateLightIndependently is true, use real elapsed time for frame count
286
+ // so light effects aren't tied to video playback
287
+ var frameCount = _this.config.animateLightIndependently ? _this.independentLightTime * 30 // Use independent time (in seconds * 30fps)
288
+ : videoAnimTime * 30; // Use video time (in seconds * 30fps)
289
+ gl.uniform1f(_this.uniformLocations.uFrameCount, frameCount);
290
+ gl.uniform1f(_this.uniformLocations.uCenterAnimTime, _this.independentLightTime);
291
+
292
+ // Resolution uniforms (only when changed)
293
+ if (_this.resolutionChanged) {
294
+ gl.uniform2f(_this.uniformLocations.iResolution, _this.canvasElement.width, _this.canvasElement.height);
295
+ gl.uniform1f(_this.uniformLocations.uDpr, _this.renderScale);
296
+ // Update visible UV bounds (where container clips the canvas)
297
+ gl.uniform4f(_this.uniformLocations.uVisibleUvBounds, _this.visibleUvBounds[0], _this.visibleUvBounds[1], _this.visibleUvBounds[2], _this.visibleUvBounds[3]);
298
+ _this.resolutionChanged = false;
299
+ }
300
+
301
+ // Animate cycleRepetitions if enabled
302
+ if (_this.config.animateCycleReps && _this.currentFrame > _this.config.cycleRepetitionsStartFrame) {
303
+ var elapsed = _this.currentFrame - _this.config.cycleRepetitionsStartFrame;
304
+ var cycleProgress = elapsed % (_this.config.cycleRepetitionsDuration * 2) / _this.config.cycleRepetitionsDuration;
305
+ var pingPong = cycleProgress <= 1 ? cycleProgress : 2 - cycleProgress;
306
+ var eased = pingPong * pingPong * (3 - 2 * pingPong); // smoothstep
307
+ var delta = _this.config.cycleRepetitionsEnd - _this.config.cycleRepetitionsStart;
308
+ gl.uniform1f(_this.uniformLocations.uCycleRepetitions, _this.config.cycleRepetitionsStart + eased * delta);
309
+ } else {
310
+ gl.uniform1f(_this.uniformLocations.uCycleRepetitions, _this.config.cycleRepetitions);
311
+ }
312
+
313
+ // Animate gradientMapBlend smoothly towards target
314
+ var targetBlend = _this.config.gradientMapBlend;
315
+ if (_this.currentGradientMapBlend !== targetBlend) {
316
+ var speed = 1.0 / _this.config.gradientMapBlendDuration;
317
+ var diff = targetBlend - _this.currentGradientMapBlend;
318
+ var step = Math.sign(diff) * Math.min(Math.abs(diff), speed * deltaTime);
319
+ _this.currentGradientMapBlend += step;
320
+ gl.uniform1f(_this.uniformLocations.uGradientMapBlend, _this.currentGradientMapBlend);
321
+ }
322
+
323
+ // Draw
324
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
325
+ });
326
+ _defineProperty(this, "handlePerformanceLevelChange", function (level) {
327
+ if (level === 0) {
328
+ _this.stopRenderLoop();
329
+ _this.canvasElement.style.display = 'none';
330
+ return;
331
+ }
332
+ var _LEVEL_RENDER_SETTING = LEVEL_RENDER_SETTINGS[level],
333
+ maxPixelCount = _LEVEL_RENDER_SETTING.maxPixelCount,
334
+ minPixelRatio = _LEVEL_RENDER_SETTING.minPixelRatio;
335
+ _this.maxPixelCount = maxPixelCount;
336
+ _this.minPixelRatio = minPixelRatio;
337
+
338
+ // Restore canvas + render loop if they were previously hidden/stopped
339
+ if (_this.canvasElement.style.display === 'none') {
340
+ _this.canvasElement.style.display = '';
341
+ }
342
+ if (_this.isInitialized) {
343
+ _this.startRenderLoop();
344
+ }
345
+ _this.handleResize();
346
+ });
347
+ this.parentElement = parentElement;
348
+ this.assets = assets;
349
+ this.config = _objectSpread(_objectSpread({}, DEFAULT_CONFIG), config);
350
+ this.currentFrame = frame;
351
+ this.minPixelRatio = _minPixelRatio;
352
+ this.maxPixelCount = _maxPixelCount;
353
+
354
+ // Inject default styles if not already present
355
+ if (!document.querySelector('style[data-rzp-glass-style]')) {
356
+ var styleElement = document.createElement('style');
357
+ styleElement.innerHTML = defaultStyle;
358
+ styleElement.setAttribute('data-rzp-glass-style', '');
359
+ document.head.prepend(styleElement);
360
+ }
361
+
362
+ // Create canvas element
363
+ this.canvasElement = document.createElement('canvas');
364
+ this.parentElement.prepend(this.canvasElement);
365
+ this.parentElement.setAttribute('data-rzp-glass', '');
366
+
367
+ // Get WebGL context with alpha for transparency during loading
368
+ var _gl = this.canvasElement.getContext('webgl', {
369
+ antialias: false,
370
+ premultipliedAlpha: false,
371
+ depth: false,
372
+ alpha: true,
373
+ powerPreference: 'high-performance'
374
+ });
375
+ this.gl = _gl;
376
+ this.performanceController = new WebGLPerformanceController({
377
+ gl: this.gl,
378
+ onLevelChange: this.handlePerformanceLevelChange
379
+ });
380
+ this.stopIfPotato();
381
+
382
+ // Flip Y axis when uploading textures (video/images have Y=0 at top, WebGL has Y=0 at bottom)
383
+ _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, true);
384
+
385
+ // WebGL state setup (matching OGL defaults for 2D rendering)
386
+ _gl.disable(_gl.DEPTH_TEST);
387
+ _gl.disable(_gl.CULL_FACE);
388
+
389
+ // Set clear color to transparent (for alpha blending during loading)
390
+ _gl.clearColor(0, 0, 0, 0);
391
+
392
+ // Initialize program
393
+ this.initProgram();
394
+ this.setupPositionAttribute();
395
+ this.setupUniformLocations();
396
+ this.setupResizeObserver();
397
+
398
+ // Visual viewport listener for zoom changes
399
+ (_visualViewport2 = visualViewport) === null || _visualViewport2 === void 0 || _visualViewport2.addEventListener('resize', this.handleVisualViewportChange);
400
+
401
+ // Listen for visibility changes to pause when tab is hidden
402
+ document.addEventListener('visibilitychange', this.handleDocumentVisibilityChange);
403
+ }
404
+ return _createClass(RzpGlassMount, [{
405
+ key: "stopIfPotato",
406
+ value: function stopIfPotato() {
407
+ var _this$performanceCont;
408
+ if (!((_this$performanceCont = this.performanceController) !== null && _this$performanceCont !== void 0 && _this$performanceCont.isPotato())) {
409
+ return;
410
+ }
411
+ this.stopRenderLoop();
412
+ throw new Error('RzpGlass: WebGL is not supported in this browser');
413
+ }
414
+
415
+ /**
416
+ * Load all assets (video or static image + gradient maps) and start rendering.
417
+ * When `assets.imageSrc` is provided it is used as a static base texture and
418
+ * no video element is created.
419
+ */
420
+ }, {
421
+ key: "loadAssets",
422
+ value: (function () {
423
+ var _loadAssets = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
424
+ var _this$assets$gradient, useStaticImage, gradientMap2Src, _yield$Promise$all, _yield$Promise$all2, baseAsset, gradientMap, gradientMap2, centerGradientMap, _t;
425
+ return _regeneratorRuntime.wrap(function (_context) {
426
+ while (1) switch (_context.prev = _context.next) {
427
+ case 0:
428
+ this.stopIfPotato();
429
+ _context.prev = 1;
430
+ useStaticImage = Boolean(this.assets.imageSrc);
431
+ gradientMap2Src = (_this$assets$gradient = this.assets.gradientMap2Src) !== null && _this$assets$gradient !== void 0 ? _this$assets$gradient : this.assets.gradientMapSrc;
432
+ _context.next = 2;
433
+ return Promise.all([useStaticImage ? loadImage(this.assets.imageSrc) : loadVideo(this.assets.videoSrc), loadImage(this.assets.gradientMapSrc), loadImage(gradientMap2Src), loadImage(this.assets.centerGradientMapSrc)]);
434
+ case 2:
435
+ _yield$Promise$all = _context.sent;
436
+ _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 4);
437
+ baseAsset = _yield$Promise$all2[0];
438
+ gradientMap = _yield$Promise$all2[1];
439
+ gradientMap2 = _yield$Promise$all2[2];
440
+ centerGradientMap = _yield$Promise$all2[3];
441
+ if (!useStaticImage) {
442
+ _context.next = 3;
443
+ break;
444
+ }
445
+ // Static image path — upload once to texture unit 0, no video loop needed
446
+ this.setupImageTexture('uVideoTexture', baseAsset, 0);
447
+ _context.next = 4;
448
+ break;
449
+ case 3:
450
+ this.video = baseAsset;
451
+ this.setupVideoTexture();
452
+ // Set video to start time and apply playback rate before playback
453
+ this.video.currentTime = this.config.startTime;
454
+ this.video.playbackRate = this.config.playbackRate;
455
+ if (this.config.paused) {
456
+ _context.next = 4;
457
+ break;
458
+ }
459
+ _context.next = 4;
460
+ return this.video.play()["catch"](function (e) {
461
+ console.warn('Video autoplay failed:', e);
462
+ });
463
+ case 4:
464
+ this.setupImageTexture('uGradientMap', gradientMap, 1);
465
+ this.setupImageTexture('uCenterGradientMap', centerGradientMap, 2);
466
+ this.setupImageTexture('uGradientMap2', gradientMap2, 3);
467
+
468
+ // Set initial uniform values
469
+ this.setAllUniforms();
470
+ this.isInitialized = true;
471
+
472
+ // Initial resize
473
+ this.handleResize();
474
+
475
+ // Start the render loop (runs continuously)
476
+ this.startRenderLoop();
477
+ _context.next = 6;
478
+ break;
479
+ case 5:
480
+ _context.prev = 5;
481
+ _t = _context["catch"](1);
482
+ console.error('RzpGlass: Failed to load assets', _t);
483
+ throw _t;
484
+ case 6:
485
+ case "end":
486
+ return _context.stop();
487
+ }
488
+ }, _callee, this, [[1, 5]]);
489
+ }));
490
+ function loadAssets() {
491
+ return _loadAssets.apply(this, arguments);
492
+ }
493
+ return loadAssets;
494
+ }())
495
+ }, {
496
+ key: "initProgram",
497
+ value: function initProgram() {
498
+ var program = createProgram(this.gl, rzpGlassVertexShader, rzpGlassFragmentShader);
499
+ if (!program) {
500
+ throw new Error('RzpGlass: Failed to create WebGL program');
501
+ }
502
+ this.program = program;
503
+ }
504
+ }, {
505
+ key: "setupPositionAttribute",
506
+ value: function setupPositionAttribute() {
507
+ var buffers = setupFullscreenQuad(this.gl, this.program);
508
+ if (!buffers) {
509
+ throw new Error('RzpGlass: Failed to setup fullscreen quad');
510
+ }
511
+ }
512
+ }, {
513
+ key: "setupUniformLocations",
514
+ value: function setupUniformLocations() {
515
+ var gl = this.gl;
516
+ var program = this.program;
517
+
518
+ // All uniform names from the shader
519
+ var uniformNames = ['uTime', 'iResolution', 'uDpr', 'uVideoTexture', 'uGradientMap', 'uGradientMap2', 'uGradientMapBlend', 'uCenterGradientMap', 'uEnableDisplacement', 'uEnableColorama', 'uEnableBloom', 'uEnableLightSweep', 'uInputMin', 'uInputMax', 'uModifyGamma', 'uPosterizeLevels', 'uCycleRepetitions', 'uPhaseShift', 'uCycleSpeed', 'uWrapMode', 'uReverse', 'uBlendWithOriginal', 'uLightIntensity', 'uFrameCount', 'uLightStartFrame', 'uNumSegments', 'uSlitAngle', 'uDisplacementX', 'uDisplacementY', 'uEnableCenterElement', 'uCenterAnimDuration', 'uCenterAnimTime', 'uCCBlackPoint', 'uCCWhitePoint', 'uCCMidtoneGamma', 'uCCGamma', 'uCCContrast', 'uZoom', 'uPan',
520
+ // vec2(panX, panY) - set in vertex shader
521
+ 'uEdgeFeather', 'uRefResolution', 'uVisibleUvBounds',
522
+ // vec4(minX, minY, maxX, maxY) - visible portion of canvas in UV space
523
+ 'uBackgroundColor',
524
+ // vec3(r, g, b) - background color to blend with
525
+ // Ripple wave
526
+ 'uEnableRippleWave', 'uRippleSpeed', 'uRippleBlend', 'uRippleAngularPower', 'uRippleRadialFalloff', 'uRippleWaitTime'];
527
+ for (var _i = 0, _uniformNames = uniformNames; _i < _uniformNames.length; _i++) {
528
+ var name = _uniformNames[_i];
529
+ this.uniformLocations[name] = gl.getUniformLocation(program, name);
530
+ }
531
+ }
532
+ }, {
533
+ key: "setupVideoTexture",
534
+ value: function setupVideoTexture() {
535
+ var _this2 = this;
536
+ this.videoTexture = new Texture(this.gl, {
537
+ textureUnit: 0
538
+ });
539
+
540
+ // Use requestVideoFrameCallback for efficient video texture updates
541
+ if (this.video && 'requestVideoFrameCallback' in this.video) {
542
+ var _updateVideoFrame = function updateVideoFrame() {
543
+ if (_this2.hasBeenDisposed || !_this2.video || !_this2.videoTexture) return;
544
+ _this2.videoTexture.update(_this2.video);
545
+ _this2.videoFrameCallbackId = _this2.video.requestVideoFrameCallback(_updateVideoFrame);
546
+ };
547
+ this.videoFrameCallbackId = this.video.requestVideoFrameCallback(_updateVideoFrame);
548
+ }
549
+ }
550
+ }, {
551
+ key: "setupImageTexture",
552
+ value: function setupImageTexture(uniformName, image, textureUnit) {
553
+ var texture = new Texture(this.gl, {
554
+ textureUnit: textureUnit
555
+ });
556
+ texture.image(image);
557
+ if (uniformName === 'uVideoTexture') {
558
+ this.videoTexture = texture;
559
+ } else if (uniformName === 'uGradientMap') {
560
+ this.gradientMapTexture = texture;
561
+ } else if (uniformName === 'uGradientMap2') {
562
+ this.gradientMap2Texture = texture;
563
+ } else if (uniformName === 'uCenterGradientMap') {
564
+ this.centerGradientMapTexture = texture;
565
+ }
566
+ }
567
+
568
+ /**
569
+ * Hot-swap the gradient map texture at runtime.
570
+ * Accepts an HTMLCanvasElement (generated by generateGradientCanvas) or an HTMLImageElement.
571
+ * No reinitialization required — the next frame will pick up the new texture.
572
+ */
573
+ }, {
574
+ key: "updateGradientMapTexture",
575
+ value: function updateGradientMapTexture(source) {
576
+ if (!this.isInitialized || !this.gradientMapTexture) return;
577
+ this.gradientMapTexture.image(source);
578
+ }
579
+ }, {
580
+ key: "setupResizeObserver",
581
+ value: function setupResizeObserver() {
582
+ var _this3 = this;
583
+ this.resizeObserver = new ResizeObserver(function (_ref) {
584
+ var _ref2 = _slicedToArray(_ref, 1),
585
+ entry = _ref2[0];
586
+ if (entry !== null && entry !== void 0 && entry.borderBoxSize[0]) {
587
+ var _entry$devicePixelCon;
588
+ var physicalPixelSize = (_entry$devicePixelCon = entry.devicePixelContentBoxSize) === null || _entry$devicePixelCon === void 0 ? void 0 : _entry$devicePixelCon[0];
589
+ if (physicalPixelSize !== undefined) {
590
+ _this3.devicePixelsSupported = true;
591
+ _this3.parentDevicePixelWidth = physicalPixelSize.inlineSize;
592
+ _this3.parentDevicePixelHeight = physicalPixelSize.blockSize;
593
+ }
594
+ _this3.parentWidth = entry.borderBoxSize[0].inlineSize;
595
+ _this3.parentHeight = entry.borderBoxSize[0].blockSize;
596
+ }
597
+ _this3.handleResize();
598
+ });
599
+ this.resizeObserver.observe(this.parentElement);
600
+ }
601
+ }, {
602
+ key: "setAllUniforms",
603
+ value: function setAllUniforms() {
604
+ var gl = this.gl;
605
+ gl.useProgram(this.program);
606
+
607
+ // Texture units
608
+ gl.uniform1i(this.uniformLocations.uVideoTexture, 0);
609
+ gl.uniform1i(this.uniformLocations.uGradientMap, 1);
610
+ gl.uniform1i(this.uniformLocations.uCenterGradientMap, 2);
611
+ gl.uniform1i(this.uniformLocations.uGradientMap2, 3);
612
+ gl.uniform1f(this.uniformLocations.uGradientMapBlend, this.currentGradientMapBlend);
613
+
614
+ // Set all config-based uniforms
615
+ this.setUniformValues(this.config);
616
+
617
+ // Explicitly set pan uniform (vertex shader uniform)
618
+ gl.uniform2f(this.uniformLocations.uPan, this.config.panX, this.config.panY);
619
+
620
+ // Reference resolution (constant)
621
+ gl.uniform2f(this.uniformLocations.uRefResolution, REF_RESOLUTION.width, REF_RESOLUTION.height);
622
+
623
+ // Background color (or set to -1 if not provided)
624
+ if (this.config.backgroundColor) {
625
+ var _this$config$backgrou = _slicedToArray(this.config.backgroundColor, 3),
626
+ r = _this$config$backgrou[0],
627
+ g = _this$config$backgrou[1],
628
+ b = _this$config$backgrou[2];
629
+ gl.uniform3f(this.uniformLocations.uBackgroundColor, r, g, b);
630
+ // Also set clear color to match
631
+ gl.clearColor(r, g, b, 1.0);
632
+ } else {
633
+ // Set to -1 to indicate no background color blending
634
+ gl.uniform3f(this.uniformLocations.uBackgroundColor, -1.0, -1.0, -1.0);
635
+ // Use transparent clear color
636
+ gl.clearColor(0, 0, 0, 0);
637
+ }
638
+
639
+ // Visible UV bounds (where container clips the canvas)
640
+ gl.uniform4f(this.uniformLocations.uVisibleUvBounds, this.visibleUvBounds[0], this.visibleUvBounds[1], this.visibleUvBounds[2], this.visibleUvBounds[3]);
641
+ }
642
+
643
+ /** Check if uniform values are equal (handles arrays) */
644
+ }, {
645
+ key: "areUniformValuesEqual",
646
+ value: function areUniformValuesEqual(a, b) {
647
+ var _this4 = this;
648
+ if (a === b) return true;
649
+ if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
650
+ return a.every(function (val, i) {
651
+ return _this4.areUniformValuesEqual(val, b[i]);
652
+ });
653
+ }
654
+ return false;
655
+ }
656
+
657
+ /** Set uniform values with caching to avoid redundant updates */
658
+ }, {
659
+ key: "setUniformValues",
660
+ value: function setUniformValues(config) {
661
+ var _this5 = this;
662
+ var gl = this.gl;
663
+ gl.useProgram(this.program);
664
+ Object.entries(config).forEach(function (_ref3) {
665
+ var _ref4 = _slicedToArray(_ref3, 2),
666
+ key = _ref4[0],
667
+ value = _ref4[1];
668
+ if (value === undefined) return;
669
+
670
+ // Check if value has changed
671
+ if (_this5.areUniformValuesEqual(_this5.uniformCache[key], value)) return;
672
+ _this5.uniformCache[key] = value;
673
+
674
+ // Get uniform name from config key
675
+ var uniformName = CONFIG_TO_UNIFORM[key];
676
+ if (!uniformName) return; // Skip non-uniform config values
677
+
678
+ var location = _this5.uniformLocations[uniformName];
679
+ if (!location) return;
680
+ if (typeof value === 'boolean') {
681
+ gl.uniform1f(location, value ? 1 : 0);
682
+ } else if (typeof value === 'number') {
683
+ gl.uniform1f(location, value);
684
+ } else if (Array.isArray(value)) {
685
+ // Handle array uniforms (cast to number[] since config values are all numbers/booleans)
686
+ var flatArray = value.flat();
687
+ switch (flatArray.length) {
688
+ case 2:
689
+ gl.uniform2fv(location, flatArray);
690
+ break;
691
+ case 3:
692
+ gl.uniform3fv(location, flatArray);
693
+ break;
694
+ case 4:
695
+ gl.uniform4fv(location, flatArray);
696
+ break;
697
+ }
698
+ }
699
+ });
700
+
701
+ // Handle special pan uniform (vec2 in vertex shader)
702
+ if (config.panX !== undefined || config.panY !== undefined) {
703
+ var panCacheKey = 'pan';
704
+ var panValue = [this.config.panX, this.config.panY];
705
+ if (!this.areUniformValuesEqual(this.uniformCache[panCacheKey], panValue)) {
706
+ this.uniformCache[panCacheKey] = panValue;
707
+ gl.uniform2f(this.uniformLocations.uPan, panValue[0], panValue[1]);
708
+ }
709
+ }
710
+
711
+ // Handle special backgroundColor uniform (vec3 in fragment shader)
712
+ if (config.backgroundColor !== undefined) {
713
+ var bgCacheKey = 'backgroundColor';
714
+ if (!this.areUniformValuesEqual(this.uniformCache[bgCacheKey], config.backgroundColor)) {
715
+ this.uniformCache[bgCacheKey] = config.backgroundColor;
716
+ if (config.backgroundColor) {
717
+ var _config$backgroundCol = _slicedToArray(config.backgroundColor, 3),
718
+ r = _config$backgroundCol[0],
719
+ g = _config$backgroundCol[1],
720
+ b = _config$backgroundCol[2];
721
+ gl.uniform3f(this.uniformLocations.uBackgroundColor, r, g, b);
722
+ // Also update clear color to match
723
+ gl.clearColor(r, g, b, 1.0);
724
+ } else {
725
+ // Set to -1 to indicate no background color blending
726
+ gl.uniform3f(this.uniformLocations.uBackgroundColor, -1.0, -1.0, -1.0);
727
+ // Use transparent clear color
728
+ gl.clearColor(0, 0, 0, 0);
729
+ }
730
+ }
731
+ }
732
+ }
733
+
734
+ /**
735
+ * Update uniforms from config (partial update supported)
736
+ */
737
+ }, {
738
+ key: "setUniforms",
739
+ value: function setUniforms(newConfig) {
740
+ this.config = _objectSpread(_objectSpread({}, this.config), newConfig);
741
+ if (!this.isInitialized) return;
742
+
743
+ // Use the new caching-based uniform setter
744
+ this.setUniformValues(newConfig);
745
+
746
+ // Handle paused state changes - control video play/pause
747
+ if (newConfig.paused !== undefined) {
748
+ if (newConfig.paused) {
749
+ var _this$video3;
750
+ (_this$video3 = this.video) === null || _this$video3 === void 0 || _this$video3.pause();
751
+ } else {
752
+ var _this$video4;
753
+ (_this$video4 = this.video) === null || _this$video4 === void 0 || _this$video4.play()["catch"](function () {});
754
+ }
755
+ }
756
+ if (newConfig.playbackRate !== undefined && this.video) {
757
+ this.video.playbackRate = newConfig.playbackRate;
758
+ }
759
+ if (newConfig.aspectRatio !== undefined) {
760
+ this.handleResize();
761
+ }
762
+ }
763
+ }, {
764
+ key: "startRenderLoop",
765
+ value: function startRenderLoop() {
766
+ if (this.rafId !== null) return; // Already running
767
+ this.lastRenderTime = performance.now() * 0.001; // Initialize in seconds
768
+ this.rafId = requestAnimationFrame(this.render);
769
+ }
770
+ }, {
771
+ key: "stopRenderLoop",
772
+ value: function stopRenderLoop() {
773
+ if (this.rafId !== null) {
774
+ cancelAnimationFrame(this.rafId);
775
+ this.rafId = null;
776
+ }
777
+ }
778
+ }, {
779
+ key: "getCurrentFrame",
780
+ value:
781
+ // ===== Public API (paper-shader style) =====
782
+
783
+ /** Get the current animation frame (in ms) */
784
+ function getCurrentFrame() {
785
+ return this.currentFrame;
786
+ }
787
+
788
+ /** Set a specific frame for deterministic results */
789
+ }, {
790
+ key: "setFrame",
791
+ value: function setFrame(newFrame) {
792
+ this.currentFrame = newFrame;
793
+ }
794
+
795
+ /** Set the maximum pixel count for performance tuning */
796
+ }, {
797
+ key: "setMaxPixelCount",
798
+ value: function setMaxPixelCount() {
799
+ var newMaxPixelCount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_MAX_PIXEL_COUNT;
800
+ this.maxPixelCount = newMaxPixelCount;
801
+ this.handleResize();
802
+ }
803
+
804
+ /** Set the minimum pixel ratio for quality tuning */
805
+ }, {
806
+ key: "setMinPixelRatio",
807
+ value: function setMinPixelRatio() {
808
+ var newMinPixelRatio = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
809
+ this.minPixelRatio = newMinPixelRatio;
810
+ this.handleResize();
811
+ }
812
+
813
+ /** Play video */
814
+ }, {
815
+ key: "play",
816
+ value: function play() {
817
+ var _this$video5;
818
+ this.config.paused = false;
819
+ (_this$video5 = this.video) === null || _this$video5 === void 0 || _this$video5.play()["catch"](function () {});
820
+ }
821
+
822
+ /** Pause video */
823
+ }, {
824
+ key: "pause",
825
+ value: function pause() {
826
+ var _this$video6;
827
+ this.config.paused = true;
828
+ (_this$video6 = this.video) === null || _this$video6 === void 0 || _this$video6.pause();
829
+ }
830
+
831
+ /** Seek to specific time in video */
832
+ }, {
833
+ key: "setTime",
834
+ value: function setTime(time) {
835
+ if (this.video) {
836
+ this.video.currentTime = time;
837
+ }
838
+ }
839
+ }, {
840
+ key: "dispose",
841
+ value: /** Clean up all WebGL resources */
842
+ function dispose() {
843
+ var _this$performanceCont2, _visualViewport3;
844
+ // Immediately mark as disposed to prevent future renders
845
+ this.hasBeenDisposed = true;
846
+
847
+ // Cancel any pending RAF
848
+ if (this.rafId !== null) {
849
+ cancelAnimationFrame(this.rafId);
850
+ this.rafId = null;
851
+ }
852
+
853
+ // Cancel video frame callback
854
+ if (this.videoFrameCallbackId !== null && this.video && 'cancelVideoFrameCallback' in this.video) {
855
+ this.video.cancelVideoFrameCallback(this.videoFrameCallbackId);
856
+ }
857
+
858
+ // Pause and remove video
859
+ if (this.video) {
860
+ this.video.pause();
861
+ this.video.src = '';
862
+ this.video.load();
863
+ this.video = null;
864
+ }
865
+
866
+ // Clean up WebGL resources
867
+ if (this.gl && this.program) {
868
+ var _this$videoTexture, _this$gradientMapText, _this$gradientMap2Tex, _this$centerGradientM;
869
+ (_this$videoTexture = this.videoTexture) === null || _this$videoTexture === void 0 || _this$videoTexture.destroy();
870
+ (_this$gradientMapText = this.gradientMapTexture) === null || _this$gradientMapText === void 0 || _this$gradientMapText.destroy();
871
+ (_this$gradientMap2Tex = this.gradientMap2Texture) === null || _this$gradientMap2Tex === void 0 || _this$gradientMap2Tex.destroy();
872
+ (_this$centerGradientM = this.centerGradientMapTexture) === null || _this$centerGradientM === void 0 || _this$centerGradientM.destroy();
873
+ this.gl.deleteProgram(this.program);
874
+ this.program = null;
875
+
876
+ // Reset WebGL state
877
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
878
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
879
+ this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null);
880
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
881
+
882
+ // Clear any errors
883
+ this.gl.getError();
884
+ }
885
+
886
+ // Clean up performance controller
887
+ (_this$performanceCont2 = this.performanceController) === null || _this$performanceCont2 === void 0 || _this$performanceCont2.dispose();
888
+ this.performanceController = null;
889
+
890
+ // Clean up observers and listeners
891
+ if (this.resizeObserver) {
892
+ this.resizeObserver.disconnect();
893
+ this.resizeObserver = null;
894
+ }
895
+ (_visualViewport3 = visualViewport) === null || _visualViewport3 === void 0 || _visualViewport3.removeEventListener('resize', this.handleVisualViewportChange);
896
+ document.removeEventListener('visibilitychange', this.handleDocumentVisibilityChange);
897
+ this.uniformLocations = {};
898
+ this.uniformCache = {};
899
+
900
+ // Remove canvas
901
+ this.canvasElement.remove();
902
+ this.parentElement.removeAttribute('data-rzp-glass');
903
+ }
904
+ }]);
905
+ }();
906
+
907
+ export { RzpGlassMount };
908
+ //# sourceMappingURL=RzpGlassMount.js.map