reel-deal 0.1.0-dev.1 → 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/dist/index.es.js CHANGED
@@ -1,73 +1,68 @@
1
- const b = {
1
+ const T = {
2
2
  minSpins: 2,
3
3
  durationMs: 4e3,
4
4
  speedPxS: 4e3,
5
5
  staggerMs: 300
6
- }, y = {
7
- warpAngleDeg: 90,
8
- edgePower: 0.5
9
- }, I = {
6
+ }, C = {
10
7
  maxPx: 4,
11
8
  speedAtMax: 2200
12
- }, g = {
13
- amplitudePx: 8,
9
+ }, E = {
10
+ amplitudePx: 9,
14
11
  speedHz: 0.25,
15
12
  phaseOffsetRad: 0.9,
16
- delayMs: 500,
17
13
  rampMs: 800
18
- }, L = 0.1, x = 0.6, B = (a, e, i) => Math.max(e, Math.min(i, Math.floor(a))), P = (a, e) => (a % e + e) % e, v = (a) => Math.max(0, Math.min(1, a)), U = (a) => {
19
- const e = v(a);
20
- return e ** 2 * (2 - e);
21
- }, G = (a) => {
22
- const e = v(a);
23
- return e + e ** 2 - e ** 3;
24
- }, X = (a) => {
25
- const e = v(a);
26
- if (e <= L) {
27
- const s = e / L;
28
- return U(s) * L;
29
- }
30
- if (e < x)
31
- return e;
32
- const i = (e - x) / (1 - x);
33
- return x + G(i) * (1 - x);
34
- }, E = (a, e) => typeof a == "number" && Number.isFinite(a) ? a : e, m = (a, e) => Math.max(0, E(a, e)), p = (a, e) => Math.max(0, Math.floor(E(a, e))), z = 2, D = (a) => {
35
- const e = { ...b, ...a ?? {} };
36
- return {
37
- minSpins: p(e.minSpins, b.minSpins),
38
- durationMs: p(e.durationMs, b.durationMs ?? 0),
39
- speedPxS: p(e.speedPxS, b.speedPxS ?? 0),
40
- staggerMs: p(e.staggerMs, b.staggerMs ?? 0)
41
- };
42
- }, N = (a) => {
43
- const e = { ...I, ...a ?? {} };
14
+ }, B = 0.1, A = 0.6, O = (a, t, s) => Math.max(t, Math.min(s, Math.floor(a))), I = (a, t) => (a % t + t) % t, v = (a) => Math.max(0, Math.min(1, a)), F = (a) => {
15
+ const t = v(a);
16
+ return t ** 2 * (2 - t);
17
+ }, $ = (a) => {
18
+ const t = v(a);
19
+ return t + t ** 2 - t ** 3;
20
+ }, Q = (a) => {
21
+ const t = v(a);
22
+ if (t <= B) {
23
+ const i = t / B;
24
+ return F(i) * B;
25
+ }
26
+ if (t < A)
27
+ return t;
28
+ const s = (t - A) / (1 - A);
29
+ return A + $(s) * (1 - A);
30
+ }, L = (a, t) => typeof a == "number" && Number.isFinite(a) ? a : t, _ = (a, t) => Math.max(0, L(a, t)), w = (a, t) => Math.max(0, Math.floor(L(a, t))), K = 2, X = (a) => {
31
+ const t = { ...T, ...a ?? {} };
44
32
  return {
45
- maxPx: m(e.maxPx, I.maxPx),
46
- speedAtMax: m(e.speedAtMax, I.speedAtMax)
33
+ minSpins: w(t.minSpins, T.minSpins),
34
+ durationMs: w(t.durationMs, T.durationMs ?? 0),
35
+ speedPxS: w(t.speedPxS, T.speedPxS ?? 0),
36
+ staggerMs: w(t.staggerMs, T.staggerMs ?? 0)
47
37
  };
48
- }, F = (a) => {
49
- const e = { ...y, ...a ?? {} };
38
+ }, Z = (a) => {
39
+ const t = { ...C, ...a ?? {} };
50
40
  return {
51
- warpAngleDeg: m(e.warpAngleDeg, y.warpAngleDeg),
52
- edgePower: m(e.edgePower, y.edgePower)
41
+ maxPx: _(t.maxPx, C.maxPx),
42
+ speedAtMax: _(t.speedAtMax, C.speedAtMax)
53
43
  };
54
- }, V = (a) => {
44
+ }, j = (a) => {
55
45
  if (a === !1) return null;
56
- const e = { ...g, ...a ?? {} };
46
+ const t = { ...E, ...a ?? {} };
57
47
  return {
58
- amplitudePx: m(e.amplitudePx, g.amplitudePx),
59
- speedHz: m(e.speedHz, g.speedHz),
60
- phaseOffsetRad: E(e.phaseOffsetRad, g.phaseOffsetRad),
61
- delayMs: p(e.delayMs, g.delayMs),
62
- rampMs: p(e.rampMs, g.rampMs)
48
+ amplitudePx: _(t.amplitudePx, E.amplitudePx),
49
+ speedHz: _(t.speedHz, E.speedHz),
50
+ phaseOffsetRad: L(t.phaseOffsetRad, E.phaseOffsetRad),
51
+ rampMs: w(t.rampMs, E.rampMs)
63
52
  };
64
- }, k = (a) => Math.max(1, E(a, z)), Y = (a, e) => {
65
- const i = document.getElementById(a);
66
- if (!i)
67
- throw new Error(`${e} not found: ${a}`);
68
- return i;
69
- }, H = (a, e) => typeof a == "string" ? Y(a, e) : a, q = 5, C = 0.72, $ = 0.28, Q = 7, W = 0.85, K = 1 - W;
70
- class j {
53
+ }, J = (a) => Math.max(1, L(a, K)), tt = (a, t) => {
54
+ const s = document.getElementById(a);
55
+ if (!s)
56
+ throw new Error(`${t} not found: ${a}`);
57
+ return s;
58
+ }, U = (a, t) => typeof a == "string" ? tt(a, t) : a, et = 5, z = 0.72, st = 0.28, it = 7, V = 0.85, rt = 1 - V, nt = 55, at = 300, ot = 1.25, lt = 0.35, N = {
59
+ warpAngleDeg: 60,
60
+ edgePower: 4.8
61
+ }, ht = (a) => ({
62
+ warpAngleDeg: _(a?.warpAngleDeg, N.warpAngleDeg),
63
+ edgePower: _(a?.edgePower, N.edgePower)
64
+ });
65
+ class ut {
71
66
  canvas;
72
67
  container;
73
68
  opts;
@@ -109,8 +104,8 @@ class j {
109
104
  buttonHandlerAttached = !1;
110
105
  spinning = !1;
111
106
  queuedSpins = null;
112
- constructor(e) {
113
- this.opts = e, this.reels = B(e.reels ?? 1, 1, q), this.spinConfig = D(e.spinConfig), this.spinBlur = N(e.spinBlur), this.webglShading = F(e.webglShading), this.idleBob = V(e.idleBob), this.maxDpr = k(e.maxDpr), this.canvas = H(e.canvas, "Canvas"), this.container = H(e.container, "Container"), this.offsets = new Array(this.reels).fill(0), this.velocities = new Array(this.reels).fill(0), this.lastVelOffsets = new Array(this.reels).fill(0), this.idleBaseOffsets = new Array(this.reels).fill(0);
107
+ constructor(t) {
108
+ this.opts = t, this.reels = O(t.reels ?? 1, 1, et), this.spinConfig = X(t.spinConfig), this.spinBlur = Z(t.spinBlur), this.webglShading = ht(t.webglShading), this.idleBob = j(t.idleBob), this.maxDpr = J(t.maxDpr), this.canvas = U(t.canvas, "Canvas"), this.container = U(t.container, "Container"), this.offsets = new Array(this.reels).fill(0), this.velocities = new Array(this.reels).fill(0), this.lastVelOffsets = new Array(this.reels).fill(0), this.idleBaseOffsets = new Array(this.reels).fill(0);
114
109
  }
115
110
  async init() {
116
111
  if (await this.loadSprite(), this.tryInitWebGL(), !this.gl)
@@ -126,70 +121,93 @@ class j {
126
121
  this.canvas !== this.container && this.container.contains(this.canvas) && (this.canvas.style.width || (this.canvas.style.width = "100%"), this.canvas.style.height || (this.canvas.style.height = "100%"), this.canvas.style.display || (this.canvas.style.display = "block"));
127
122
  }
128
123
  syncContainerLayoutVars() {
129
- const e = this.canvas === this.container ? this.canvas : this.container;
130
- e.style.setProperty("--reels", String(this.reels)), e.style.setProperty("--visible-slots", String(this.visibleSlots)), e.style.aspectRatio = `${this.reels} / ${this.visibleSlots * this.heightScale}`, this.canvas !== this.container && (this.container.style.overflow = "hidden");
124
+ const t = this.canvas === this.container ? this.canvas : this.container;
125
+ t.style.setProperty("--reels", String(this.reels)), t.style.setProperty("--visible-slots", String(this.visibleSlots)), t.style.aspectRatio = `${this.reels} / ${this.visibleSlots * this.heightScale}`, this.canvas !== this.container && (this.container.style.overflow = "hidden");
131
126
  }
132
- setSegments(e) {
127
+ setSegments(t) {
133
128
  this.ensureReady();
134
- const i = e ?? [];
135
- for (let s = 0; s < this.reels; s += 1) {
136
- const t = i[s] ?? 0, r = B(t, 0, this.opts.slotCount - 1);
137
- this.offsets[s] = r * this.frameHeight - this.centerIndex * this.frameHeight, this.lastVelOffsets[s] = this.offsets[s], this.velocities[s] = 0, this.idleBaseOffsets[s] = this.offsets[s];
129
+ const s = t ?? [];
130
+ for (let i = 0; i < this.reels; i += 1) {
131
+ const e = s[i] ?? 0, r = O(e, 0, this.opts.slotCount - 1);
132
+ this.offsets[i] = r * this.frameHeight - this.centerIndex * this.frameHeight, this.lastVelOffsets[i] = this.offsets[i], this.velocities[i] = 0, this.idleBaseOffsets[i] = this.offsets[i];
138
133
  }
139
134
  this.lastVelT = null, this.idleStartTime = null, this.anim = null, this.stop(), this.render(), this.startLoop();
140
135
  }
141
- setSegment(e) {
142
- this.setSegments(new Array(this.reels).fill(e));
136
+ setSegment(t) {
137
+ this.setSegments(new Array(this.reels).fill(t));
143
138
  }
144
- spinOnce(e, i) {
139
+ spinOnce(t, s) {
145
140
  this.ensureReady();
146
- const { minSpins: s, staggerMs: t, speedPxS: r, durationMs: o } = this.getSpinConfig(i), n = r > 0, c = new Array(this.reels), f = new Array(this.reels), u = new Array(this.reels);
147
- for (let l = 0; l < this.reels; l += 1) {
148
- const T = B(e[l] ?? 0, 0, this.opts.slotCount - 1) * this.frameHeight - this.centerIndex * this.frameHeight, A = P(T, this.spriteHeight), O = P(this.offsets[l], this.spriteHeight), w = P(O - A, this.spriteHeight);
149
- let _ = -(s * this.spriteHeight + w);
150
- if (n && o > 0) {
151
- const M = r * o / 1e3, R = Math.max(
152
- s,
153
- Math.ceil(Math.max(0, M - w) / this.spriteHeight)
141
+ const { minSpins: i, staggerMs: e, speedPxS: r, durationMs: l } = this.getSpinConfig(s), u = r > 0, f = this.getStopSpringOvershootPx(), c = Math.max(0, at), n = c > 0 && f > 0, h = new Array(this.reels), g = new Array(this.reels), p = new Array(this.reels), d = new Array(this.reels), m = new Array(this.reels);
142
+ for (let o = 0; o < this.reels; o += 1) {
143
+ const Y = O(t[o] ?? 0, 0, this.opts.slotCount - 1) * this.frameHeight - this.centerIndex * this.frameHeight, k = I(Y, this.spriteHeight), q = I(this.offsets[o], this.spriteHeight), H = I(q - k, this.spriteHeight);
144
+ let b = -(i * this.spriteHeight + H);
145
+ if (u && l > 0) {
146
+ const R = r * l / 1e3, P = Math.max(
147
+ i,
148
+ Math.ceil(Math.max(0, R - H) / this.spriteHeight)
154
149
  );
155
- _ = -(w + R * this.spriteHeight);
150
+ b = -(H + P * this.spriteHeight);
151
+ }
152
+ if (e > 0 && u) {
153
+ const R = r * e * o / 1e3, P = Math.ceil(R / this.spriteHeight);
154
+ b -= P * this.spriteHeight;
156
155
  }
157
- if (t > 0 && n) {
158
- const M = r * t * l / 1e3, R = Math.ceil(M / this.spriteHeight);
159
- _ -= R * this.spriteHeight;
156
+ h[o] = this.offsets[o], m[o] = this.offsets[o] + b;
157
+ let D = b, G = 0;
158
+ if (n && b !== 0 && f > 0) {
159
+ const P = Math.sign(b) * f;
160
+ D += P, G = c;
160
161
  }
161
- c[l] = this.offsets[l], f[l] = _, n ? u[l] = Math.max(0, Math.round(Math.abs(_) / r * 1e3)) : u[l] = Math.max(0, o + t * l);
162
+ g[o] = D, d[o] = G, u ? p[o] = Math.max(0, Math.round(Math.abs(D) / r * 1e3)) : p[o] = Math.max(0, l + e * o);
162
163
  }
163
- if (f.reduce((l, S) => l + Math.abs(S), 0) === 0 || u.every((l) => l <= 0)) {
164
- for (let l = 0; l < this.reels; l += 1)
165
- this.offsets[l] = this.offsets[l] + f[l];
164
+ const S = g.reduce((o, M) => o + Math.abs(M), 0), x = p.every((o) => o <= 0), W = d.every((o) => o <= 0);
165
+ if (S === 0 || x && W) {
166
+ for (let o = 0; o < this.reels; o += 1)
167
+ this.offsets[o] = m[o];
166
168
  return this.anim = null, this.resolvePendingSpins(), this.render(), Promise.resolve();
167
169
  }
168
- const h = performance.now();
169
- return this.anim = { startTime: h, startOffsets: c, deltas: f, durationMs: u }, this.idleStartTime = null, this.startLoop(), new Promise((l) => {
170
- this.pendingSpinResolvers.push(l);
170
+ const y = performance.now();
171
+ return this.anim = {
172
+ startTime: y,
173
+ startOffsets: h,
174
+ deltas: g,
175
+ durationMs: p,
176
+ settleDurationMs: d,
177
+ targets: m
178
+ }, this.idleStartTime = null, this.startLoop(), new Promise((o) => {
179
+ this.pendingSpinResolvers.push(o);
171
180
  });
172
181
  }
173
- getSpinConfig(e) {
174
- return e ? D({ ...this.spinConfig, ...e }) : this.spinConfig;
182
+ getSpinConfig(t) {
183
+ return t ? X({ ...this.spinConfig, ...t }) : this.spinConfig;
184
+ }
185
+ getStopSpringOvershootPx() {
186
+ const t = this.frameHeight * lt, s = Math.max(0, nt);
187
+ return Math.min(s, t);
175
188
  }
176
- async spinQueue(e) {
177
- for (let i = 0; i < e.length; i += 1) {
178
- const s = e[i];
179
- await this.spinOnce(s.stopAtSegments), s.callback?.(i, s.stopAtSegments);
189
+ getStopSpringOffset(t, s) {
190
+ if (t === 0) return 0;
191
+ const i = Math.exp(-5 * s), e = Math.PI * 2 * ot * s;
192
+ return t * i * Math.cos(e);
193
+ }
194
+ async spinQueue(t) {
195
+ for (let s = 0; s < t.length; s += 1) {
196
+ const i = t[s];
197
+ await this.spinOnce(i.stopAtSegments), i.callback?.(s, i.stopAtSegments);
180
198
  }
181
199
  }
182
200
  stop() {
183
201
  this.rafId !== null && cancelAnimationFrame(this.rafId), this.rafId = null, this.anim = null, this.resolvePendingSpins(), this.lastVelT = null;
184
- for (let e = 0; e < this.reels; e += 1)
185
- this.velocities[e] = 0;
202
+ for (let t = 0; t < this.reels; t += 1)
203
+ this.velocities[t] = 0;
186
204
  }
187
205
  resolvePendingSpins() {
188
206
  if (this.pendingSpinResolvers.length === 0) return;
189
- const e = this.pendingSpinResolvers;
207
+ const t = this.pendingSpinResolvers;
190
208
  this.pendingSpinResolvers = [];
191
- for (const i of e)
192
- i();
209
+ for (const s of t)
210
+ s();
193
211
  }
194
212
  requestResize() {
195
213
  this.queueResize();
@@ -203,18 +221,18 @@ class j {
203
221
  }
204
222
  handleButtonClick = async () => {
205
223
  if (this.spinning) return;
206
- const e = this.consumeNextSpin() ?? {
224
+ const t = this.consumeNextSpin() ?? {
207
225
  stopAtSegments: this.buildRandomSegments()
208
226
  };
209
227
  this.spinning = !0, this.setButtonDisabled(!0);
210
228
  try {
211
- await this.spinOnce(e.stopAtSegments);
229
+ await this.spinOnce(t.stopAtSegments);
212
230
  } finally {
213
231
  this.queuedSpins && this.queuedSpins.length === 0 ? this.setButtonDisabled(!0) : this.setButtonDisabled(!1), this.spinning = !1;
214
232
  }
215
233
  };
216
234
  resolveButton() {
217
- return this.opts.button ? H(this.opts.button, "Button") : null;
235
+ return this.opts.button ? U(this.opts.button, "Button") : null;
218
236
  }
219
237
  resolveSpinQueue() {
220
238
  return this.opts.queuedSpinStates ?? null;
@@ -223,13 +241,13 @@ class j {
223
241
  return this.queuedSpins || (this.queuedSpins = this.resolveSpinQueue()), !this.queuedSpins || this.queuedSpins.length === 0 ? null : this.queuedSpins.shift() ?? null;
224
242
  }
225
243
  buildRandomSegments() {
226
- const e = Math.max(1, Math.floor(this.opts.slotCount)), i = [];
227
- for (let s = 0; s < this.reels; s += 1)
228
- i.push(Math.floor(Math.random() * e));
229
- return i;
244
+ const t = Math.max(1, Math.floor(this.opts.slotCount)), s = [];
245
+ for (let i = 0; i < this.reels; i += 1)
246
+ s.push(Math.floor(Math.random() * t));
247
+ return s;
230
248
  }
231
- setButtonDisabled(e) {
232
- this.button && (this.button.disabled = e, e ? this.button.setAttribute("aria-busy", "true") : this.button.removeAttribute("aria-busy"));
249
+ setButtonDisabled(t) {
250
+ this.button && (this.button.disabled = t, t ? this.button.setAttribute("aria-busy", "true") : this.button.removeAttribute("aria-busy"));
233
251
  }
234
252
  shouldAnimate() {
235
253
  return this.anim !== null || this.idleBob !== null;
@@ -237,30 +255,39 @@ class j {
237
255
  startLoop() {
238
256
  this.rafId === null && this.shouldAnimate() && (this.rafId = requestAnimationFrame(this.loop));
239
257
  }
240
- loop = (e) => {
258
+ loop = (t) => {
241
259
  if (this.anim) {
242
- const { startTime: i, durationMs: s, startOffsets: t, deltas: r } = this.anim;
243
- let o = !0;
260
+ const { startTime: s, durationMs: i, startOffsets: e, deltas: r, settleDurationMs: l, targets: u } = this.anim, f = t - s;
261
+ let c = !0;
244
262
  for (let n = 0; n < this.reels; n += 1) {
245
- const c = s[n] ?? 0, f = c <= 0 ? 1 : Math.min(1, (e - i) / c), u = X(f);
246
- f < 1 && (o = !1);
247
- const d = t[n] + r[n] * u;
248
- let h = 0;
249
- if (f > C && this.frameHeight > 0) {
250
- const S = (1 - v((f - C) / $)) ** 2, T = d / this.frameHeight * Math.PI * 2, A = Math.min(Q, this.frameHeight * 0.06);
251
- h = Math.sin(T) * S * A;
252
- }
253
- this.offsets[n] = d + h;
263
+ const h = i[n] ?? 0, g = l[n] ?? 0, p = u[n] ?? e[n] + r[n];
264
+ if (h > 0 && f < h) {
265
+ const d = Math.min(1, f / h), m = Q(d);
266
+ d < 1 && (c = !1);
267
+ const S = e[n] + r[n] * m;
268
+ let x = 0;
269
+ if (d > z && this.frameHeight > 0) {
270
+ const y = (1 - v((d - z) / st)) ** 2, o = S / this.frameHeight * Math.PI * 2, M = Math.min(it, this.frameHeight * 0.06);
271
+ x = Math.sin(o) * y * M;
272
+ }
273
+ this.offsets[n] = S + x;
274
+ } else if (g > 0) {
275
+ const d = h <= 0 ? f / g : (f - h) / g, m = v(d), S = e[n] + r[n] - p, x = this.getStopSpringOffset(S, m);
276
+ m < 1 && (c = !1), this.offsets[n] = p + x;
277
+ } else
278
+ this.offsets[n] = p;
254
279
  }
255
- if (this.updateVelocity(e), this.render(), o) {
256
- for (let n = 0; n < this.reels; n += 1)
257
- this.offsets[n] = this.anim.startOffsets[n] + this.anim.deltas[n], this.idleBaseOffsets[n] = this.offsets[n];
258
- this.updateVelocity(e);
280
+ if (this.updateVelocity(t), this.render(), c) {
281
+ for (let n = 0; n < this.reels; n += 1) {
282
+ const h = this.anim.targets[n] ?? this.anim.startOffsets[n] + this.anim.deltas[n];
283
+ this.offsets[n] = h, this.idleBaseOffsets[n] = this.offsets[n];
284
+ }
285
+ this.updateVelocity(t);
259
286
  for (let n = 0; n < this.reels; n += 1)
260
287
  this.velocities[n] = 0;
261
288
  this.anim = null, this.idleStartTime = null, this.render(), this.resolvePendingSpins();
262
289
  }
263
- } else this.idleBob && (this.updateIdle(e), this.render());
290
+ } else this.idleBob && (this.updateIdle(t), this.render());
264
291
  if (!this.shouldAnimate()) {
265
292
  this.rafId = null;
266
293
  return;
@@ -270,70 +297,61 @@ class j {
270
297
  render() {
271
298
  this.spriteImg && (this.width <= 0 || this.height <= 0 || this.gl && this.renderWebGL());
272
299
  }
273
- getSpinBlurPxForReel(e) {
300
+ getSpinBlurPxForReel(t) {
274
301
  if (!this.anim) return 0;
275
- const i = Math.abs(this.velocities[e] ?? 0), s = Math.max(1, this.spinBlur.speedAtMax);
276
- return v(i / s) * Math.max(0, this.spinBlur.maxPx);
302
+ const s = Math.abs(this.velocities[t] ?? 0), i = Math.max(1, this.spinBlur.speedAtMax);
303
+ return v(s / i) * Math.max(0, this.spinBlur.maxPx);
277
304
  }
278
305
  renderWebGL() {
279
306
  if (!this.gl || !this.glProgram || !this.glAttribs || !this.glUniforms || !this.glTexture || !this.glBuffer || !this.spriteImg) return;
280
- const e = this.gl;
281
- e.useProgram(this.glProgram), e.bindBuffer(e.ARRAY_BUFFER, this.glBuffer), e.enableVertexAttribArray(this.glAttribs.pos), e.vertexAttribPointer(this.glAttribs.pos, 2, e.FLOAT, !1, 16, 0), e.enableVertexAttribArray(this.glAttribs.uv), e.vertexAttribPointer(this.glAttribs.uv, 2, e.FLOAT, !1, 16, 8), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.glTexture), e.uniform1i(this.glUniforms.texture, 0), e.uniform1f(this.glUniforms.frameHeight, this.frameHeight), e.uniform1f(this.glUniforms.spriteHeight, this.spriteHeight), e.uniform1f(this.glUniforms.visibleSlots, this.visibleSlots), e.uniform1f(this.glUniforms.heightScale, this.heightScale), e.uniform1f(this.glUniforms.edgePower, Math.max(0.5, this.webglShading.edgePower));
282
- const i = this.webglShading, s = Math.max(0, i.warpAngleDeg) * Math.PI / 180;
283
- e.uniform1f(this.glUniforms.warpAngle, s), e.clear(e.COLOR_BUFFER_BIT);
284
- const t = 1 / this.reels;
307
+ const t = this.gl;
308
+ t.useProgram(this.glProgram), t.bindBuffer(t.ARRAY_BUFFER, this.glBuffer), t.enableVertexAttribArray(this.glAttribs.pos), t.vertexAttribPointer(this.glAttribs.pos, 2, t.FLOAT, !1, 16, 0), t.enableVertexAttribArray(this.glAttribs.uv), t.vertexAttribPointer(this.glAttribs.uv, 2, t.FLOAT, !1, 16, 8), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.glTexture), t.uniform1i(this.glUniforms.texture, 0), t.uniform1f(this.glUniforms.frameHeight, this.frameHeight), t.uniform1f(this.glUniforms.spriteHeight, this.spriteHeight), t.uniform1f(this.glUniforms.visibleSlots, this.visibleSlots), t.uniform1f(this.glUniforms.heightScale, this.heightScale), t.uniform1f(this.glUniforms.edgePower, Math.max(0.5, this.webglShading.edgePower));
309
+ const s = this.webglShading, i = Math.max(0, s.warpAngleDeg) * Math.PI / 180;
310
+ t.uniform1f(this.glUniforms.warpAngle, i), t.clear(t.COLOR_BUFFER_BIT);
311
+ const e = 1 / this.reels;
285
312
  for (let r = 0; r < this.reels; r += 1) {
286
- e.uniform1f(this.glUniforms.reelX, r * t), e.uniform1f(this.glUniforms.reelW, t);
287
- const o = P(this.offsets[r], this.spriteHeight);
288
- e.uniform1f(this.glUniforms.offsetPx, o), e.uniform1f(this.glUniforms.blurPx, this.getSpinBlurPxForReel(r)), e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
313
+ t.uniform1f(this.glUniforms.reelX, r * e), t.uniform1f(this.glUniforms.reelW, e);
314
+ const l = I(this.offsets[r], this.spriteHeight);
315
+ t.uniform1f(this.glUniforms.offsetPx, l), t.uniform1f(this.glUniforms.blurPx, this.getSpinBlurPxForReel(r)), t.drawArrays(t.TRIANGLE_STRIP, 0, 4);
289
316
  }
290
317
  }
291
- updateVelocity(e) {
318
+ updateVelocity(t) {
292
319
  if (this.lastVelT === null) {
293
- this.lastVelT = e;
294
- for (let s = 0; s < this.reels; s += 1)
295
- this.lastVelOffsets[s] = this.offsets[s], this.velocities[s] = 0;
320
+ this.lastVelT = t;
321
+ for (let i = 0; i < this.reels; i += 1)
322
+ this.lastVelOffsets[i] = this.offsets[i], this.velocities[i] = 0;
296
323
  return;
297
324
  }
298
- const i = (e - this.lastVelT) / 1e3;
299
- if (!(i <= 0)) {
300
- for (let s = 0; s < this.reels; s += 1) {
301
- const t = (this.offsets[s] - this.lastVelOffsets[s]) / i;
302
- this.velocities[s] = this.velocities[s] * W + t * K, this.lastVelOffsets[s] = this.offsets[s];
325
+ const s = (t - this.lastVelT) / 1e3;
326
+ if (!(s <= 0)) {
327
+ for (let i = 0; i < this.reels; i += 1) {
328
+ const e = (this.offsets[i] - this.lastVelOffsets[i]) / s;
329
+ this.velocities[i] = this.velocities[i] * V + e * rt, this.lastVelOffsets[i] = this.offsets[i];
303
330
  }
304
- this.lastVelT = e;
331
+ this.lastVelT = t;
305
332
  }
306
333
  }
307
- updateIdle(e) {
334
+ updateIdle(t) {
308
335
  if (!this.idleBob) return;
309
- this.idleStartTime === null && (this.idleStartTime = e);
310
- const { amplitudePx: i, speedHz: s, phaseOffsetRad: t, delayMs: r, rampMs: o } = this.idleBob, n = e - this.idleStartTime;
311
- if (n < Math.max(0, r)) {
312
- for (let h = 0; h < this.reels; h += 1)
313
- this.offsets[h] = this.idleBaseOffsets[h], this.velocities[h] = 0;
314
- return;
315
- }
316
- const c = (n - Math.max(0, r)) / 1e3, f = Math.max(
317
- 0,
318
- Math.min(1, (n - Math.max(0, r)) / Math.max(1, o))
319
- ), u = U(f), d = s * Math.PI * 2;
336
+ this.idleStartTime === null && (this.idleStartTime = t);
337
+ const { amplitudePx: s, speedHz: i, phaseOffsetRad: e, rampMs: r } = this.idleBob, l = t - this.idleStartTime, u = l / 1e3, f = Math.max(0, Math.min(1, l / Math.max(1, r))), c = F(f), n = i * Math.PI * 2;
320
338
  for (let h = 0; h < this.reels; h += 1) {
321
- const l = c * d + h * t;
322
- this.offsets[h] = this.idleBaseOffsets[h] + Math.sin(l) * (i * u), this.velocities[h] = 0;
339
+ const g = u * n + h * e;
340
+ this.offsets[h] = this.idleBaseOffsets[h] + Math.sin(g) * (s * c), this.velocities[h] = 0;
323
341
  }
324
342
  }
325
343
  async loadSprite() {
326
- const { sprite: e } = this.opts, i = typeof e == "string" ? new Image() : e;
327
- typeof e == "string" && (i.src = e), (!i.complete || i.naturalWidth <= 0) && await new Promise((f, u) => {
328
- const d = () => f(), h = () => u(new Error("Failed to load sprite image"));
329
- i.addEventListener("load", d, { once: !0 }), i.addEventListener("error", h, { once: !0 });
344
+ const { sprite: t } = this.opts, s = typeof t == "string" ? new Image() : t;
345
+ typeof t == "string" && (s.src = t), (!s.complete || s.naturalWidth <= 0) && await new Promise((c, n) => {
346
+ const h = () => c(), g = () => n(new Error("Failed to load sprite image"));
347
+ s.addEventListener("load", h, { once: !0 }), s.addEventListener("error", g, { once: !0 });
330
348
  });
331
- const s = Math.max(1, Math.floor(this.opts.slotCount)), t = i.naturalWidth, r = t, o = r * s, n = i.naturalHeight;
332
- if (Math.abs(n - o) > 2)
349
+ const i = Math.max(1, Math.floor(this.opts.slotCount)), e = s.naturalWidth, r = e, l = r * i, u = s.naturalHeight;
350
+ if (Math.abs(u - l) > 2)
333
351
  throw new Error(
334
- `Sprite size mismatch. Expected height ~${Math.round(o)}px (slotCount=${s}, slot aspect 1/1), got ${n}px.`
352
+ `Sprite size mismatch. Expected height ~${Math.round(l)}px (slotCount=${i}, slot aspect 1/1), got ${u}px.`
335
353
  );
336
- this.spriteImg = i, this.spriteWidth = t, this.frameHeight = Math.max(1, Math.round(r)), this.spriteHeight = Math.max(1, Math.round(this.frameHeight * s));
354
+ this.spriteImg = s, this.spriteWidth = e, this.frameHeight = Math.max(1, Math.round(r)), this.spriteHeight = Math.max(1, Math.round(this.frameHeight * i));
337
355
  }
338
356
  setupResizeWatcher() {
339
357
  typeof ResizeObserver > "u" || this.resizeObserver || (this.resizeObserver = new ResizeObserver(() => this.queueResize()), this.resizeObserver.observe(this.container));
@@ -344,32 +362,32 @@ class j {
344
362
  }));
345
363
  };
346
364
  resizeToContainer() {
347
- const e = this.container.clientWidth, i = this.container.clientHeight, s = this.visibleSlots * this.heightScale;
348
- if (e <= 0 || i <= 0) {
365
+ const t = this.container.clientWidth, s = this.container.clientHeight, i = this.visibleSlots * this.heightScale;
366
+ if (t <= 0 || s <= 0) {
349
367
  this.applyResize(1, 1);
350
368
  return;
351
369
  }
352
- const t = s, r = this.reels, o = e / r * t;
353
- let n = e, c = o;
354
- c > i && (c = i, n = i / t * r);
355
- const f = Math.max(1, Math.floor(n)), u = Math.max(1, Math.floor(c));
356
- this.applyResize(f, u), this.render();
370
+ const e = i, r = this.reels, l = t / r * e;
371
+ let u = t, f = l;
372
+ f > s && (f = s, u = s / e * r);
373
+ const c = Math.max(1, Math.floor(u)), n = Math.max(1, Math.floor(f));
374
+ this.applyResize(c, n), this.render();
357
375
  }
358
376
  applyViewportCrop() {
359
- this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.canvas.style.transform = "";
377
+ this.ensureCanvasCoversContainer(), this.canvas.style.transform = "";
360
378
  }
361
- applyResize(e, i) {
362
- const s = Math.max(1, Math.floor(e)), t = Math.max(1, Math.floor(i)), r = this.getTargetDpr();
363
- this.width = s, this.height = t, this.dpr = r, this.canvas.width = Math.floor(this.width * this.dpr), this.canvas.height = Math.floor(this.height * this.dpr), this.gl && this.gl.viewport(0, 0, this.canvas.width, this.canvas.height), this.applyViewportCrop();
379
+ applyResize(t, s) {
380
+ const i = Math.max(1, Math.floor(t)), e = Math.max(1, Math.floor(s)), r = this.getTargetDpr();
381
+ this.width = i, this.height = e, this.dpr = r, this.canvas.width = Math.floor(this.width * this.dpr), this.canvas.height = Math.floor(this.height * this.dpr), this.gl && this.gl.viewport(0, 0, this.canvas.width, this.canvas.height), this.applyViewportCrop();
364
382
  }
365
383
  getTargetDpr() {
366
- const e = window.devicePixelRatio || 1, i = Math.max(1, e);
367
- return Math.min(this.maxDpr, i);
384
+ const t = window.devicePixelRatio || 1, s = Math.max(1, t);
385
+ return Math.min(this.maxDpr, s);
368
386
  }
369
387
  tryInitWebGL() {
370
388
  if (!this.spriteImg) return;
371
389
  this.releaseWebGLResources(), this.webglInitError = null;
372
- const e = this.canvas.getContext("webgl2", {
390
+ const t = this.canvas.getContext("webgl2", {
373
391
  antialias: !0,
374
392
  alpha: !0
375
393
  }) ?? this.canvas.getContext("webgl", {
@@ -379,12 +397,12 @@ class j {
379
397
  antialias: !0,
380
398
  alpha: !0
381
399
  });
382
- if (!e) {
383
- const u = document.createElement("canvas"), d = typeof WebGLRenderingContext < "u", h = u.getContext("webgl2") ?? u.getContext("webgl");
384
- this.webglInitError = `context is null (browser WebGL=${d ? "yes" : "no"}, fallback canvas=${h ? "yes" : "no"})`, console.warn("ReelDeal WebGL:", this.webglInitError);
400
+ if (!t) {
401
+ const n = document.createElement("canvas"), h = typeof WebGLRenderingContext < "u", g = n.getContext("webgl2") ?? n.getContext("webgl");
402
+ this.webglInitError = `context is null (browser WebGL=${h ? "yes" : "no"}, fallback canvas=${g ? "yes" : "no"})`, console.warn("ReelDeal WebGL:", this.webglInitError);
385
403
  return;
386
404
  }
387
- const t = this.createWebGLProgram(e, `
405
+ const e = this.createWebGLProgram(t, `
388
406
  attribute vec2 a_pos;
389
407
  attribute vec2 a_uv;
390
408
  varying vec2 v_uv;
@@ -412,6 +430,8 @@ class j {
412
430
  uniform float u_warpAngle;
413
431
  uniform float u_blurPx;
414
432
 
433
+ const float HALF_PI = 1.5707963;
434
+
415
435
  float saturate(float x) { return clamp(x, 0.0, 1.0); }
416
436
 
417
437
  void main() {
@@ -420,43 +440,33 @@ class j {
420
440
  }
421
441
 
422
442
  float localX = (v_uv.x - u_reelX) / u_reelW;
423
- // v_uv.y is authored as 0 at TOP, 1 at BOTTOM (Canvas-like).
424
443
  float localY = v_uv.y;
425
444
  float hs = max(0.0001, u_heightScale);
426
445
  float fullY = localY * hs + (1.0 - hs) * 0.5;
427
446
 
428
447
  float warp = max(0.0, u_warpAngle);
429
- float warpStrength = saturate(warp / 1.2);
430
- float center = 0.5;
431
- float centerBand = 1.0 / 3.0;
432
- float halfBand = centerBand * 0.5;
433
- float dist = abs(fullY - center);
434
- // Smoother transition: avoid a hard boundary at halfBand.
435
- float edgeWeight = smoothstep(halfBand, 0.5, dist);
448
+ float warpStrength = saturate(warp / HALF_PI);
449
+ float distNorm = abs(fullY - 0.5) * 2.0;
436
450
  float edgePow = max(0.5, u_edgePower);
437
- edgeWeight = pow(edgeWeight, edgePow) * warpStrength;
438
- float tEase = smoothstep(0.0, 1.0, fullY);
439
- float warpedY = mix(fullY, tEase, edgeWeight);
440
- float y = (warpedY - 0.5) * 2.0;
441
- float theta = y * warp;
442
- float edgeWarp = edgeWeight;
451
+ float edgeWeight = pow(saturate(distNorm), edgePow) * warpStrength;
452
+
453
+ float stretchMax = 6.0;
454
+ float stretch = mix(1.0, stretchMax, edgeWeight);
455
+ float warpedY = 0.5 + (fullY - 0.5) * stretch;
456
+
457
+ float arcY = 0.5 + 0.5 * sin((warpedY - 0.5) * HALF_PI);
458
+ warpedY = mix(warpedY, arcY, 0.2);
443
459
 
444
460
  float yPx = u_offsetPx + warpedY * (u_frameHeight * u_visibleSlots);
445
- // With UNPACK_FLIP_Y_WEBGL=0 and Canvas-like UVs (v=0 at TOP),
446
- // v=0 samples the TOP of the original image, so pixel Y-from-top maps directly to v.
447
- // Normalize early to improve precision on mobile GPUs.
448
461
  float v = fract((u_offsetPx / u_spriteHeight) +
449
462
  warpedY * ((u_frameHeight * u_visibleSlots) / u_spriteHeight));
450
463
 
451
464
  vec4 base = texture2D(u_tex, vec2(localX, v));
452
465
 
453
466
  if (u_blurPx > 0.0) {
454
- // Clamp blur step to reduce banding on mobile GPUs.
455
- // Scale max step with speed proxy (u_blurPx).
456
467
  float maxStepPx = 1.0 + 3.0 * saturate(u_blurPx / 4.0);
457
468
  float blurPx = min(u_blurPx, maxStepPx);
458
469
  float blurStep = blurPx / max(1.0, u_spriteHeight);
459
- // 9-tap gaussian-ish blur to reduce banding on mobile.
460
470
  vec4 sum = base * 0.227027;
461
471
  sum += texture2D(u_tex, vec2(localX, fract(v + blurStep))) * 0.1945946;
462
472
  sum += texture2D(u_tex, vec2(localX, fract(v - blurStep))) * 0.1945946;
@@ -472,72 +482,71 @@ class j {
472
482
  gl_FragColor = base;
473
483
  }
474
484
  `);
475
- if (!t) {
485
+ if (!e) {
476
486
  this.webglInitError = "shader program failed to compile/link (see console)", console.warn("ReelDeal WebGL:", this.webglInitError);
477
487
  return;
478
488
  }
479
- const r = e.createBuffer();
489
+ const r = t.createBuffer();
480
490
  if (!r) {
481
- this.webglInitError = "failed to create vertex buffer", console.warn("ReelDeal WebGL:", this.webglInitError), e.deleteProgram(t);
491
+ this.webglInitError = "failed to create vertex buffer", console.warn("ReelDeal WebGL:", this.webglInitError), t.deleteProgram(e);
482
492
  return;
483
493
  }
484
- e.bindBuffer(e.ARRAY_BUFFER, r);
485
- const o = new Float32Array([-1, -1, 0, 1, 1, -1, 1, 1, -1, 1, 0, 0, 1, 1, 1, 0]);
486
- e.bufferData(e.ARRAY_BUFFER, o, e.STATIC_DRAW);
487
- const n = e.createTexture();
488
- if (!n) {
489
- this.webglInitError = "failed to create texture", console.warn("ReelDeal WebGL:", this.webglInitError), e.deleteBuffer(r), e.deleteProgram(t);
494
+ t.bindBuffer(t.ARRAY_BUFFER, r);
495
+ const l = new Float32Array([-1, -1, 0, 1, 1, -1, 1, 1, -1, 1, 0, 0, 1, 1, 1, 0]);
496
+ t.bufferData(t.ARRAY_BUFFER, l, t.STATIC_DRAW);
497
+ const u = t.createTexture();
498
+ if (!u) {
499
+ this.webglInitError = "failed to create texture", console.warn("ReelDeal WebGL:", this.webglInitError), t.deleteBuffer(r), t.deleteProgram(e);
490
500
  return;
491
501
  }
492
- e.bindTexture(e.TEXTURE_2D, n), e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL, 0), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, this.spriteImg);
493
- const c = (u) => u > 0 && (u & u - 1) === 0;
494
- c(this.spriteWidth) && c(this.spriteHeight) ? (e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.REPEAT), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.REPEAT), e.generateMipmap(e.TEXTURE_2D), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR_MIPMAP_LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR)) : (e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE)), e.useProgram(t), e.clearColor(0, 0, 0, 0), e.enable(e.BLEND), e.blendFunc(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA), this.gl = e, this.glProgram = t, this.glBuffer = r, this.glTexture = n, this.glAttribs = {
495
- pos: e.getAttribLocation(t, "a_pos"),
496
- uv: e.getAttribLocation(t, "a_uv")
502
+ t.bindTexture(t.TEXTURE_2D, u), t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL, 0), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, this.spriteImg);
503
+ const f = (n) => n > 0 && (n & n - 1) === 0;
504
+ f(this.spriteWidth) && f(this.spriteHeight) ? (t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.REPEAT), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.REPEAT), t.generateMipmap(t.TEXTURE_2D), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.LINEAR_MIPMAP_LINEAR), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.LINEAR)) : (t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.LINEAR), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.LINEAR), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.CLAMP_TO_EDGE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.CLAMP_TO_EDGE)), t.useProgram(e), t.clearColor(0, 0, 0, 0), t.enable(t.BLEND), t.blendFunc(t.SRC_ALPHA, t.ONE_MINUS_SRC_ALPHA), this.gl = t, this.glProgram = e, this.glBuffer = r, this.glTexture = u, this.glAttribs = {
505
+ pos: t.getAttribLocation(e, "a_pos"),
506
+ uv: t.getAttribLocation(e, "a_uv")
497
507
  }, this.glUniforms = {
498
- texture: e.getUniformLocation(t, "u_tex"),
499
- reelX: e.getUniformLocation(t, "u_reelX"),
500
- reelW: e.getUniformLocation(t, "u_reelW"),
501
- offsetPx: e.getUniformLocation(t, "u_offsetPx"),
502
- frameHeight: e.getUniformLocation(t, "u_frameHeight"),
503
- spriteHeight: e.getUniformLocation(t, "u_spriteHeight"),
504
- visibleSlots: e.getUniformLocation(t, "u_visibleSlots"),
505
- heightScale: e.getUniformLocation(t, "u_heightScale"),
506
- edgePower: e.getUniformLocation(t, "u_edgePower"),
507
- warpAngle: e.getUniformLocation(t, "u_warpAngle"),
508
- blurPx: e.getUniformLocation(t, "u_blurPx")
508
+ texture: t.getUniformLocation(e, "u_tex"),
509
+ reelX: t.getUniformLocation(e, "u_reelX"),
510
+ reelW: t.getUniformLocation(e, "u_reelW"),
511
+ offsetPx: t.getUniformLocation(e, "u_offsetPx"),
512
+ frameHeight: t.getUniformLocation(e, "u_frameHeight"),
513
+ spriteHeight: t.getUniformLocation(e, "u_spriteHeight"),
514
+ visibleSlots: t.getUniformLocation(e, "u_visibleSlots"),
515
+ heightScale: t.getUniformLocation(e, "u_heightScale"),
516
+ edgePower: t.getUniformLocation(e, "u_edgePower"),
517
+ warpAngle: t.getUniformLocation(e, "u_warpAngle"),
518
+ blurPx: t.getUniformLocation(e, "u_blurPx")
509
519
  };
510
520
  }
511
- createWebGLProgram(e, i, s) {
512
- const t = this.createWebGLShader(e, e.VERTEX_SHADER, i), r = this.createWebGLShader(e, e.FRAGMENT_SHADER, s);
513
- if (!t || !r)
514
- return t && e.deleteShader(t), r && e.deleteShader(r), null;
515
- const o = e.createProgram();
516
- if (!o) return null;
517
- if (e.attachShader(o, t), e.attachShader(o, r), e.linkProgram(o), !e.getProgramParameter(o, e.LINK_STATUS)) {
518
- const n = e.getProgramInfoLog(o) ?? "unknown link error";
519
- return this.webglInitError = `program link failed: ${n}`, console.warn("ReelDeal WebGL: program link failed", n), e.deleteProgram(o), e.deleteShader(t), e.deleteShader(r), null;
521
+ createWebGLProgram(t, s, i) {
522
+ const e = this.createWebGLShader(t, t.VERTEX_SHADER, s), r = this.createWebGLShader(t, t.FRAGMENT_SHADER, i);
523
+ if (!e || !r)
524
+ return e && t.deleteShader(e), r && t.deleteShader(r), null;
525
+ const l = t.createProgram();
526
+ if (!l) return null;
527
+ if (t.attachShader(l, e), t.attachShader(l, r), t.linkProgram(l), !t.getProgramParameter(l, t.LINK_STATUS)) {
528
+ const u = t.getProgramInfoLog(l) ?? "unknown link error";
529
+ return this.webglInitError = `program link failed: ${u}`, console.warn("ReelDeal WebGL: program link failed", u), t.deleteProgram(l), t.deleteShader(e), t.deleteShader(r), null;
520
530
  }
521
- return e.detachShader(o, t), e.detachShader(o, r), e.deleteShader(t), e.deleteShader(r), o;
522
- }
523
- createWebGLShader(e, i, s) {
524
- const t = e.createShader(i);
525
- if (!t) return null;
526
- if (e.shaderSource(t, s), e.compileShader(t), !e.getShaderParameter(t, e.COMPILE_STATUS)) {
527
- const r = e.getShaderInfoLog(t) ?? "unknown compile error";
528
- return this.webglInitError = `shader compile failed: ${r}`, console.warn("ReelDeal WebGL: shader compile failed", r), e.deleteShader(t), null;
531
+ return t.detachShader(l, e), t.detachShader(l, r), t.deleteShader(e), t.deleteShader(r), l;
532
+ }
533
+ createWebGLShader(t, s, i) {
534
+ const e = t.createShader(s);
535
+ if (!e) return null;
536
+ if (t.shaderSource(e, i), t.compileShader(e), !t.getShaderParameter(e, t.COMPILE_STATUS)) {
537
+ const r = t.getShaderInfoLog(e) ?? "unknown compile error";
538
+ return this.webglInitError = `shader compile failed: ${r}`, console.warn("ReelDeal WebGL: shader compile failed", r), t.deleteShader(e), null;
529
539
  }
530
- return t;
540
+ return e;
531
541
  }
532
542
  releaseWebGLResources() {
533
543
  this.gl && (this.glTexture && this.gl.deleteTexture(this.glTexture), this.glBuffer && this.gl.deleteBuffer(this.glBuffer), this.glProgram && this.gl.deleteProgram(this.glProgram), this.glTexture = null, this.glBuffer = null, this.glProgram = null, this.glAttribs = null, this.glUniforms = null, this.gl = null);
534
544
  }
535
545
  }
536
546
  export {
537
- j as ReelDeal,
538
- g as defaultIdleBob,
539
- I as defaultSpinBlur,
540
- b as defaultSpinConfig,
541
- y as defaultWebGLShading
547
+ ut as ReelDeal,
548
+ E as defaultIdleBob,
549
+ C as defaultSpinBlur,
550
+ T as defaultSpinConfig
542
551
  };
543
552
  //# sourceMappingURL=index.es.js.map