@everymatrix/casino-challenges-overlay 0.22.12 → 0.22.13
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/casino-challenges-overlay/casino-challenge-details-events_23.entry.js +1 -1
- package/dist/casino-challenges-overlay/casino-challenges-overlay-fc86db96.js +1 -0
- package/dist/casino-challenges-overlay/casino-challenges-overlay.esm.js +1 -1
- package/dist/casino-challenges-overlay/{index-b4a452f5.js → index-58f943ea.js} +2 -2
- package/dist/casino-challenges-overlay/index.esm.js +1 -1
- package/dist/cjs/casino-challenge-details-events_23.cjs.entry.js +2 -2
- package/dist/cjs/{casino-challenges-overlay-7ce3e62a.js → casino-challenges-overlay-e699eea9.js} +494 -67
- package/dist/cjs/casino-challenges-overlay.cjs.js +2 -2
- package/dist/cjs/{index-6300a889.js → index-98384ab0.js} +4 -1
- package/dist/cjs/index.cjs.js +2 -2
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/collection/assets/completed.svg +1 -0
- package/dist/collection/components/casino-challenges-overlay/casino-challenges-overlay.css +66 -2
- package/dist/collection/components/casino-challenges-overlay/casino-challenges-overlay.js +155 -65
- package/dist/collection/utils/progress-animation-helpers.js +168 -0
- package/dist/collection/utils/progress-animation.js +173 -0
- package/dist/esm/casino-challenge-details-events_23.entry.js +3 -3
- package/dist/esm/{casino-challenges-overlay-9406646f.js → casino-challenges-overlay-fc86db96.js} +494 -67
- package/dist/esm/casino-challenges-overlay.js +3 -3
- package/dist/esm/{index-b4a452f5.js → index-58f943ea.js} +4 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/loader.js +3 -3
- package/dist/types/components/casino-challenges-overlay/casino-challenges-overlay.d.ts +42 -1
- package/dist/types/utils/progress-animation-helpers.d.ts +64 -0
- package/dist/types/utils/progress-animation.d.ts +53 -0
- package/package.json +1 -1
- package/dist/casino-challenges-overlay/casino-challenges-overlay-9406646f.js +0 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// ---------- Configs ----------
|
|
2
|
+
// The floating gain is more precise than the progress label, so tiny gains (+0.0001%) still show
|
|
3
|
+
export const GAIN_MAX_DECIMAL_PLACES = 4;
|
|
4
|
+
export const PROGRESS_DECIMAL_PLACES = 1;
|
|
5
|
+
// Count-up of the number, border and dot: longer for bigger gains, within these limits
|
|
6
|
+
export const COUNT_UP_MIN_MS = 500;
|
|
7
|
+
export const COUNT_UP_MS_PER_POINT = 20;
|
|
8
|
+
export const COUNT_UP_MAX_MS = 2500;
|
|
9
|
+
export const COMPLETED_ICON_VISIBLE_MS = 1700;
|
|
10
|
+
// Centre of the coin drawn inside bg-icon.svg
|
|
11
|
+
export const COIN_CENTER = { x: 7.6, y: 18.7 };
|
|
12
|
+
export const COIN_DROP_STAGGER_MS = 140;
|
|
13
|
+
export const COIN_DROP_COUNT = 5;
|
|
14
|
+
// Room for two back-to-back drops; further rapid updates skip their coins
|
|
15
|
+
export const MAX_COINS_IN_FLIGHT = COIN_DROP_COUNT * 2;
|
|
16
|
+
export const CONFETTI_COUNT = 26;
|
|
17
|
+
export const CONFETTI_COLORS = ['#ff9400', '#fef746', '#ffe24a', '#24aa4d', '#a4d3b4', '#ffffff', '#1df98b'];
|
|
18
|
+
const COIN_SPIN_TURNS = 4;
|
|
19
|
+
export const EFFECTS = {
|
|
20
|
+
jelly: {
|
|
21
|
+
timing: { duration: 700, easing: 'ease-out' },
|
|
22
|
+
keyframes: [
|
|
23
|
+
{ transform: 'scale(1, 1)' },
|
|
24
|
+
{ transform: 'scale(1.16, 0.84)', offset: 0.18 },
|
|
25
|
+
{ transform: 'scale(0.9, 1.12)', offset: 0.4 },
|
|
26
|
+
{ transform: 'scale(1.05, 0.96)', offset: 0.62 },
|
|
27
|
+
{ transform: 'scale(0.98, 1.02)', offset: 0.8 },
|
|
28
|
+
{ transform: 'scale(1, 1)' }
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
floatingGain: {
|
|
32
|
+
timing: { duration: 2000, easing: 'ease-out' },
|
|
33
|
+
keyframes: [
|
|
34
|
+
{ transform: 'translate(-50%, 4px) scale(0.5)', opacity: 0 },
|
|
35
|
+
{ transform: 'translate(-50%, -6px) scale(1.15)', opacity: 1, offset: 0.25 },
|
|
36
|
+
{ transform: 'translate(-50%, -12px) scale(1)', opacity: 1, offset: 0.6 },
|
|
37
|
+
{ transform: 'translate(-50%, -22px) scale(0.95)', opacity: 0 }
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
coinDrop: {
|
|
41
|
+
// Accelerates like a falling object; `backwards` keeps the coin hidden at its first keyframe during its delay
|
|
42
|
+
timing: { duration: 520, easing: 'cubic-bezier(0.55, 0, 0.85, 0.45)', fill: 'backwards' },
|
|
43
|
+
// A mini coin appears above the pill coin, flips while falling and shrinks into it
|
|
44
|
+
keyframes: [
|
|
45
|
+
{ transform: `translate(${COIN_CENTER.x}px, -18px) rotateY(0deg)`, opacity: 0 },
|
|
46
|
+
{ transform: `translate(${COIN_CENTER.x}px, -12px) rotateY(180deg)`, opacity: 1, offset: 0.25 },
|
|
47
|
+
{ transform: `translate(${COIN_CENTER.x}px, 8px) rotateY(540deg) scale(0.9)`, opacity: 1, offset: 0.85 },
|
|
48
|
+
{ transform: `translate(${COIN_CENTER.x}px, 12px) rotateY(600deg) scale(0.4)`, opacity: 0 }
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
coinWobble: {
|
|
52
|
+
timing: { duration: 480, easing: 'ease-out' },
|
|
53
|
+
keyframes: [
|
|
54
|
+
{ transform: 'rotate(0deg) scale(1)', filter: 'brightness(1)' },
|
|
55
|
+
{ transform: 'rotate(-16deg) scale(1.15, 0.88)', filter: 'brightness(1.4)', offset: 0.25 },
|
|
56
|
+
{ transform: 'rotate(10deg) scale(0.95, 1.06)', filter: 'brightness(1.15)', offset: 0.55 },
|
|
57
|
+
{ transform: 'rotate(-4deg) scale(1.02)', filter: 'brightness(1)', offset: 0.8 },
|
|
58
|
+
{ transform: 'rotate(0deg) scale(1)', filter: 'brightness(1)' }
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
coinSpin: {
|
|
62
|
+
// Fast start, long slow-down, like a coin flicked by a thumb
|
|
63
|
+
timing: { duration: 1100, easing: 'cubic-bezier(0.2, 0.7, 0.2, 1)' },
|
|
64
|
+
// perspective() makes the turn look 3D; without it the coin only gets thinner and wider
|
|
65
|
+
keyframes: [
|
|
66
|
+
{ transform: 'perspective(80px) rotateY(0deg)' },
|
|
67
|
+
{ transform: `perspective(80px) rotateY(${COIN_SPIN_TURNS * 360}deg)` }
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
goldGlow: {
|
|
71
|
+
timing: { duration: 1700 },
|
|
72
|
+
keyframes: [
|
|
73
|
+
{ filter: 'drop-shadow(0 0 0 rgba(255, 210, 60, 0))' },
|
|
74
|
+
{ filter: 'drop-shadow(0 0 7px rgba(255, 210, 60, 0.95))', offset: 0.3 },
|
|
75
|
+
{ filter: 'drop-shadow(0 0 3px rgba(255, 210, 60, 0.6))', offset: 0.7 },
|
|
76
|
+
{ filter: 'drop-shadow(0 0 0 rgba(255, 210, 60, 0))' }
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
confetti: {
|
|
80
|
+
// `backwards` keeps the piece hidden at the burst centre while it waits for its delay
|
|
81
|
+
timing: { easing: 'cubic-bezier(0.2, 0.6, 0.4, 1)', fill: 'backwards' }
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
// ---------- Utils ----------
|
|
85
|
+
export function randomBetween(min, max) {
|
|
86
|
+
return min + Math.random() * (max - min);
|
|
87
|
+
}
|
|
88
|
+
export function canAnimate(element) {
|
|
89
|
+
return typeof (element === null || element === void 0 ? void 0 : element.animate) === 'function';
|
|
90
|
+
}
|
|
91
|
+
export function prefersReducedMotion() {
|
|
92
|
+
var _a, _b, _c;
|
|
93
|
+
return (_c = (_b = (_a = window.matchMedia) === null || _a === void 0 ? void 0 : _a.call(window, '(prefers-reduced-motion: reduce)')) === null || _b === void 0 ? void 0 : _b.matches) !== null && _c !== void 0 ? _c : false;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Cancels the effects running on `element` and its descendants: the one named `name`, or all of them.
|
|
97
|
+
* Effects are started with their name as the animation id; CSS animations have no id, so they are kept.
|
|
98
|
+
*/
|
|
99
|
+
export function cancelEffects(element, name) {
|
|
100
|
+
if (typeof (element === null || element === void 0 ? void 0 : element.getAnimations) !== 'function')
|
|
101
|
+
return;
|
|
102
|
+
element.getAnimations({ subtree: true }).forEach((animation) => {
|
|
103
|
+
if (name ? animation.id === name : animation.id)
|
|
104
|
+
animation.cancel();
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
export function getCountUpDuration(startProgress, targetProgress) {
|
|
108
|
+
return Math.min(COUNT_UP_MAX_MS, COUNT_UP_MIN_MS + (targetProgress - startProgress) * COUNT_UP_MS_PER_POINT);
|
|
109
|
+
}
|
|
110
|
+
/** Fast start, gentle landing; `timeFraction` goes from 0 to 1 */
|
|
111
|
+
export function easeOutCubic(timeFraction) {
|
|
112
|
+
return 1 - Math.pow(1 - timeFraction, 3);
|
|
113
|
+
}
|
|
114
|
+
export function formatProgress(progress) {
|
|
115
|
+
if (progress === 0 || progress === 100)
|
|
116
|
+
return progress.toString();
|
|
117
|
+
const factor = 10 ** PROGRESS_DECIMAL_PLACES;
|
|
118
|
+
// Floored so the label never runs ahead of the fill (99.96 -> 99.9, not 100.0); the epsilon
|
|
119
|
+
// absorbs float error such as 0.29 * 100 = 28.999999999999996
|
|
120
|
+
return (Math.floor(progress * factor + 1e-9) / factor).toFixed(PROGRESS_DECIMAL_PLACES);
|
|
121
|
+
}
|
|
122
|
+
// Gain label such as "+5%", "+0.3%" or "+0.0001%", or '' when the gain rounds to 0. Trailing zeros are dropped (0.2500 -> 0.25).
|
|
123
|
+
export function formatProgressGain(previousProgress, newProgress) {
|
|
124
|
+
const factor = 10 ** GAIN_MAX_DECIMAL_PLACES;
|
|
125
|
+
// Rounded to the label precision, so float error (20.3 - 20.1 = 0.1999...) doesn't leak in
|
|
126
|
+
const roundedGain = Math.round((newProgress - previousProgress) * factor) / factor;
|
|
127
|
+
if (roundedGain <= 0)
|
|
128
|
+
return '';
|
|
129
|
+
return `+${roundedGain}%`;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* A random confetti piece bursting from `center`: it shoots out to the top of its arc (35% of the time),
|
|
133
|
+
* then falls and fades, like it has weight
|
|
134
|
+
*/
|
|
135
|
+
export function createConfettiPiece(index, center) {
|
|
136
|
+
// Mostly upwards: straight up (-90deg) spread by about ±120deg
|
|
137
|
+
const angle = -Math.PI / 2 + randomBetween(-0.5, 0.5) * Math.PI * 1.35;
|
|
138
|
+
const speed = randomBetween(18, 40);
|
|
139
|
+
const travelX = Math.cos(angle) * speed;
|
|
140
|
+
const travelY = Math.sin(angle) * speed;
|
|
141
|
+
const fallDistance = randomBetween(34, 50);
|
|
142
|
+
const rotation = randomBetween(-400, 400);
|
|
143
|
+
const width = randomBetween(2, 3.4);
|
|
144
|
+
const height = randomBetween(3, 5);
|
|
145
|
+
return {
|
|
146
|
+
style: {
|
|
147
|
+
width: `${width}px`,
|
|
148
|
+
height: `${height}px`,
|
|
149
|
+
// Centres the piece on the point the keyframes translate it to
|
|
150
|
+
margin: `${-height / 2}px 0 0 ${-width / 2}px`,
|
|
151
|
+
background: CONFETTI_COLORS[index % CONFETTI_COLORS.length],
|
|
152
|
+
borderRadius: index % 3 === 0 ? '50%' : ''
|
|
153
|
+
},
|
|
154
|
+
keyframes: [
|
|
155
|
+
{ transform: `translate(${center.x}px, ${center.y}px) rotate(0deg)`, opacity: 1 },
|
|
156
|
+
{
|
|
157
|
+
transform: `translate(${center.x + travelX}px, ${center.y + travelY}px) rotate(${rotation / 2}deg)`,
|
|
158
|
+
opacity: 1,
|
|
159
|
+
offset: 0.35
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
transform: `translate(${center.x + travelX * 1.3}px, ${center.y + travelY + fallDistance}px) rotate(${rotation}deg)`,
|
|
163
|
+
opacity: 0
|
|
164
|
+
}
|
|
165
|
+
],
|
|
166
|
+
timing: { duration: randomBetween(1200, 1700), delay: randomBetween(0, 120) }
|
|
167
|
+
};
|
|
168
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { canAnimate, cancelEffects, COIN_DROP_COUNT, COIN_DROP_STAGGER_MS, COMPLETED_ICON_VISIBLE_MS, CONFETTI_COUNT, createConfettiPiece, easeOutCubic, EFFECTS, formatProgressGain, getCountUpDuration, MAX_COINS_IN_FLIGHT, prefersReducedMotion } from "./progress-animation-helpers";
|
|
2
|
+
export class ProgressAnimation {
|
|
3
|
+
constructor(host) {
|
|
4
|
+
this.host = host;
|
|
5
|
+
}
|
|
6
|
+
attach(elements) {
|
|
7
|
+
this.elements = elements;
|
|
8
|
+
}
|
|
9
|
+
/** Counts up to `targetProgress` with the gain effects */
|
|
10
|
+
animateProgress(previousTarget, targetProgress) {
|
|
11
|
+
this.playProgressGain(previousTarget, targetProgress);
|
|
12
|
+
this.countUp(targetProgress);
|
|
13
|
+
}
|
|
14
|
+
/** Shows `targetProgress` at once and stops the count-up and all effects */
|
|
15
|
+
jumpToProgress(targetProgress) {
|
|
16
|
+
this.stopAll();
|
|
17
|
+
this.host.setDisplayedProgress(targetProgress);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Called when a level is completed: counts up to 100, then checkmark, coin spin, gold glow and confetti.
|
|
21
|
+
* `onFinished` runs when the checkmark hides; it is dropped if stopAll() or another call cuts the animation.
|
|
22
|
+
* With reduced motion 100 and the checkmark are shown at once, so the player still sees the level is done.
|
|
23
|
+
*/
|
|
24
|
+
playLevelComplete(previousTarget, onFinished) {
|
|
25
|
+
// Already showing 100 when a completion follows another one; the previous target is the next level's then
|
|
26
|
+
const startProgress = Math.max(previousTarget, this.host.getDisplayedProgress());
|
|
27
|
+
this.stopAll();
|
|
28
|
+
if (prefersReducedMotion()) {
|
|
29
|
+
this.host.setDisplayedProgress(100);
|
|
30
|
+
this.showCompletedIcon(onFinished);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (startProgress < 100)
|
|
34
|
+
this.playProgressGain(startProgress, 100);
|
|
35
|
+
this.countUp(100, () => {
|
|
36
|
+
var _a;
|
|
37
|
+
this.showCompletedIcon(onFinished);
|
|
38
|
+
this.spinCoin();
|
|
39
|
+
this.play((_a = this.elements) === null || _a === void 0 ? void 0 : _a.capsule, 'goldGlow');
|
|
40
|
+
this.burstConfetti();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/** Stops the count-up where it is and cancels all effects */
|
|
44
|
+
stopAll() {
|
|
45
|
+
var _a, _b;
|
|
46
|
+
this.stopCountUp();
|
|
47
|
+
clearTimeout(this.completedIconTimeoutId);
|
|
48
|
+
this.host.setCompletedIconVisible(false);
|
|
49
|
+
// The capsule's subtree includes the coin; cancelled particles remove themselves
|
|
50
|
+
cancelEffects((_a = this.elements) === null || _a === void 0 ? void 0 : _a.capsule);
|
|
51
|
+
cancelEffects((_b = this.elements) === null || _b === void 0 ? void 0 : _b.effectsLayer);
|
|
52
|
+
}
|
|
53
|
+
playProgressGain(previousProgress, newProgress) {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
// Restarted instead of stacked when updates arrive back to back
|
|
56
|
+
cancelEffects((_a = this.elements) === null || _a === void 0 ? void 0 : _a.capsule, 'jelly');
|
|
57
|
+
this.play((_b = this.elements) === null || _b === void 0 ? void 0 : _b.capsule, 'jelly');
|
|
58
|
+
this.showFloatingGain(formatProgressGain(previousProgress, newProgress));
|
|
59
|
+
this.dropCoins(COIN_DROP_COUNT);
|
|
60
|
+
}
|
|
61
|
+
countUp(targetProgress, onFinished) {
|
|
62
|
+
this.stopCountUp();
|
|
63
|
+
const startProgress = this.host.getDisplayedProgress();
|
|
64
|
+
if (startProgress === targetProgress) {
|
|
65
|
+
onFinished === null || onFinished === void 0 ? void 0 : onFinished();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const duration = getCountUpDuration(startProgress, targetProgress);
|
|
69
|
+
let startTime;
|
|
70
|
+
const step = (timestamp) => {
|
|
71
|
+
startTime !== null && startTime !== void 0 ? startTime : (startTime = timestamp);
|
|
72
|
+
const timeFraction = Math.min((timestamp - startTime) / duration, 1);
|
|
73
|
+
if (timeFraction < 1) {
|
|
74
|
+
this.host.setDisplayedProgress(startProgress + (targetProgress - startProgress) * easeOutCubic(timeFraction));
|
|
75
|
+
this.countUpFrameId = requestAnimationFrame(step);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// The last frame lands exactly on the target
|
|
79
|
+
this.host.setDisplayedProgress(targetProgress);
|
|
80
|
+
this.countUpFrameId = undefined;
|
|
81
|
+
onFinished === null || onFinished === void 0 ? void 0 : onFinished();
|
|
82
|
+
};
|
|
83
|
+
this.countUpFrameId = requestAnimationFrame(step);
|
|
84
|
+
}
|
|
85
|
+
stopCountUp() {
|
|
86
|
+
if (this.countUpFrameId !== undefined)
|
|
87
|
+
cancelAnimationFrame(this.countUpFrameId);
|
|
88
|
+
this.countUpFrameId = undefined;
|
|
89
|
+
}
|
|
90
|
+
showFloatingGain(label) {
|
|
91
|
+
const elements = this.getParticleElements();
|
|
92
|
+
if (!label || !elements)
|
|
93
|
+
return;
|
|
94
|
+
const { particle } = this.spawnParticle(elements.effectsLayer, 'floating-gain', 'floatingGain');
|
|
95
|
+
particle.style.left = `${elements.capsule.offsetWidth / 2}px`;
|
|
96
|
+
particle.textContent = label;
|
|
97
|
+
}
|
|
98
|
+
dropCoins(count) {
|
|
99
|
+
const elements = this.getParticleElements();
|
|
100
|
+
if (!elements)
|
|
101
|
+
return;
|
|
102
|
+
// Rapid updates would otherwise pile up coins; extra ones are skipped, not queued
|
|
103
|
+
const coinsInFlight = elements.effectsLayer.getElementsByClassName('mini-coin').length;
|
|
104
|
+
const coinsToDrop = Math.min(count, MAX_COINS_IN_FLIGHT - coinsInFlight);
|
|
105
|
+
for (let coinIndex = 0; coinIndex < coinsToDrop; coinIndex++) {
|
|
106
|
+
const { animation } = this.spawnParticle(elements.effectsLayer, 'mini-coin', 'coinDrop', {
|
|
107
|
+
timing: { delay: coinIndex * COIN_DROP_STAGGER_MS }
|
|
108
|
+
});
|
|
109
|
+
// Only a coin that actually lands makes the pill coin wobble; a cancelled one doesn't
|
|
110
|
+
animation.addEventListener('finish', () => {
|
|
111
|
+
cancelEffects(elements.coin, 'coinWobble');
|
|
112
|
+
this.play(elements.coin, 'coinWobble');
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
showCompletedIcon(onHidden) {
|
|
117
|
+
this.host.setCompletedIconVisible(true);
|
|
118
|
+
this.completedIconTimeoutId = setTimeout(() => {
|
|
119
|
+
this.host.setCompletedIconVisible(false);
|
|
120
|
+
onHidden();
|
|
121
|
+
}, COMPLETED_ICON_VISIBLE_MS);
|
|
122
|
+
}
|
|
123
|
+
spinCoin() {
|
|
124
|
+
var _a, _b, _c;
|
|
125
|
+
cancelEffects((_a = this.elements) === null || _a === void 0 ? void 0 : _a.effectsLayer, 'coinDrop');
|
|
126
|
+
cancelEffects((_b = this.elements) === null || _b === void 0 ? void 0 : _b.coin, 'coinWobble');
|
|
127
|
+
this.play((_c = this.elements) === null || _c === void 0 ? void 0 : _c.coin, 'coinSpin');
|
|
128
|
+
}
|
|
129
|
+
burstConfetti() {
|
|
130
|
+
const elements = this.getParticleElements();
|
|
131
|
+
if (!elements)
|
|
132
|
+
return;
|
|
133
|
+
const { offsetWidth, offsetHeight } = elements.capsule;
|
|
134
|
+
const burstCenter = { x: offsetWidth / 2, y: offsetHeight / 2 };
|
|
135
|
+
for (let pieceIndex = 0; pieceIndex < CONFETTI_COUNT; pieceIndex++) {
|
|
136
|
+
const piece = createConfettiPiece(pieceIndex, burstCenter);
|
|
137
|
+
const { particle } = this.spawnParticle(elements.effectsLayer, 'confetti', 'confetti', piece);
|
|
138
|
+
Object.assign(particle.style, piece.style);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** Starts an effect if `element` is rendered and can animate */
|
|
142
|
+
play(element, name) {
|
|
143
|
+
if (canAnimate(element))
|
|
144
|
+
this.startEffect(element, name);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Starts an effect with its name as the animation id, so cancelEffects() can find it.
|
|
148
|
+
* `keyframes` and `timing` are for particles, whose keyframes are generated per particle.
|
|
149
|
+
*/
|
|
150
|
+
startEffect(element, name, { keyframes, timing } = {}) {
|
|
151
|
+
var _a;
|
|
152
|
+
return element.animate((_a = keyframes !== null && keyframes !== void 0 ? keyframes : EFFECTS[name].keyframes) !== null && _a !== void 0 ? _a : null, Object.assign(Object.assign(Object.assign({}, EFFECTS[name].timing), timing), { id: name }));
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The elements particles need, or undefined when particles should be skipped: in a hidden tab updates keep
|
|
156
|
+
* arriving while animations don't advance, so particles would pile up and all play on return
|
|
157
|
+
*/
|
|
158
|
+
getParticleElements() {
|
|
159
|
+
const elements = this.elements;
|
|
160
|
+
if (!elements || document.hidden || !canAnimate(elements.effectsLayer))
|
|
161
|
+
return undefined;
|
|
162
|
+
return elements;
|
|
163
|
+
}
|
|
164
|
+
/** Appends a particle to the effects layer and plays `name` on it; the particle removes itself when done */
|
|
165
|
+
spawnParticle(effectsLayer, className, name, animationOptions) {
|
|
166
|
+
const particle = document.createElement('span');
|
|
167
|
+
particle.className = className;
|
|
168
|
+
effectsLayer.appendChild(particle);
|
|
169
|
+
const animation = this.startEffect(particle, name, animationOptions);
|
|
170
|
+
animation.onfinish = animation.oncancel = () => particle.remove();
|
|
171
|
+
return { particle, animation };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-
|
|
2
|
-
import { s as setClientStyling, a as setClientStylingURL, b as setStreamStyling } from './casino-challenges-overlay-
|
|
3
|
-
export { C as casino_challenges_overlay } from './casino-challenges-overlay-
|
|
1
|
+
import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-58f943ea.js';
|
|
2
|
+
import { s as setClientStyling, a as setClientStylingURL, b as setStreamStyling } from './casino-challenges-overlay-fc86db96.js';
|
|
3
|
+
export { C as casino_challenges_overlay } from './casino-challenges-overlay-fc86db96.js';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_LANGUAGE$3 = 'en';
|
|
6
6
|
const TRANSLATIONS$3 = {
|