@everymatrix/lottery-program-wof 1.3.2
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/README.md +30 -0
- package/dist/lottery-program-wof.js +7278 -0
- package/dist/lottery-program-wof.js.map +1 -0
- package/index.html +42 -0
- package/index.js +1 -0
- package/package.json +41 -0
- package/public/favicon.png +0 -0
- package/public/reset.css +48 -0
- package/rollup.config.js +61 -0
- package/src/LotteryProgramWof.svelte +129 -0
- package/src/api/api.ts +2011 -0
- package/src/api/configuration.ts +65 -0
- package/src/api/custom.d.ts +2 -0
- package/src/api/index.ts +15 -0
- package/src/business.dom.ts +130 -0
- package/src/business.fake.ts +17 -0
- package/src/business.ts +276 -0
- package/src/calc.image.ts +13 -0
- package/src/calc.point.ts +315 -0
- package/src/calc.temp.ts +29 -0
- package/src/calc.ts +34 -0
- package/src/class.spinable.ts +65 -0
- package/src/class.spinable.util.ts +10 -0
- package/src/class.spinner.ts +145 -0
- package/src/class.spinner.util.ts +92 -0
- package/src/css.state.ts +13 -0
- package/src/fakeDraw.ts +9 -0
- package/src/fakeResult.ts +49 -0
- package/src/images/area.svg +11 -0
- package/src/images/areaSec.svg +11 -0
- package/src/images/areaV1.svg +18 -0
- package/src/images/areaV2.svg +17 -0
- package/src/images/background.svg +27 -0
- package/src/images/background3.svg +13 -0
- package/src/images/backgroundShadow.svg +22 -0
- package/src/images/centerArrow.svg +50 -0
- package/src/images/centerArrow1.svg +18 -0
- package/src/images/centerArrow2.svg +5 -0
- package/src/images/centerArrow3.svg +46 -0
- package/src/images/centerArrowBg.svg +12 -0
- package/src/images/centerBackground2.svg +24 -0
- package/src/images/centerCircle.svg +24 -0
- package/src/images/centerPack.svg +16 -0
- package/src/images/centerText3.svg +3 -0
- package/src/images/gift.svg +964 -0
- package/src/images/light.svg +19 -0
- package/src/images/partition1.svg +10 -0
- package/src/images/pointerArrow.svg +24 -0
- package/src/images/pointerArrow3.svg +25 -0
- package/src/images/spin.svg +13 -0
- package/src/index.ts +4 -0
- package/src/message.ts +28 -0
- package/src/private.item.svelte +279 -0
- package/src/private.item.svg.svelte +791 -0
- package/src/private.message.svelte +167 -0
- package/src/private.outcomes.svelte +163 -0
- package/src/private.tabs.svelte +92 -0
- package/src/themes.partitions.ts +174 -0
- package/src/themes.ts +206 -0
- package/src/types.business.ts +4 -0
- package/src/types.ts +74 -0
- package/src/util.ts +83 -0
- package/stories/LotteryProgramWof.stories.js +13 -0
- package/svelte.config.js +7 -0
- package/tsconfig.json +6 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// tslint:disable
|
|
2
|
+
/**
|
|
3
|
+
* BE.Server
|
|
4
|
+
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
|
5
|
+
*
|
|
6
|
+
* OpenAPI spec version: 1.0
|
|
7
|
+
*
|
|
8
|
+
*
|
|
9
|
+
* NOTE: This file is auto generated by the swagger code generator program.
|
|
10
|
+
* https://github.com/swagger-api/swagger-codegen.git
|
|
11
|
+
* Do not edit the file manually.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export interface ConfigurationParameters {
|
|
15
|
+
apiKey?: string | ((name: string) => string);
|
|
16
|
+
username?: string;
|
|
17
|
+
password?: string;
|
|
18
|
+
accessToken?: string | ((name: string, scopes?: string[]) => string);
|
|
19
|
+
basePath?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class Configuration {
|
|
23
|
+
/**
|
|
24
|
+
* parameter for apiKey security
|
|
25
|
+
* @param name security name
|
|
26
|
+
* @memberof Configuration
|
|
27
|
+
*/
|
|
28
|
+
apiKey?: string | ((name: string) => string);
|
|
29
|
+
/**
|
|
30
|
+
* parameter for basic security
|
|
31
|
+
*
|
|
32
|
+
* @type {string}
|
|
33
|
+
* @memberof Configuration
|
|
34
|
+
*/
|
|
35
|
+
username?: string;
|
|
36
|
+
/**
|
|
37
|
+
* parameter for basic security
|
|
38
|
+
*
|
|
39
|
+
* @type {string}
|
|
40
|
+
* @memberof Configuration
|
|
41
|
+
*/
|
|
42
|
+
password?: string;
|
|
43
|
+
/**
|
|
44
|
+
* parameter for oauth2 security
|
|
45
|
+
* @param name security name
|
|
46
|
+
* @param scopes oauth2 scope
|
|
47
|
+
* @memberof Configuration
|
|
48
|
+
*/
|
|
49
|
+
accessToken?: string | ((name: string, scopes?: string[]) => string);
|
|
50
|
+
/**
|
|
51
|
+
* override base path
|
|
52
|
+
*
|
|
53
|
+
* @type {string}
|
|
54
|
+
* @memberof Configuration
|
|
55
|
+
*/
|
|
56
|
+
basePath?: string;
|
|
57
|
+
|
|
58
|
+
constructor(param: ConfigurationParameters = {}) {
|
|
59
|
+
this.apiKey = param.apiKey;
|
|
60
|
+
this.username = param.username;
|
|
61
|
+
this.password = param.password;
|
|
62
|
+
this.accessToken = param.accessToken;
|
|
63
|
+
this.basePath = param.basePath;
|
|
64
|
+
}
|
|
65
|
+
}
|
package/src/api/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// tslint:disable
|
|
2
|
+
/**
|
|
3
|
+
* BE.Server
|
|
4
|
+
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
|
5
|
+
*
|
|
6
|
+
* OpenAPI spec version: 1.0
|
|
7
|
+
*
|
|
8
|
+
*
|
|
9
|
+
* NOTE: This file is auto generated by the swagger code generator program.
|
|
10
|
+
* https://github.com/swagger-api/swagger-codegen.git
|
|
11
|
+
* Do not edit the file manually.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export * from "./api";
|
|
15
|
+
export * from "./configuration";
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { createSVGElement } from "./calc";
|
|
2
|
+
import { getPropsForPartitionInfo } from "./calc.point";
|
|
3
|
+
import { setProps } from "./util";
|
|
4
|
+
|
|
5
|
+
export const getSvgImageProps = (ratio, index, radius, center, length, pointermode, arrowmode) => {
|
|
6
|
+
const sizeImage = radius / 8 // this.sizeImage
|
|
7
|
+
|
|
8
|
+
const width = sizeImage
|
|
9
|
+
const height = sizeImage
|
|
10
|
+
|
|
11
|
+
const offset = {
|
|
12
|
+
center: -1 * sizeImage / 2,
|
|
13
|
+
transform: {
|
|
14
|
+
x: sizeImage / 2,
|
|
15
|
+
y: sizeImage / 2,
|
|
16
|
+
},
|
|
17
|
+
position: {
|
|
18
|
+
x: 0,
|
|
19
|
+
y: 0,
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
...getPropsForPartitionInfo(ratio, radius, center, index, length, pointermode, arrowmode, offset),
|
|
24
|
+
width,
|
|
25
|
+
height,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const getSvgTextProps = (ratio, index, radius, center, length, pointermode, arrowmode) => {
|
|
30
|
+
|
|
31
|
+
const offset = {
|
|
32
|
+
center: 0,
|
|
33
|
+
position: {
|
|
34
|
+
x: 0, //option.name.length * 4,
|
|
35
|
+
y: 0
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
transform: {
|
|
39
|
+
x: 0,
|
|
40
|
+
y: 0,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
...getPropsForPartitionInfo(ratio, radius, center, index, length, pointermode, arrowmode, offset),
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const renderPartitionInfo = (ratio, svg, options, radius, center, pointermode, arrowmode) => {
|
|
50
|
+
const container = svg.querySelector("g#Images")
|
|
51
|
+
container.innerHTML = null
|
|
52
|
+
|
|
53
|
+
options.map((option, index) => {
|
|
54
|
+
|
|
55
|
+
let partitionAppearence: SVGElement
|
|
56
|
+
|
|
57
|
+
if(option.image){
|
|
58
|
+
|
|
59
|
+
const image = option.image as SVGImageElement
|
|
60
|
+
|
|
61
|
+
const sizeImage = radius / 8 // this.sizeImage
|
|
62
|
+
|
|
63
|
+
const width = sizeImage
|
|
64
|
+
const height = sizeImage
|
|
65
|
+
|
|
66
|
+
const offset = {
|
|
67
|
+
center: -1 * sizeImage / 2,
|
|
68
|
+
transform: {
|
|
69
|
+
x: sizeImage / 2,
|
|
70
|
+
y: sizeImage / 2,
|
|
71
|
+
},
|
|
72
|
+
position: {
|
|
73
|
+
x: 0,
|
|
74
|
+
y: 0,
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
setProps(image, {
|
|
79
|
+
...getPropsForPartitionInfo(ratio, radius, center, index, options.length, pointermode, arrowmode, offset),
|
|
80
|
+
width,
|
|
81
|
+
height,
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
partitionAppearence = image
|
|
85
|
+
|
|
86
|
+
}else if(option.name){
|
|
87
|
+
|
|
88
|
+
const text = createSVGElement("text")
|
|
89
|
+
|
|
90
|
+
const offset = {
|
|
91
|
+
center: 0,
|
|
92
|
+
position: {
|
|
93
|
+
x: option.name.length * 4,
|
|
94
|
+
y: 0
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
transform: {
|
|
98
|
+
x: 0,
|
|
99
|
+
y: 0,
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
setProps(text, {
|
|
104
|
+
...getPropsForPartitionInfo(ratio, radius, center, index, options.length, pointermode, arrowmode, offset),
|
|
105
|
+
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
text.innerHTML = option.name
|
|
109
|
+
|
|
110
|
+
partitionAppearence = text
|
|
111
|
+
|
|
112
|
+
}else{
|
|
113
|
+
throw new Error('please set name for partition')
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
container.appendChild(partitionAppearence)
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export const getPropsOfBackgroundCircle = (radius, rRingOuter, rRingInner) => ({
|
|
121
|
+
cx: radius,
|
|
122
|
+
cy: radius,
|
|
123
|
+
r: rRingInner,
|
|
124
|
+
'stroke-width': `${(rRingOuter - rRingInner) * 2}px`
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
export const getColorSchema = (index, length, colorSchema) => {
|
|
129
|
+
return colorSchema[index % Math.ceil(length / 2)]
|
|
130
|
+
}
|
package/src/business.ts
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import type { WheelOfFortunePartition } from './api';
|
|
2
|
+
import { getExceptionData } from './business.fake';
|
|
3
|
+
import { findDeg, randomInSection } from './calc';
|
|
4
|
+
import { getStatePropsForSpin } from './css.state';
|
|
5
|
+
import fakeDraw from './fakeDraw';
|
|
6
|
+
import fakeResult from './fakeResult';
|
|
7
|
+
import { _postMessage } from './message';
|
|
8
|
+
import { Api, ApiConfigs, Lang, PointerMode } from './types';
|
|
9
|
+
import type { LotteryProgramForPlayer } from './types.business';
|
|
10
|
+
import { delay, fetcher, imageLoaderSvg, setProps } from './util';
|
|
11
|
+
|
|
12
|
+
export interface Option {
|
|
13
|
+
image: SVGElement | string,
|
|
14
|
+
name: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const isUsingFakeData: boolean = false
|
|
18
|
+
|
|
19
|
+
const fetcherApi = async <T extends Api>(api: T, endpoint: string, config: ApiConfigs[T]) => {
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if(isUsingFakeData){
|
|
23
|
+
switch (api) {
|
|
24
|
+
case Api.lotteries: return fakeResult
|
|
25
|
+
case Api.draw: return fakeDraw
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
const { session } = config
|
|
31
|
+
|
|
32
|
+
const options = {
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
'accept': 'text/plain',
|
|
36
|
+
|
|
37
|
+
...(session ? {'x-SessionId': session} : {})
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const getArgs = {
|
|
42
|
+
[Api.lotteries]: () => {
|
|
43
|
+
|
|
44
|
+
const { } = config || {} as ApiConfigs[Api.lotteries]
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
path: '/wof/lotteries',
|
|
48
|
+
params: {
|
|
49
|
+
},
|
|
50
|
+
options,
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
[Api.outcome]: () => {
|
|
54
|
+
|
|
55
|
+
const { id } = config as ApiConfigs[Api.outcome]
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
path: `/wof/outcome/${id}`,
|
|
59
|
+
params: {
|
|
60
|
+
},
|
|
61
|
+
options,
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
[Api.draw]: () => {
|
|
65
|
+
|
|
66
|
+
const { id, guid } = config as ApiConfigs[Api.draw]
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
path: `/wof/draw/${id}`,
|
|
70
|
+
params: {
|
|
71
|
+
},
|
|
72
|
+
options: {
|
|
73
|
+
...options,
|
|
74
|
+
method: 'PUT',
|
|
75
|
+
body: JSON.stringify({
|
|
76
|
+
guid
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const args = getArgs[api]()
|
|
84
|
+
|
|
85
|
+
args.path = endpoint + args.path
|
|
86
|
+
|
|
87
|
+
return await fetcher(args)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const getOptionsFromPartitions = (partitions: WheelOfFortunePartition[], lang: Lang): Option[] => {
|
|
91
|
+
let options = partitions.map((_partition, index) => {
|
|
92
|
+
const partitionLang = {}
|
|
93
|
+
Object.keys(_partition).map((_key) => {
|
|
94
|
+
if(['name', 'image1', 'image2', 'image3'].includes(_key)){
|
|
95
|
+
partitionLang[_key] = _partition[_key][lang === 'en' ? '*' : lang] || ''
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const option: Option = {
|
|
100
|
+
image: partitionLang['image1'],
|
|
101
|
+
name: partitionLang['name']
|
|
102
|
+
}
|
|
103
|
+
return option
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
let probabilityAll = 0
|
|
107
|
+
partitions.map(partition => probabilityAll += Number(partition.probability))
|
|
108
|
+
if(probabilityAll < 1){
|
|
109
|
+
options.push({
|
|
110
|
+
image: '',
|
|
111
|
+
name: 'Thank you'
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return options
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const setMessage = (id: string, entry: string | object) => {
|
|
119
|
+
const _postMessageScoped = (props) => _postMessage({ ...props, id })
|
|
120
|
+
switch(typeof entry) {
|
|
121
|
+
case 'string':
|
|
122
|
+
_postMessageScoped({ type: 'wof-private-message-open', mode: 'normal', modeValue: entry })
|
|
123
|
+
break;
|
|
124
|
+
case 'object':
|
|
125
|
+
_postMessageScoped({ type: 'wof-private-message-open', ...(entry as object) })
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const getOptions = async (partitions: WheelOfFortunePartition[], lang: Lang) => {
|
|
131
|
+
|
|
132
|
+
const preloadImage = async (src: string) => {
|
|
133
|
+
if(!src) return {}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
image: await imageLoaderSvg(src) as SVGImageElement
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const options: Option[] = await Promise.all(
|
|
141
|
+
getOptionsFromPartitions(partitions, lang).map(async o => ({
|
|
142
|
+
...o,
|
|
143
|
+
...(await preloadImage(o.image as string))
|
|
144
|
+
}))
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return options
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const getCurrentInfo = (
|
|
151
|
+
lotteryProgramForPlayer: LotteryProgramForPlayer, key: 'active'|'implicit'
|
|
152
|
+
) => {
|
|
153
|
+
|
|
154
|
+
const { current } = lotteryProgramForPlayer
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
active: current.activeTickets,
|
|
158
|
+
implicit: `${current.maxImplicitTickets - current.usedImplicitTickets}/${current.maxImplicitTickets}`,
|
|
159
|
+
remainingTimes: current.remainingTimes,
|
|
160
|
+
}[key]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const api = {
|
|
164
|
+
lotteries:
|
|
165
|
+
async (endpoint: string, session: string) => {
|
|
166
|
+
|
|
167
|
+
const data = await fetcherApi(Api.lotteries, endpoint, { session })
|
|
168
|
+
|
|
169
|
+
const lotteryProgramForPlayers = data.items as LotteryProgramForPlayer[] || []
|
|
170
|
+
|
|
171
|
+
return lotteryProgramForPlayers
|
|
172
|
+
},
|
|
173
|
+
draw:
|
|
174
|
+
async (endpoint: string, session: string, id: string, guid, options: Option[], pointermode: PointerMode) => {
|
|
175
|
+
|
|
176
|
+
let data = await fetcherApi(Api.draw, endpoint, { id, session, guid })
|
|
177
|
+
|
|
178
|
+
// data = getExceptionData(data)
|
|
179
|
+
|
|
180
|
+
let index = data.item?.result?.wheelOfFortunePartitionIndex
|
|
181
|
+
|
|
182
|
+
let message: any
|
|
183
|
+
|
|
184
|
+
if(!index){
|
|
185
|
+
index = options.length - 1
|
|
186
|
+
message = `OOPs! You are close to a prize!`
|
|
187
|
+
}else{
|
|
188
|
+
message = {
|
|
189
|
+
mode: 'gift',
|
|
190
|
+
modeValue: options[index].name,
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
data,
|
|
196
|
+
message, index
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
outcome:
|
|
201
|
+
async (endpoint: string, session: string, id: string) => {
|
|
202
|
+
return await fetcherApi(Api.outcome, endpoint, { session, id })
|
|
203
|
+
},
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export const getMessageByCurrent = (current) => {
|
|
207
|
+
|
|
208
|
+
const { maxImplicitTickets, usedImplicitTickets, activeTickets } = current
|
|
209
|
+
|
|
210
|
+
const conditionImplicitTickets = usedImplicitTickets < maxImplicitTickets
|
|
211
|
+
const conditionActiveTickets = activeTickets > 0
|
|
212
|
+
|
|
213
|
+
if(conditionImplicitTickets){
|
|
214
|
+
return `You have ${maxImplicitTickets - usedImplicitTickets}/${maxImplicitTickets} Implicit Tickets`
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if(conditionActiveTickets){
|
|
218
|
+
return `You used all Implicit Tickets in this period, but you have ${activeTickets} active Tickets`
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return `You not have any more tickets, please check T&C to get a chance.`
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export const checkIfNowIsBetween = (current) => {
|
|
225
|
+
|
|
226
|
+
const { startTime, endTime } = current
|
|
227
|
+
|
|
228
|
+
const getTime = (timeString: string) => (new Date(timeString)).getTime()
|
|
229
|
+
const nowTime = (new Date()).getTime()
|
|
230
|
+
|
|
231
|
+
const condition =
|
|
232
|
+
getTime(startTime) < nowTime && nowTime < getTime(endTime)
|
|
233
|
+
|
|
234
|
+
return condition
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export const getSpinContainerSelector = (pointerMode: PointerMode) => {
|
|
238
|
+
switch(pointerMode){
|
|
239
|
+
case PointerMode.Arrow: return 'g.Partitions'
|
|
240
|
+
case PointerMode.Partition: return 'g.Pointer'
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export const findDegWithPointerMode = (index: number, length: number, pointerMode: PointerMode) => {
|
|
245
|
+
switch(pointerMode){
|
|
246
|
+
case PointerMode.Arrow:
|
|
247
|
+
return findDeg(length - index, length) // + randomInSection(length)
|
|
248
|
+
case PointerMode.Partition:
|
|
249
|
+
return findDeg(index, length)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export const spin = async (container: Element, deg: number, rotation: string, duration: string) => {
|
|
254
|
+
|
|
255
|
+
const _duration = Number(duration)
|
|
256
|
+
const _rotation = Number(rotation)
|
|
257
|
+
|
|
258
|
+
const props = getStatePropsForSpin(deg, _rotation, _duration)
|
|
259
|
+
|
|
260
|
+
setProps(container, props.before)
|
|
261
|
+
|
|
262
|
+
await delay(_duration)
|
|
263
|
+
|
|
264
|
+
setProps(container, props.after)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export const getSpinCondition = (lotteryProgramForPlayer: LotteryProgramForPlayer) => {
|
|
268
|
+
const { current } = lotteryProgramForPlayer
|
|
269
|
+
if(!current) return false;
|
|
270
|
+
|
|
271
|
+
const condition =
|
|
272
|
+
current.activeTickets === 0 &&
|
|
273
|
+
current.usedImplicitTickets === current.maxImplicitTickets
|
|
274
|
+
|
|
275
|
+
return condition
|
|
276
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
interface ImageSize {
|
|
3
|
+
width: number
|
|
4
|
+
height: number
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const renderSvgImageProps = (center: number, href: string, size: ImageSize, offset = {x: 0, y: 0}) => ({
|
|
8
|
+
x: center - size.width / 2 - offset.x,
|
|
9
|
+
y: center - size.height / 2 - offset.y,
|
|
10
|
+
width: size.width,
|
|
11
|
+
height: size.height,
|
|
12
|
+
href,
|
|
13
|
+
})
|