-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathcountdown-timer.js
139 lines (124 loc) · 3.87 KB
/
countdown-timer.js
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
// Functions for countdown timer
digits = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
const FULL_DASH_ARRAY = 283;
const WARNING_THRESHOLD = 30;
const ALERT_THRESHOLD = 10;
const COLOR_CODES = {
info: {
color: "green"
},
warning: {
color: "orange",
threshold: WARNING_THRESHOLD
},
alert: {
color: "red",
threshold: ALERT_THRESHOLD
}
};
var countdown_timer = null;
var TIME_LIMIT;
var last; // timestamp of the last updateTimer() call
var timeElapsed;
var timeLeft;
var remainingPathColor = COLOR_CODES.info.color;
var digitObjects;
var min;
var sec;
function startTimer(TIME_LIMIT) {
// Initialize variables
last = 0; // timestamp of the last updateTimer() call
timeElapsed = -1;
timeLeft = TIME_LIMIT;
// For zero-th second
digitObjects = qsa('.digit');
min = [digitObjects[0], digitObjects[1]];
sec = [digitObjects[2], digitObjects[3]];
drawMinute(timeLeft);
drawSecond(timeLeft);
// Update timer every second
countdown_timer = requestAnimationFrame(updateTimer);
}
function updateTimer(now) {
// Update timer every second
if ((last == 0) || (now - last) >= 1000) {
last = now;
timeElapsed++;
timeLeft = TIME_LIMIT - timeElapsed;
drawMinute(timeLeft);
drawSecond(timeLeft);
if (!useProgressBar) {
setCircleDasharray();
setRemainingPathColor(timeLeft);
}
if (timeLeft == 0) {
pauseTimer();
endGame();
return;
}
}
cancelAnimationFrame(countdown_timer);
countdown_timer = requestAnimationFrame(updateTimer);
}
function formatTime(time) {
// Convert a string of seconds into a string of MM:SS format
var m = Math.floor(time / 60);
var s = Math.floor(time % 60);
m = (m < 10) ? ("0" + m) : m;
s = (s < 10) ? ("0" + s) : s;
return `${m}:${s}`;
}
function pauseTimer() {
cancelAnimationFrame(countdown_timer);
if (useProgressBar) {
pauseProgressBar();
}
id("pause-btn").disabled = true;
id("resume-btn").disabled = false;
$("#alert-pause").slideDown("slow");
}
function resumeTimer() {
countdown_timer = requestAnimationFrame(updateTimer);
if (useProgressBar) {
resumeProgressBar();
}
id("pause-btn").disabled = false;
id("resume-btn").disabled = true;
$("#alert-pause").slideUp("200");
}
function setRemainingPathColor(timeLeft) {
const { alert, warning, info } = COLOR_CODES;
if (timeLeft <= alert.threshold) {
id("base-timer-path-remaining").classList.remove(warning.color);
id("base-timer-path-remaining").classList.add(alert.color);
} else if (timeLeft <= warning.threshold) {
id("base-timer-path-remaining").classList.remove(info.color);
id("base-timer-path-remaining").classList.add(warning.color);
}
}
function calculateTimeFraction() {
// Reduce the length of the ring gradually during the countdown to avoid the additional 1s needed
// to actually animate the ring to zero, when the value of timeLeft is set to zero
const rawTimeFraction = timeLeft / TIME_LIMIT;
if (timeLeft == 1) {
return 0;
} else {
return rawTimeFraction - (1 / TIME_LIMIT) * (1 - rawTimeFraction);
}
}
function setCircleDasharray() {
const circleDasharray = `${(calculateTimeFraction() * FULL_DASH_ARRAY).toFixed(0)} 283`;
id("base-timer-path-remaining").setAttribute("stroke-dasharray", circleDasharray);
}
function drawMinute(time) {
drawDigits(min, Math.floor(time / 60));
}
function drawSecond(time) {
drawDigits(sec, Math.floor(time % 60));
}
function drawDigits(timeArray, time) {
var tens = Math.floor(time / 10);
var units = Math.floor(time % 10);
timeArray[0].className = "digit " + digits[tens];
timeArray[1].className = "digit " + digits[units];
}