-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex-zh.html
More file actions
463 lines (404 loc) · 17.3 KB
/
Copy pathindex-zh.html
File metadata and controls
463 lines (404 loc) · 17.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
<!doctype html>
<!--
____ __ __ __ __
/\ _`\ /\ \/\ \/\ \/\ \
\ \ \/\_\ __ ___ __ _ __ \ \ \_\ \ \ \/'/'
\ \ \/_/_ /'__`\ /' _ `\ /'__`\/\`'__\ \ \ _ \ \ , <
\ \ \L\ \/\ \L\.\_/\ \/\ \/\ __/\ \ \/ \ \ \ \ \ \ \\`\
\ \____/\ \__/.\_\ \_\ \_\ \____\\ \_\ \ \_\ \_\ \_\ \_\
\/___/ \/__/\/_/\/_/\/_/\/____/ \/_/ \/_/\/_/\/_/\/_/
COPYRIGHT © Caner HK 2025
https://github.com/Caner-HK/Randomrizer-LuckyOne
-->
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no" />
<meta name="renderer" content="webkit" />
<meta name="force-rendering" content="webkit" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<link rel="stylesheet" href="https://resource.caner.hk/get/mdui/css/mdui.min.css" />
<link href="https://resource.caner.hk/get/josefin_sans/get.css" rel="stylesheet">
<title>随机抽取幸运儿</title>
<style>
body {
font-family: 'Josefin Sans', sans-serif;
}
.rounded {
border-radius: 6px;
}
.custom-container {
padding-left: 15px;
padding-right: 15px;
display: flex;
justify-content: center;
align-items: center;
min-height: 93vh;
}
.mdui-card {
width: 100%;
max-width: 700px;
}
.action-container {
display: flex;
align-items: center;
}
.full-container {
margin: 0px;
}
#excludeCheckboxes {
padding-left: 24px;
max-height: 300px;
overflow-y: auto;
padding-top: 10px;
}
</style>
</head>
<body class="mdui-theme-primary-blue mdui-theme-accent-amber mdui-theme-layout-auto">
<div class="custom-container">
<div class="mdui-card rounded">
<!-- Loading Progress -->
<div id="loadingProgress" class="mdui-progress" style="display: none;">
<div class="mdui-progress-indeterminate"></div>
</div>
<!-- Normal Progress -->
<div id="normalProgress" class="mdui-progress">
<div class="mdui-progress-determinate" style="width: 100%;"></div>
</div>
<!-- 卡片标题 -->
<div class="mdui-card-primary">
<div class="mdui-card-primary-title mdui-text-color-theme-700">
随机抽取 <span id="number">5 人</span> 作为幸运儿
</div>
<div class="mdui-card-primary-subtitle">
通过随机点名抓取幸运儿参加活动 😁
</div>
</div>
<!-- 卡片内容 -->
<div class="mdui-card-content" style="margin-top: -16px;">
<!-- 设置总人数(默认显示“点击以设置总人数”)-->
<div class="mdui-chip" style="margin-bottom: 8px;" mdui-dialog="{target: '#setCount'}">
<span class="mdui-chip-icon mdui-color-blue">
<i class="mdui-icon material-icons">people</i>
</span>
<span class="mdui-chip-title" id="chipTotalPeople">点击以设置总人数</span>
</div>
<br>
<!-- 设置排除项(默认显示“点击以设置排除项”)-->
<div class="mdui-chip" style="margin-bottom: 8px;" mdui-dialog="{target: '#setExclude'}">
<span class="mdui-chip-icon mdui-color-blue">
<i class="mdui-icon material-icons">people_outlined</i>
</span>
<span class="mdui-chip-title" id="chipExcluded">点击以设置排除项</span>
</div>
<br>
<!-- 设置抽取人数:菜单项根据剩余人数判断可用性 -->
<div class="mdui-chip" mdui-menu="{target: '#example-menu'}">
<span class="mdui-chip-icon mdui-color-amber">
<i class="mdui-icon material-icons">games</i>
</span>
<span class="mdui-chip-title" id="chipContent">选择抽取的人数:5 人</span>
</div>
<ul class="mdui-menu rounded" id="example-menu">
<li class="mdui-menu-item" id="menuItem1" onclick="updateChip(1)">
<a href="javascript:;" class="mdui-ripple">1 人</a>
</li>
<li class="mdui-menu-item" id="menuItem5" onclick="updateChip(5)">
<a href="javascript:;" class="mdui-ripple">5 人</a>
</li>
<li class="mdui-menu-item" id="menuItem10" onclick="updateChip(10)">
<a href="javascript:;" class="mdui-ripple">10 人</a>
</li>
</ul>
<!-- 显示抽取结果 -->
<div class="mdui-typo-headline" style="margin-top: 16px;">本次幸运儿是:</div>
<br>
<strong class="mdui-typo-display-2">
<span id="luckyone" style="line-height: 1;">? ? ? ? ?</span>
</strong>
</div>
<!-- 卡片按钮区 -->
<div class="mdui-card-actions action-container">
<button id="startButton" class="mdui-btn rounded mdui-btn-raised mdui-ripple mdui-color-theme-accent action-item"
onclick="getRandomPeople()" disabled>
<span style="position: relative; top: 1px;">开始</span>
<i class="mdui-icon material-icons">arrow_forward</i>
</button>
<div id="spinnerContainer" class="action-item" style="display:none; margin-left: 24px; margin-right:24px;">
<div class="mdui-spinner mdui-spinner-colorful"></div>
</div>
<button id="saveButton" class="mdui-btn rounded mdui-btn-raised mdui-ripple mdui-color-theme-accent action-item"
onclick="saveResult()" style="display:none;">
<span style="position: relative; top: 1px;">下载结果</span>
<i class="mdui-icon material-icons">file_download</i>
</button>
</div>
</div>
</div>
<!-- 对话框:设置总人数 -->
<div class="mdui-dialog" id="setCount">
<div class="mdui-dialog-title">设置抽取总人数</div>
<div class="mdui-dialog-content">
填写人数,抽取数字将为 1 至 您设置的数字
<div class="mdui-textfield mdui-textfield-floating-label">
<label class="mdui-textfield-label">输入数字</label>
<input class="mdui-textfield-input" id="inputCount" type="number" min="1" />
</div>
</div>
<div class="mdui-dialog-actions">
<button class="mdui-btn mdui-ripple" mdui-dialog-close>取消</button>
<button class="mdui-btn mdui-ripple" mdui-dialog-confirm onclick="setTotalCount()">确定</button>
</div>
</div>
<!-- 对话框:设置排除项 -->
<div class="mdui-dialog" id="setExclude">
<div class="mdui-dialog-title">设置排除列表</div>
<div class="full-container">
<div class="mdui-dialog-content" style="margin-top: -25px; margin-bottom: -16px;">所勾选的数字将被排除在抽取列表外,剩余人数少于抽取人数时将无法抽取</div>
<div id="excludeCheckboxes">
<!-- 动态添加复选框 -->
</div>
</div>
<div class="mdui-dialog-actions">
<button class="mdui-btn mdui-ripple" mdui-dialog-close>取消</button>
<button class="mdui-btn mdui-ripple" mdui-dialog-confirm onclick="setExcludeList()">确定</button>
</div>
</div>
<footer>
<span class="mdui-typo-caption-opacity" style="margin-left:16px; margin-bottom:16px;">
© Caner HK 2025
</span>
<span class="mdui-typo-caption-opacity" style="margin-left:8px; margin-right:8px;">|</span>
<a href="https://github.com/Caner-HK/Randomrizer-LuckyOne" target="_blank" class="mdui-typo-caption-opacity" style="text-decoration: none; color: inherit;">
Github Repo
</a>
</footer>
<script src="https://resource.caner.hk/get/mdui/js/mdui.min.js"></script>
<script>
let totalPeopleCount = 0; // 总人数
let excludedNumbers = []; // 排除列表(由用户通过对话框选择)
let selectedNumber = 5; // 当前选定的“抽几个人”,默认 5 人
document.addEventListener('DOMContentLoaded', function () {
mdui.mutation();
});
/**
* 剩余人数 = totalPeopleCount - excludedNumbers.length
*/
function getLeftoverCount() {
return totalPeopleCount - excludedNumbers.length;
}
/**
* 设置总人数
*/
function setTotalCount() {
const inputVal = document.getElementById('inputCount').value;
if (!inputVal || inputVal <= 0) {
return;
}
totalPeopleCount = parseInt(inputVal, 10);
// 更新显示
document.getElementById('chipTotalPeople').textContent = `数组内序号:1 - ${totalPeopleCount}`;
// 生成“排除列表”对话框的复选框
generateExcludeCheckboxes();
// 重置排除项
excludedNumbers = [];
document.getElementById('chipExcluded').textContent = '点击以设置排除项';
// 菜单项可用性:基于“剩余人数”来判断
toggleMenuItems(getLeftoverCount());
// 检查是否能抽取
checkIfStartButtonEnabled();
// 关闭对话框
const dialog = document.getElementById('setCount');
new mdui.Dialog(dialog).close();
}
/**
* 动态生成复选框(1 ~ totalPeopleCount)
*/
function generateExcludeCheckboxes() {
const container = document.getElementById('excludeCheckboxes');
container.innerHTML = ''; // 先清空
for (let i = 1; i <= totalPeopleCount; i++) {
// 创建 label
const label = document.createElement('label');
label.className = 'mdui-checkbox';
// 创建 input
const input = document.createElement('input');
input.type = 'checkbox';
input.value = i; // 用数字标识自己
// 创建 i
const iTag = document.createElement('i');
iTag.className = 'mdui-checkbox-icon';
// label 的文本节点
const textNode = document.createTextNode(` 数字 ${i}`);
// 拼装
label.appendChild(input);
label.appendChild(iTag);
label.appendChild(textNode);
// 换行
container.appendChild(label);
container.appendChild(document.createElement('br'));
}
}
/**
* 用户点击“确定”时,读取勾选的数字并更新 excludedNumbers
*/
function setExcludeList() {
const container = document.getElementById('excludeCheckboxes');
const checkboxes = container.querySelectorAll('input[type="checkbox"]');
const newExcludes = [];
checkboxes.forEach(chk => {
if (chk.checked) {
newExcludes.push(parseInt(chk.value, 10));
}
});
excludedNumbers = newExcludes;
// 更新 Chip 显示
if (excludedNumbers.length > 0) {
// 排除项格式:已排除 1,3,6 共 3 项
document.getElementById('chipExcluded').textContent = `已排除 ${excludedNumbers.join(', ')} 共 ${excludedNumbers.length} 项`;
} else {
document.getElementById('chipExcluded').textContent = '点击以设置排除项';
}
// 更新菜单项可用性、检查可否抽取
toggleMenuItems(getLeftoverCount());
checkIfStartButtonEnabled();
}
/**
* 根据剩余人数来禁用或启用抽取人数 > 剩余人数 的菜单项
* @param {*} effectiveCount 剩余人数(总人数-排除人数)
*/
function toggleMenuItems(effectiveCount) {
const menuItem1 = document.getElementById('menuItem1');
const menuItem5 = document.getElementById('menuItem5');
const menuItem10 = document.getElementById('menuItem10');
// 先全部移除禁用
[menuItem1, menuItem5, menuItem10].forEach(item => item.classList.remove('mdui-disabled'));
// 如果 effectiveCount < 1,都禁用
if (effectiveCount < 1) {
[menuItem1, menuItem5, menuItem10].forEach(item => item.classList.add('mdui-disabled'));
return;
}
// 如果 < 5,人,则禁用5和10
if (effectiveCount < 5) {
menuItem5.classList.add('mdui-disabled');
menuItem10.classList.add('mdui-disabled');
}
// 如果 < 10 人,则禁用10
else if (effectiveCount < 10) {
menuItem10.classList.add('mdui-disabled');
}
}
/**
* 更新“抽几个人”设置
*/
function updateChip(number) {
const menuItem = document.getElementById(`menuItem${number}`);
if (menuItem.classList.contains('mdui-disabled')) {
// 如果被禁用,给出提示
mdui.snackbar({
message: `剩余人数不足以抽 ${number} 人`,
position: 'left-bottom'
});
return;
}
selectedNumber = number;
document.getElementById('chipContent').textContent = `选择抽取的人数:${number} 人`;
document.getElementById('number').textContent = `${number} 人`;
// 检查是否可以开始
checkIfStartButtonEnabled();
}
/**
* 检查“开始”按钮是否可用:剩余人数 >= selectedNumber
*/
function checkIfStartButtonEnabled() {
// 如果还没设定 totalPeopleCount,或者 totalPeopleCount=0,直接禁用
if (totalPeopleCount <= 0) {
document.getElementById('startButton').disabled = true;
return;
}
const leftover = getLeftoverCount();
// 如果剩余人数 >= 选定抽取人数 => 启用,否则禁用
if (leftover >= selectedNumber) {
document.getElementById('startButton').disabled = false;
} else {
document.getElementById('startButton').disabled = true;
}
}
/**
* 开始抽取
*/
function getRandomPeople() {
// 隐藏开始按钮,显示 spinner
document.getElementById('startButton').style.display = 'none';
document.getElementById('spinnerContainer').style.display = 'block';
// 隐藏 normalProgress,显示 loadingProgress
document.getElementById('normalProgress').style.display = 'none';
document.getElementById('loadingProgress').style.display = 'block';
// 动态更新数字:每100毫秒随机更新
const intervalId = setInterval(() => {
const luckyOneElement = document.getElementById('luckyone');
let randomNumbers = [];
for (let i = 0; i < selectedNumber; i++) {
randomNumbers.push(Math.floor(Math.random() * totalPeopleCount) + 1);
}
luckyOneElement.textContent = randomNumbers.join(', ');
}, 100);
// 3秒后停止闪烁,并给出最终结果
setTimeout(() => {
clearInterval(intervalId);
// 可抽取的数组:剔除排除项
let peopleArray = Array.from({ length: totalPeopleCount }, (_, i) => i + 1)
.filter(num => !excludedNumbers.includes(num));
let leftover = peopleArray.length; // 真正剩余可抽的人数
let luckyOnes = [];
for (let i = 0; i < selectedNumber; i++) {
if (peopleArray.length === 0) break; // 没人可抽则跳出
const randomIndex = Math.floor(Math.random() * peopleArray.length);
luckyOnes.push(peopleArray.splice(randomIndex, 1)[0]);
}
// 显示最终结果
document.getElementById('luckyone').textContent = luckyOnes.join(', ');
// UI 还原
document.getElementById('spinnerContainer').style.display = 'none';
document.getElementById('loadingProgress').style.display = 'none';
document.getElementById('normalProgress').style.display = 'block';
const startButton = document.getElementById('startButton');
startButton.style.display = 'block';
// 改成“再次抽取”状态
startButton.innerHTML = '<span style="position: relative; top: 2px;">再次抽取</span> <i class="mdui-icon material-icons">refresh</i>';
document.getElementById('saveButton').style.display = 'block'; // 显示保存按钮
}, 3000);
}
/**
* 下载抽取结果到 html 文件
*/
function saveResult() {
const luckyNumbers = document.getElementById('luckyone').textContent;
const currentDate = new Date();
const dateString = currentDate.toLocaleDateString('zh-CN'); // 日期
const timeString = currentDate.toLocaleTimeString('zh-CN', { hour12: false }); // 时间
const htmlContent = `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no" />
<title>本次幸运儿</title>
</head>
<body>
<h1>幸运儿序号:<strong> ${luckyNumbers}</strong></h1>
<p>抽取日期: ${dateString}</p>
<p>抽取时间: ${timeString}</p>
<h1>太幸运了吧,你被抽中了😁😁😁</h1>
</body>
</html>`;
const blob = new Blob([htmlContent], { type: 'text/html' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '抽取结果.html';
a.click();
}
</script>
</body>
</html>