@everymatrix/lottery-program-wof 1.13.8 → 1.13.10

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.
@@ -0,0 +1,126 @@
1
+
2
+ :host {
3
+ font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
4
+ }
5
+
6
+ *,
7
+ *::before,
8
+ *::after {
9
+ margin: 0;
10
+ padding: 0;
11
+ list-style: none;
12
+ text-decoration: none;
13
+ outline: none;
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ $outlineColor: rgb(150, 54, 88);
18
+ $outlineWidth: 2px;
19
+
20
+ .LotteryProgramWof {
21
+ background: var(--emfe-w-color-contrast, #07072A);
22
+ display: flex;
23
+ align-items: center;
24
+ flex-direction: column;
25
+ padding: 20px 0;
26
+ }
27
+
28
+ main {
29
+ max-width: 600px;
30
+ width: 100%;
31
+ display: flex;
32
+ justify-content: space-around;
33
+ min-height: 200px;
34
+ }
35
+
36
+ svg {
37
+ transition: opacity 0.3s;
38
+ }
39
+
40
+ .HighLightArea {
41
+ mix-blend-mode: color-dodge;
42
+ }
43
+
44
+ .HighLightAreaBackground {
45
+ mix-blend-mode: screen;
46
+ opacity: 0.41;
47
+ }
48
+
49
+ .HighLightAreaV1 {
50
+ background: radial-gradient(72.02% 62.64% at 50% 84.62%, rgba(255, 184, 47, 0.7) 0%, rgba(255, 184, 47, 0.384271) 30.52%, rgba(255, 184, 47, 0.165346) 52.4%, rgba(255, 184, 47, 0) 100%);
51
+ filter: blur(9px);
52
+ }
53
+ .HighLightAreaV2 {
54
+ background: radial-gradient(87.18% 75.82% at 50% 84.62%, rgba(255, 248, 186, 0.7) 0%, rgba(255, 248, 186, 0.384271) 29.48%, rgba(255, 248, 186, 0) 100%);
55
+ filter: blur(9px);
56
+ }
57
+
58
+ .FortuneContainer {
59
+ width: 100%;
60
+ display: flex;
61
+ align-items: center;
62
+ flex-direction: column;
63
+ }
64
+
65
+ .Center {
66
+ cursor: pointer;
67
+
68
+ transition: filter;
69
+ transition-duration: 1s;
70
+
71
+ &.disabled {
72
+ filter: grayscale(80%);
73
+ }
74
+
75
+ .CenterCircle {
76
+ fill: #3CE4BB;
77
+ stroke: $outlineColor;
78
+ stroke-width: $outlineWidth;
79
+ cursor: pointer;
80
+
81
+ transition: fill;
82
+ transition-duration: 1s;
83
+
84
+ }
85
+
86
+ .CenterText {
87
+ fill: #FFFFFF;
88
+ }
89
+ }
90
+
91
+ .PointerPartition {
92
+ opacity: 0.3;
93
+ fill: lightgoldenrodyellow;
94
+ stroke: red;
95
+ stroke-width: 6px;
96
+ stroke-dasharray: 12;
97
+ }
98
+
99
+ .Current {
100
+ color: #FFFFFF;
101
+ }
102
+
103
+ .PartitionText {
104
+ color: #FFFFFF;
105
+ font-style: normal;
106
+ font-weight: 700;
107
+ text-anchor: end;
108
+ text-shadow: 0px 3px #000;
109
+ dominant-baseline: central;
110
+ }
111
+
112
+ .PartitionsShadow {
113
+ background-blend-mode: multiply;
114
+ mix-blend-mode: multiply;
115
+ }
116
+
117
+ .PartitionTextEntityContainer {
118
+ height: 100%;
119
+ display: flex;
120
+ align-items: center;
121
+ }
122
+
123
+ .PartitionTextEntity {
124
+ width: 100%;
125
+ text-align: end;
126
+ }
@@ -9,34 +9,43 @@
9
9
  import { onMountMessageLifeCycle, _postMessage } from './message';
10
10
  import type { LotteryProgramForPlayer } from './types.business';
11
11
  import { themes } from './themes';
12
- import { classWithPart, setProps } from './util';
12
+ import { setProps } from './util';
13
13
  import { Spinner } from './class.spinner';
14
14
  import { SvgCalc } from './class.svgcalc';
15
15
  import { Process } from './class.process';
16
16
  import { _ } from './i18n';
17
+ import { setClientStyling } from './widget';
17
18
 
18
- // properties
19
+ // properties common
19
20
  export let lang: Lang = Lang.en
20
21
  export let endpoint: string = ''
21
22
  export let session: string = ''
23
+ export let clientstyling:string = ''
24
+
25
+ let rootContainer: HTMLElement
26
+ $: clientstyling && rootContainer && setClientStyling(rootContainer, clientstyling);
22
27
 
23
- export let lotteryprogramforplayer: string = undefined
24
-
28
+ // properties
25
29
  export let id: string = undefined
26
- export let sizeraw: string = '0'
27
- $: size = Number(sizeraw) || 0;
30
+ export let size
31
+
32
+ let bonus: LotteryProgramForPlayer
33
+ const updateOptions = async () => {
34
+ if(!options.length){
35
+ options = await getOptions(bonus, lang)
36
+ }
37
+ }
38
+ $: bonus && lang && updateOptions()
28
39
 
29
- export let optionsraw: string = '[]'
30
40
  let options: Option[] = []
31
- $: options = JSON.parse(optionsraw);
32
41
 
33
42
  // binds
34
43
  let svg: SVGElement;
35
- let container
44
+ let spinContainer
36
45
 
37
46
  let spinner = new Spinner({
38
47
  tick: (deg, _speed) => {
39
- setProps(container, {
48
+ setProps(spinContainer, {
40
49
  transform: `rotate(${deg})`,
41
50
  })
42
51
  speed = _speed * 0.5
@@ -50,16 +59,8 @@
50
59
  let shownFirstCheck = false
51
60
 
52
61
  let speed: number = 0
53
-
54
- $: lotteryProgramForPlayer = lotteryprogramforplayer && (JSON.parse(lotteryprogramforplayer)) as LotteryProgramForPlayer
55
- $: lotteryProgramForPlayer && (async () => {
56
-
57
- if(!options.length){
58
- options = await getOptions(lotteryProgramForPlayer.program.wheelOfFortune.partitions, lang)
59
- }
60
- })()
61
62
 
62
- $: themeIndex = lotteryProgramForPlayer?.program?.metadata?.template || 0
63
+ $: themeIndex = bonus?.program?.metadata?.template || 0
63
64
  $: theme = themes[themeIndex]
64
65
  $: calc = new SvgCalc({
65
66
  size,
@@ -67,22 +68,23 @@
67
68
  themeIndex,
68
69
  })
69
70
 
70
- $: lotteryProgramForPlayer && checkSpinable()
71
+ $: bonus && checkSpinable()
71
72
 
72
73
  const checkSpinable = () => {
73
74
  if(shownFirstCheck) return;
74
75
  shownFirstCheck = true
75
76
 
76
77
  if(spinable){
77
- if(getSpinCondition(lotteryProgramForPlayer)){
78
+
79
+ const isNoTimeToSpin = getSpinCondition(bonus)
80
+
81
+ if(isNoTimeToSpin){
78
82
  process.setMessage({
79
83
  mode: 'spin-failed'
80
84
  })
81
- }else if(getSpinCondition(lotteryProgramForPlayer) && !lotteryProgramForPlayer.next){
85
+ }else if(!isNoTimeToSpin && !bonus.next){
82
86
  process.setMessage($_('wof.NoNext'))
83
87
  }
84
- }else{
85
- // hasQueuedMessage = true
86
88
  }
87
89
  }
88
90
 
@@ -98,11 +100,11 @@
98
100
  const eventSpin = async () => {
99
101
  if(!spinable) return;
100
102
 
101
- if(!lotteryProgramForPlayer.current?.remainingTimes){
102
- if(lotteryProgramForPlayer.next){
103
+ if(!bonus.current?.remainingTimes){
104
+ if(bonus.next){
103
105
  process.setMessage({
104
106
  mode: 'show-next',
105
- modeValue: lotteryProgramForPlayer.next
107
+ modeValue: bonus.next
106
108
  })
107
109
  }else{
108
110
  process.setMessage($_('wof.NoNext'))
@@ -113,12 +115,15 @@
113
115
  spinable = false
114
116
  isShowPrizeArea = false
115
117
 
116
- container = svg.querySelector(getSpinContainerSelector(theme.pointerMode))
118
+ spinContainer = svg.querySelector(getSpinContainerSelector(theme.pointerMode))
117
119
 
118
120
  spinner.launch()
119
121
  process.drawer(`userid-${id}-${new Date().getTime()}`)
120
122
  }
121
123
  onMountMessageLifeCycle({
124
+ 'wof-private-bonuses': (data) => {
125
+ bonus = data.bonuses.find(_bonus => _bonus.program.id === id)
126
+ },
122
127
  'wof-private-message-close': (data) => {
123
128
  if(data.id !== id) return;
124
129
 
@@ -137,274 +142,162 @@
137
142
  $: optionFilter = theme.pointerMode === PointerMode.Arrow && speed > 0.3 ? `blur(${speed}px)` : null
138
143
  </script>
139
144
 
140
-
141
- {#if size && options.length}
142
- <svg
143
- bind:this={svg}
144
- width={size}
145
- height={size}
146
- style:opacity={messageShown ? '.3': ''}
147
- >
148
-
149
- <g {...classWithPart("BackgroundCircleGroup")} filter="url(#BgHalo)">
150
- {#each calc.backgroundCirclePropsArray() as props}
151
- <circle {...props} />
152
- {/each}
153
- </g>
145
+ <div class="WheelContainer" bind:this={rootContainer}>
146
+ {#if size && options.length}
147
+ <svg
148
+ bind:this={svg}
149
+ width={size}
150
+ height={size}
151
+ style:opacity={messageShown ? '.3': ''}
152
+ >
154
153
 
155
- <g {...classWithPart("Partitions")} {...calc.getSpinnerProps()}>
156
- <g {...classWithPart("PartitionsBackground")}>
157
- {#each options as option, index}
158
- <path
159
- {...classWithPart("PartitionBackground")}
160
- {...calc.getPartitionBackgroundProp(index)}
161
- />
154
+ <g class="BackgroundCircleGroup" filter="url(#BgHalo)">
155
+ {#each calc.backgroundCirclePropsArray() as props}
156
+ <circle {...props} />
157
+ {/each}
158
+ </g>
159
+
160
+ <g class="PartitionsContainer" {...calc.getSpinnerProps()}>
161
+ <g class="PartitionsBackgrounds">
162
+ {#each options as option, index}
163
+ <path
164
+ class="PartitionsBackground"
165
+ {...calc.getPartitionBackgroundProp(index)}
166
+ />
167
+ {/each}
168
+ </g>
169
+
170
+ <g class="Partitions">
171
+ {#each options as option,index}
172
+
173
+ {#if option.image}
174
+ <g
175
+ use:renderImage={index}
176
+ style:filter={optionFilter}
177
+ />
178
+ {:else if option.name}
179
+ <foreignObject
180
+ class="PartitionText"
181
+ {...(() => {
182
+ const props = calc.getSvgTextProps(index)
183
+ return {
184
+ ...props,
185
+ x: props.x - 100,
186
+ y: props.y - 50,
187
+ }
188
+ })()}
189
+ style:filter={optionFilter}
190
+ width={100}
191
+ height={100}
192
+ >
193
+ <div class="PartitionTextEntityContainer">
194
+ <p class="PartitionTextEntity">{option.name}</p>
195
+ </div>
196
+ </foreignObject>
197
+ {/if}
198
+ {/each}
199
+ </g>
200
+
201
+ <image {...{
202
+ class: "PartitionsShadow",
203
+ ...calc.getShadowImage()
204
+ }} />
205
+ </g>
206
+
207
+ {#if theme.pointerMode === PointerMode.Partition}
208
+ <g class="PointerContainer" {...calc.getSpinnerProps()}>
209
+ <image
210
+ {...{
211
+ class: "HighLightAreaBackground",
212
+ ...calc.getBackgroundImageProps(0),
213
+ }}
214
+ />
215
+ <image
216
+ {...{
217
+ class: "HighLightArea",
218
+ ...calc.getBackgroundImageProps(1),
219
+ }}
220
+ />
221
+
222
+ <path
223
+ class="PointerPartitionFrame"
224
+ {...calc.getPartitionFrame()}
225
+ {...{'stroke-width': isShowPrizeArea ? '3px' : '0px'}}
226
+ />
227
+ </g>
228
+ {/if}
229
+
230
+ <g
231
+ class="Center"
232
+ class:disabled={!spinable}
233
+ on:click={() => eventSpin()}
234
+ >
235
+ {#each calc.getThemedCenterImages() as themedImage}
236
+ <image {...calc.getThemedImageProp(themedImage)} />
162
237
  {/each}
163
238
  </g>
164
239
 
165
- <g {...classWithPart("PartitionsEntity")}>
240
+ {#if theme.background.isShowingBulb}
241
+ <g class="RingCirclesGroup">
166
242
  {#each options as option,index}
243
+ <image class="RingImage" {...calc.getRingImageProps(index)} />
244
+ <image class="RingImage" {...calc.getRingImageProps(index + 1/2)} />
245
+ {/each}
246
+ </g>
247
+ {/if}
167
248
 
168
- {#if option.image}
169
- <g
170
- use:renderImage={index}
171
- style:filter={optionFilter}
172
- />
173
- {:else if option.name}
174
- <text
175
- {...classWithPart("PartitionText")}
176
- {...calc.getSvgTextProps(index)}
177
- style:filter={optionFilter}
178
- >
179
- {option.name}
180
- </text>
181
- {/if}
249
+ {#if theme.pointerMode === PointerMode.Arrow}
250
+ <g class="PointerContainer" {...calc.getSpinnerProps()}>
251
+ {#each calc.getThemedPointerImages() as themedImage}
252
+ <image {...calc.getThemedImageProp(themedImage)} />
182
253
  {/each}
183
254
  </g>
184
-
185
- <image {...{
186
- ...classWithPart("PartitionsShadow"),
187
- ...calc.getShadowImage()
188
- }} />
189
- </g>
190
-
191
- {#if theme.pointerMode === PointerMode.Partition}
192
- <g {...classWithPart("Pointer")} {...calc.getSpinnerProps()}>
193
- <image
194
- {...{
195
- ...classWithPart("HighLightAreaBackground"),
196
- ...calc.getBackgroundImageProps(0),
197
- }}
198
- />
199
- <image
200
- {...{
201
- ...classWithPart("HighLightArea"),
202
- ...calc.getBackgroundImageProps(1),
203
- }}
204
- />
205
-
206
- <path
207
- {...classWithPart("PointerPartitionFrame")}
208
- {...calc.getPartitionFrame()}
209
- {...{'stroke-width': isShowPrizeArea ? '3px' : '0px'}}
210
- />
211
- </g>
212
- {/if}
255
+ {/if}
213
256
 
214
- <g
215
- {...classWithPart("Center")}
216
- class:disabled={!spinable}
217
- on:click={() => eventSpin()}
218
- >
219
- {#each calc.getThemedCenterImages() as themedImage}
220
- <image {...calc.getThemedImageProp(themedImage)} />
221
- {/each}
222
- </g>
223
257
 
224
- {#if theme.background.isShowingBulb}
225
- <g id="RingCirclesGroup">
226
- {#each options as option,index}
227
- <image {...classWithPart("RingImage")} {...calc.getRingImageProps(index)} />
228
- <image {...classWithPart("RingImage")} {...calc.getRingImageProps(index + 1/2)} />
229
- {/each}
230
- </g>
231
- {/if}
258
+ <!-- defs -->
232
259
 
233
- {#if theme.pointerMode === PointerMode.Arrow}
234
- <g {...classWithPart("Pointer")} {...calc.getSpinnerProps()}>
235
- {#each calc.getThemedPointerImages() as themedImage}
236
- <image {...calc.getThemedImageProp(themedImage)} />
260
+ {#each calc.getDefs() as def}
261
+ <defs>
262
+ <linearGradient {...def.props}>
263
+ {#each def.steps as step}
264
+ <stop offset={step.offset} stop-color={step.color} />
265
+ {/each}
266
+ </linearGradient>
267
+ </defs>
237
268
  {/each}
238
- </g>
269
+ <defs>
270
+ <linearGradient id="GPointerPartitionFrame" x1="50.7564" y1="-9.24463" x2="50.7564" y2="115.67" gradientUnits="userSpaceOnUse">
271
+ <stop offset="0" stop-color="#E7A60D"/>
272
+ <stop offset="0.378125" stop-color="#FFDD64"/>
273
+ <stop offset="1" stop-color="#FFF100"/>
274
+ </linearGradient>
275
+ </defs>
276
+
277
+ <defs>
278
+ <filter
279
+ {...{
280
+ width: size,
281
+ height: size,
282
+ x: 0,
283
+ y: 0,
284
+ }}
285
+ id="BgHalo" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"
286
+ >
287
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
288
+ <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
289
+ <feOffset/>
290
+ <feGaussianBlur stdDeviation="25"/>
291
+ <feComposite in2="hardAlpha" operator="out"/>
292
+ <feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 0.972917 0 0 0 0 0.729167 0 0 0 0.5 0"/>
293
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4318_310"/>
294
+ <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4318_310" result="shape"/>
295
+ </filter>
296
+ </defs>
297
+ </svg>
239
298
  {/if}
240
-
241
-
242
- <!-- defs -->
243
-
244
- {#each calc.getDefs() as def}
245
- <defs>
246
- <linearGradient {...def.props}>
247
- {#each def.steps as step}
248
- <stop offset={step.offset} stop-color={step.color} />
249
- {/each}
250
- </linearGradient>
251
- </defs>
252
- {/each}
253
- <defs>
254
- <linearGradient id="GPointerPartitionFrame" x1="50.7564" y1="-9.24463" x2="50.7564" y2="115.67" gradientUnits="userSpaceOnUse">
255
- <stop offset="0" stop-color="#E7A60D"/>
256
- <stop offset="0.378125" stop-color="#FFDD64"/>
257
- <stop offset="1" stop-color="#FFF100"/>
258
- </linearGradient>
259
- </defs>
260
-
261
- <defs>
262
- <filter
263
- {...{
264
- width: size,
265
- height: size,
266
- x: 0,
267
- y: 0,
268
- }}
269
- id="BgHalo" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"
270
- >
271
- <feFlood flood-opacity="0" result="BackgroundImageFix"/>
272
- <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
273
- <feOffset/>
274
- <feGaussianBlur stdDeviation="25"/>
275
- <feComposite in2="hardAlpha" operator="out"/>
276
- <feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 0.972917 0 0 0 0 0.729167 0 0 0 0.5 0"/>
277
- <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4318_310"/>
278
- <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4318_310" result="shape"/>
279
- </filter>
280
- </defs>
281
- </svg>
282
- {/if}
299
+ </div>
283
300
 
284
301
  <style lang="scss">
285
-
286
-
287
-
288
- *,
289
- *::before,
290
- *::after {
291
- margin: 0;
292
- padding: 0;
293
- list-style: none;
294
- text-decoration: none;
295
- outline: none;
296
- box-sizing: border-box;
297
- }
298
-
299
- $outlineColor: rgb(150, 54, 88);
300
- $outlineWidth: 2px;
301
-
302
- .LotteryProgramWof {
303
- background: var(--emfe-w-color-contrast, #07072A);
304
- display: flex;
305
- align-items: center;
306
- flex-direction: column;
307
- padding: 20px 0;
308
- }
309
-
310
- main {
311
- max-width: 600px;
312
- width: 100%;
313
- display: flex;
314
- justify-content: space-around;
315
- min-height: 200px;
316
- }
317
-
318
- svg {
319
- transition: opacity 0.3s;
320
- }
321
-
322
- .HighLightArea {
323
- mix-blend-mode: color-dodge;
324
- }
325
-
326
- .HighLightAreaBackground {
327
- mix-blend-mode: screen;
328
- opacity: 0.41;
329
- }
330
-
331
- .HighLightAreaV1 {
332
- background: radial-gradient(72.02% 62.64% at 50% 84.62%, rgba(255, 184, 47, 0.7) 0%, rgba(255, 184, 47, 0.384271) 30.52%, rgba(255, 184, 47, 0.165346) 52.4%, rgba(255, 184, 47, 0) 100%);
333
- filter: blur(9px);
334
- }
335
- .HighLightAreaV2 {
336
- background: radial-gradient(87.18% 75.82% at 50% 84.62%, rgba(255, 248, 186, 0.7) 0%, rgba(255, 248, 186, 0.384271) 29.48%, rgba(255, 248, 186, 0) 100%);
337
- filter: blur(9px);
338
- }
339
-
340
- .FortuneContainer {
341
- width: 100%;
342
- display: flex;
343
- align-items: center;
344
- flex-direction: column;
345
- }
346
-
347
- .BackgroundCircle {
348
- fill: #FFFFFF;
349
- animation: color-animation 1s infinite linear alternate;
350
- }
351
-
352
- .RingCirclesGroup {
353
- .RingCircle {
354
- fill: #FFFFFF;
355
- stroke: #FFFFFF;
356
- }
357
- }
358
-
359
- .Center {
360
- cursor: pointer;
361
-
362
- transition: filter;
363
- transition-duration: 1s;
364
-
365
- &.disabled {
366
- filter: grayscale(80%);
367
- }
368
-
369
- .CenterCircle {
370
- fill: #3CE4BB;
371
- stroke: $outlineColor;
372
- stroke-width: $outlineWidth;
373
- cursor: pointer;
374
-
375
- transition: fill;
376
- transition-duration: 1s;
377
-
378
- }
379
-
380
- .CenterText {
381
- fill: #FFFFFF;
382
- }
383
- }
384
-
385
- .PointerPartition {
386
- opacity: 0.3;
387
- fill: lightgoldenrodyellow;
388
- stroke: red;
389
- stroke-width: 6px;
390
- stroke-dasharray: 12;
391
- }
392
-
393
- .Current {
394
- color: #FFFFFF;
395
- }
396
-
397
- .PartitionText {
398
- fill: #FFFFFF;
399
- font-style: normal;
400
- font-weight: 700;
401
- text-anchor: end;
402
- text-shadow: 0px 3px #000;
403
- dominant-baseline: central;
404
- }
405
-
406
- .PartitionsShadow {
407
- background-blend-mode: multiply;
408
- mix-blend-mode: multiply;
409
- }
302
+ @import './private.item.svg.scss';
410
303
  </style>