-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcountdown.html
95 lines (90 loc) · 3.96 KB
/
countdown.html
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
<!doctype html>
<html lang="en-US">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="description" content="sig-nal countdown demo"/>
<title>sig-nal | countdown demo</title>
<script type=module src="./src/index.js"></script>
</head>
<body>
<count-down style="margin: 5rem auto; box-shadow: 1px 2px 18px 4px #ddd">
<template shadowrootmode="open">
<link rel="stylesheet" href="./countdown.css"/>
<table>
<thead> <tr>
<th>dd</th>
<th>hh</th>
<th>mm</th>
<th>ss</th>
<th>ddd</th>
</tr>
</thead>
<tbody>
<tr>
<td .textContent="days"><sig-nal id="days" new="days">0</sig-nal></td>
<td .textContent="hours"><sig-nal id="hours" new="hours">00</sig-nal></td>
<td .textContent="minutes"><sig-nal id="minutes" new="minutes">2</sig-nal></td>
<td .textContent="seconds"><sig-nal id="seconds" new="seconds">0</sig-nal></td>
<td .textContent="hundredth"><sig-nal id="hundredth" new="hundredth">0</sig-nal></td>
</tr>
</tbody>
</table>
<div hidden .hidden="fireworks" class="pyro">
<sig-nal id="fireworks" new="fireworks" type="number">1</sig-nal>
<div class="before"></div>
<div class="after"></div>
</div>
<script type="module">
// import static class methods from <sig-nal> class
const { hydrate, rerender } = await customElements.whenDefined("sig-nal");
// set up module globals
let timer, signals = {}, last = [];
// hydrate signals gathered from HTML, en passant storing those signals
// (identified via the id="signalName" attribute in HTML) in the signals object
hydrate('hours', {
"days": { ".textContent": rerender},
"hours": { ".textContent": rerender},
"minutes": { ".textContent": rerender},
"seconds": { ".textContent": rerender},
"hundredth": { ".textContent": rerender},
"fireworks": { ".hidden": rerender},
}, signals);
// list parameters of each unit of the countdown: name, subtraction offset, highest state
const units = ['hundredth', 100, '900', 'seconds', 1, '59', 'minutes', 1, '59', 'hours', 1, '23', 'days', 1, '366'];
// count-down update function:
const update = () => {
// for all units from most frequently updated to least frequently updated:
for(let i = 0, n = units.length, unit, name, step, highest; i < n; i += 3) {
// fetch per-unit parameters
name = units[i];
step = units[i + 1];
highest = units[i + 2];
// count down this unit
unit = (signals[name].value | 0) - step;
// and remember its new value in the array of last-updated values
last[i / 3] = Math.abs(unit);
// format new value with the right amount of digits
signals[name].value = `00${unit}`.slice(-1 -(Math.log10(highest | 0) | 0));
// if new value not negative, stop here
if (unit >= 0) break;
// new value would have been negative, reset it to highest value for this unit ...
signals[name].value = highest;
// ... and loop to next unit
}
// did count down reach all-zero end state (sum up last-updated values to determine that state)?
if(last.reduce((a,b) => a + b, 0) === 0) {
// yes, stop counting down
clearInterval(timer);
// start fireworks
signals.fireworks.value = 0;
// after 30 s, stop it again
setTimeout(() => (signals.fireworks.value = 1), 30 * 1000);
}
};
// update count down every 100 milliseconds
timer = setInterval(update, 100);
</script>
</template>
</count-down>
</body>
</html>