1
+ <!doctype html>
2
+ < html >
3
+ < head >
4
+ < meta charset ="utf-8 "/>
5
+ < title > 简单转盘</ title >
6
+ < style >
7
+ * {
8
+ margin : 0 ;
9
+ padding : 0 ;
10
+ }
11
+ html , body {
12
+ height : 100% ;
13
+ }
14
+ ul {
15
+ list-style : none;
16
+ }
17
+
18
+ @keyframes white-to-yellow {
19
+ 0% {
20
+ background : # fff ;
21
+ }
22
+ 100% {
23
+ background : # d7a945 ;
24
+ }
25
+ }
26
+ @keyframes heartbeat {
27
+ 0% {
28
+ transform : scale (1 );
29
+ }
30
+ 25% {
31
+ transform : scale (0.8 );
32
+ }
33
+ 50% {
34
+ transform : scale (1.2 );
35
+ }
36
+ 75% {
37
+ transform : scale (0.9 );
38
+ }
39
+ 100% {
40
+ transform : scale (1 );
41
+ }
42
+ }
43
+
44
+ .turntable-wrap {
45
+ position : relative;
46
+ overflow : hidden;
47
+ margin : 50px ;
48
+ width : 340px ;
49
+ height : 340px ;
50
+ border : 7px solid # b2a98d ;
51
+ border-radius : 50% ;
52
+ box-shadow : 0 0 20px # b2a98d ;
53
+ }
54
+ .turntable-wrap .light {
55
+ position : absolute;
56
+ top : 0 ;
57
+ left : 0 ;
58
+ width : 100% ;
59
+ height : 100% ;
60
+ background : # e0ddd1 ;
61
+ animation : rotate 5s linear infinite;
62
+ }
63
+ .turntable-wrap .light span {
64
+ position : absolute;
65
+ top : 0 ;
66
+ left : 0 ;
67
+ right : 0 ;
68
+ margin : 0 auto;
69
+ width : 10px ;
70
+ height : 100% ;
71
+ border-radius : 50% ;
72
+ transform-origin : center center;
73
+ }
74
+ .turntable-wrap .light span : before {
75
+ content : '' ;
76
+ position : absolute;
77
+ top : 5px ;
78
+ left : 0 ;
79
+ right : 0 ;
80
+ margin : 0 auto;
81
+ width : 10px ;
82
+ height : 10px ;
83
+ border-radius : 50% ;
84
+ }
85
+ .turntable-wrap .light span : nth-of-type (even ): before {
86
+ background : # fff ;
87
+ animation : white-to-yellow 1s linear infinite;
88
+ }
89
+ .turntable-wrap .light span : nth-of-type (odd ): before {
90
+ background : # d7a945 ;
91
+ animation : white-to-yellow 1s linear reverse infinite;
92
+ }
93
+
94
+ .turntable-wrap .turntable {
95
+ position : absolute;
96
+ margin : 20px ;
97
+ width : 300px ;
98
+ height : 300px ;
99
+ border-radius : 50% ;
100
+ background : # fff ;
101
+ }
102
+ .turntable-wrap .turntable .bg {
103
+ position : absolute;
104
+ top : 0 ;
105
+ left : 0 ;
106
+ width : 100% ;
107
+ height : 100% ;
108
+ background : # fff ;
109
+ border : 1px solid # dfd8be ;
110
+ border-radius : 50% ;
111
+ transform : rotate (90deg );
112
+ }
113
+ .turntable-wrap .turntable .bg li {
114
+ position : absolute;
115
+ top : 0 ;
116
+ left : 0 ;
117
+ right : 0 ;
118
+ margin : 0 auto;
119
+ width : 1px ;
120
+ height : 100% ;
121
+ background : # dfd8be ;
122
+ transform-origin : center center;
123
+ }
124
+
125
+ .turntable-wrap .turntable .gift {
126
+ position : relative;
127
+ width : 100% ;
128
+ height : 100% ;
129
+ transform : rotate (45deg );
130
+ }
131
+ .turntable-wrap .turntable .gift li {
132
+ position : absolute;
133
+ top : 5% ;
134
+ left : 5% ;
135
+ width : 45% ;
136
+ height : 45% ;
137
+ transform-origin : right bottom;
138
+ }
139
+ .turntable-wrap .turntable .gift li span {
140
+ position : absolute;
141
+ top : 0 ;
142
+ left : 0 ;
143
+ right : 0 ;
144
+ bottom : 0 ;
145
+ display : block;
146
+ width : 50px ;
147
+ height : 70px ;
148
+ margin : auto;
149
+ background : yellow;
150
+ transform : rotate (-45deg );
151
+ text-align : center;
152
+ line-height : 80px ;
153
+ border-radius : 5px ;
154
+ background : # f23c3c ;
155
+ color : # fff ;
156
+ font-size : 24px ;
157
+ }
158
+ .turntable-wrap .turntable .gift li : not (.no-gift ) span : before {
159
+ content : '' ;
160
+ position : absolute;
161
+ top : 15px ;
162
+ left : 0 ;
163
+ width : 50px ;
164
+ height : 1px ;
165
+ background : # fff ;
166
+ }
167
+ .turntable-wrap .turntable .gift li .no-gift span {
168
+ background : # fff ;
169
+ line-height : 70px ;
170
+ color : # bfa74f ;
171
+ font-size : 12px ;
172
+ }
173
+
174
+ .turntable-wrap .pointer {
175
+ box-sizing : border-box;
176
+ position : absolute;
177
+ top : 50% ;
178
+ left : 0 ;
179
+ right : 0 ;
180
+ margin : -23px auto;
181
+ width : 46px ;
182
+ height : 46px ;
183
+ border-radius : 50% ;
184
+ background : # fff ;
185
+ border : 5px solid # fff ;
186
+ box-shadow : 0 0 0 5px # b9a046 ;
187
+ text-align : center;
188
+ line-height : 16px ;
189
+ color : # b9a046 ;
190
+ font-size : 14px ;
191
+ font-weight : 700 ;
192
+ cursor : pointer;
193
+ }
194
+ .turntable-wrap .pointer : before {
195
+ content : '' ;
196
+ position : absolute;
197
+ top : -58px ;
198
+ left : 0 ;
199
+ right : 0 ;
200
+ margin : 0 auto;
201
+ width : 0 ;
202
+ border-style : solid;
203
+ border-color : transparent transparent # b9a046 transparent;
204
+ border-width : 25px 10px 25px 10px ;
205
+ }
206
+ </ style >
207
+ </ head >
208
+ < body >
209
+ < div class ="turntable-wrap ">
210
+ < div class ="light " id ="turntable_light "> </ div >
211
+ < div class ="turntable " id ="turntable ">
212
+ < ul class ="bg " id ="turntable_bg "> </ ul >
213
+ < ul class ="gift " id ="turntable_gift "> </ ul >
214
+ </ div >
215
+ < div class ="pointer disabled " id ="turntable_pointer "> 点击抽奖</ div >
216
+ </ div >
217
+
218
+ < script >
219
+ // 单例模式,转盘唯一,用对象字面量方式表示
220
+ let turntable = {
221
+ itemNum : 6 , // 转盘平均分几块
222
+
223
+ lightNum : 18 , // 转盘上的灯
224
+ light : null , // 转盘旋转灯容器
225
+
226
+ turntable : null , // 转盘
227
+
228
+ bg : null , // 转盘背景
229
+
230
+ gift : null , // 转盘上的中奖结果图
231
+
232
+ pointer : null , // 转盘指针
233
+
234
+ lottery : [ ] , // 中奖数据
235
+
236
+ typeMap : { 1 : '¥' , 2 : '谢谢参与' } ,
237
+ typeClassMap : { 1 : '' , 2 : 'no-gift' } ,
238
+
239
+ isGoing : false , // 游戏是否开始
240
+
241
+ init ( ) {
242
+ if ( ! this . lottery . length ) {
243
+ this . pointer . style . display = 'none' ;
244
+ throw new Error ( '请设置中奖结果数据' ) ;
245
+ }
246
+
247
+ // 初始化灯
248
+ let lightFragment = document . createDocumentFragment ( ) ;
249
+ for ( let i = 0 ; i < this . lightNum ; i ++ ) {
250
+ let lightItem = document . createElement ( 'span' ) ;
251
+ let deg = ( 360 / this . lightNum ) * i
252
+ lightItem . style . transform = `rotate(${ deg } deg)` ;
253
+ lightFragment . appendChild ( lightItem ) ;
254
+ }
255
+ this . light . appendChild ( lightFragment ) ;
256
+
257
+ // 初始化转盘背景、转盘上的中奖图(用不同背景色代替)
258
+ let bgFragment = document . createDocumentFragment ( ) ;
259
+ let bgItemWidth = this . bg . offsetWidth / this . num ;
260
+ let giftFragment = document . createDocumentFragment ( ) ;
261
+ for ( let i = 0 ; i < this . itemNum ; i ++ ) {
262
+ let bgItem = document . createElement ( 'li' ) ;
263
+ let deg = ( 360 / this . itemNum ) * i
264
+ bgItem . style . transform = `rotate(${ deg } deg)` ;
265
+ bgFragment . appendChild ( bgItem ) ;
266
+
267
+ let giftItem = document . createElement ( 'li' ) ;
268
+ giftItem . style . transform = `rotate(${ deg } deg)` ;
269
+ giftItem . className = this . typeClassMap [ this . lottery [ i ] . type ] ;
270
+ let span = document . createElement ( 'span' ) ;
271
+ span . innerHTML = this . typeMap [ this . lottery [ i ] . type ] ;
272
+ giftItem . appendChild ( span ) ;
273
+ giftFragment . appendChild ( giftItem )
274
+ }
275
+ this . bg . appendChild ( bgFragment ) ;
276
+ this . gift . appendChild ( giftFragment ) ;
277
+
278
+ // 给点击抽奖按钮添加点击事件
279
+ this . pointer . onclick = this . gameStart . bind ( this )
280
+ } ,
281
+
282
+ gameStart ( ) {
283
+ if ( this . isGoing ) {
284
+ return
285
+ }
286
+ this . isGoing = true ;
287
+
288
+ // 1. 随机中奖结果
289
+ // 从1-100之间得到一个随机数,看这个随机数在中奖设置的范围,得到最终中奖的项
290
+ let randomRate = ~ ~ ( Math . random ( ) * 100 ) // ~~ == Math.floor()
291
+ // 设置中奖数据的概率范围
292
+ let num = 0
293
+ this . lottery . forEach ( item => {
294
+ item . min = num ;
295
+ num += item . rate ;
296
+ item . max = num ;
297
+ } )
298
+ // 根据随机数,得到中奖结果
299
+ let res = this . lottery . filter ( item => {
300
+ return randomRate >= item . min && randomRate < item . max ;
301
+ } ) [ 0 ] ;
302
+ // 这儿可以根据实际情况,可重置中奖结果
303
+
304
+ // 2. 计算旋转角度, 需要多转5圈,达转1圈用时1s, 到旋转的效果
305
+ let rotateItemDeg = ( res . location - 1 ) * ( 360 / this . lottery . length ) ; // 每个item旋转角度, 第一个不用旋转
306
+ let rotate = rotateItemDeg + 5 * 360 ;
307
+ let rotateSpeed = ( rotateItemDeg / 360 * 1 + 5 ) . toFixed ( 2 ) ;
308
+ // 重置转盘样式
309
+ this . turntable . removeAttribute ( 'style' ) ;
310
+ // 保证下一次旋转动画生效
311
+ setTimeout ( ( ) => {
312
+ this . turntable . style . transform = `rotate(${ rotate } deg)` ;
313
+ this . turntable . style . transition = `transform ${ rotateSpeed } s ease-out` ;
314
+ } , 10 )
315
+
316
+ // 3. 动画结束,显示中奖结果,中奖结果如何显示,视实际情况而定
317
+ setTimeout ( ( ) => {
318
+ this . isGoing = false ;
319
+ console . log ( '中奖结果:' , randomRate , res , this . typeMap [ res . type ] ) ;
320
+ } , rotateSpeed * 1000 ) ;
321
+ }
322
+ }
323
+
324
+ let lottery = [
325
+ {
326
+ location : 1 , // 位置
327
+ type : 1 , // 中奖
328
+ rate : 30 ,
329
+ } ,
330
+ {
331
+ location : 2 ,
332
+ type : 2 , // 未中奖
333
+ rate : 20
334
+ } ,
335
+ { location : 3 , type : 1 , rate : 10 } ,
336
+ { location : 4 , type : 2 , rate : 20 } ,
337
+ { location : 5 , type : 1 , rate : 10 } ,
338
+ { location : 6 , type : 2 , rate : 10 }
339
+ ] ;
340
+
341
+ turntable . turntable = document . querySelector ( '#turntable' ) ;
342
+ turntable . light = document . querySelector ( '#turntable_light' ) ;
343
+ turntable . bg = document . querySelector ( '#turntable_bg' ) ;
344
+ turntable . gift = document . querySelector ( '#turntable_gift' ) ;
345
+ turntable . pointer = document . querySelector ( '#turntable_pointer' ) ;
346
+ turntable . lottery = lottery ;
347
+ turntable . init ( ) ;
348
+ </ script >
349
+ </ body >
350
+ </ html >
0 commit comments