-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
291 lines (256 loc) · 13.7 KB
/
index.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
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interval timer</title>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#eeeeee">
<meta name="theme-color" content="#eeeeee">
</head>
<body ontouchstart="">
<header>
<img id="logo" src="./logo-light.png" height="40" alt="Timeout - The interval timer app">
<span>Beta - v1.0</span>
<!-- <button id="themeToggle" class="theme-btn"><span>☾</span></button> -->
</header>
<main>
<!-- Timer -->
<div class="timer">
<canvas class="timer__canvas" id="timerCanvas"></canvas>
<button class="timer__start btn btn--icon" id="startTimer">
<svg viewBox="-3 0 28 28" xmlns="http://www.w3.org/2000/svg">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icon-Set-Filled" transform="translate(-419 -571)" fill="#000">
<path
d="m440.415 583.554-18.997-12.243c-1.127-.607-2.418-.544-2.418 1.635v24.108c0 1.992 1.385 2.306 2.418 1.635l18.997-12.243a2.076 2.076 0 0 0 0-2.892"
id="play" />
</g>
</g>
</svg>
Start
</button>
<button class="timer__stop btn btn--icon" id="stopTimer">
<svg viewBox="0 0 28 28" xmlns="http://www.w3.org/2000/svg">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icon-Set-Filled" transform="translate(-520 -571)" fill="#000">
<path d="M546 571h-24a2 2 0 0 0-2 2v24a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2v-24a2 2 0 0 0-2-2" id="stop" />
</g>
</g>
</svg>
Stop
</button>
<button class="timer__mute btn btn--ghost btn--icon" id="muteTimer" data-muted="true">
<svg viewBox="0 -3 30 30" xmlns="http://www.w3.org/2000/svg">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icon-Set-Filled" transform="translate(-311 -573)" fill="#000">
<path
d="m336.444 585 4.173-4.173c.45-.45.492-1.139.094-1.538-.399-.398-1.088-.356-1.538.094L335 583.556l-4.173-4.173c-.45-.45-1.139-.492-1.538-.094-.398.399-.356 1.088.094 1.538l4.173 4.173-4.173 4.173c-.45.45-.492 1.139-.094 1.538.399.398 1.088.356 1.538-.094l4.173-4.173 4.173 4.173c.45.45 1.139.492 1.538.094.398-.399.356-1.088-.094-1.538L336.444 585ZM325 573l-7 4.667v14.666l7 4.667a2 2 0 0 0 2-2v-20a2 2 0 0 0-2-2Zm-14 8v8a2 2 0 0 0 2 2h3v-12h-3a2 2 0 0 0-2 2Z"
id="volume-muted" />
</g>
</g>
</svg>
Mute timer
</button>
</div>
<p id="output" class="output"></p>
<p class="instructions">Set your timer and hit 'Start' for your workout.</p>
<!-- Timer customisation -->
<details id="customise" class="c-accordion">
<summary><span>Customise timer</span></summary>
<div class="content">
<div class="c-formInputs">
<!-- Countdown -->
<fieldset class="c-formField c-formField--countdown">
<label for="countdown" class="c-formField-inputContainer">
<span class="c-formField-label">Countdown</span>
<input type="number" name="countdown" id="countdown" min="0" placeholder="In seconds">
</label>
</fieldset>
<!-- Sets and rest between -->
<fieldset class="c-formField c-formField--sets">
<label for="sets" class="c-formField-inputContainer">
<span class="c-formField-label">Sets</span>
<input type="number" name="sets" id="sets" min="1" placeholder="Total loops">
</label>
</fieldset>
<fieldset class="c-formField c-formField--setsRest">
<label for="restBetweenSets" class="c-formField-inputContainer">
<span class="c-formField-label">Rest after sets</span>
<input type="number" name="restBetweenSets" id="restBetweenSets" min="0" placeholder="In seconds">
</label>
</fieldset>
<!-- Rounds -->
<fieldset class="c-formField c-formField--rounds">
<label for="rounds" class="c-formField-inputContainer">
<span class="c-formField-label">Rounds</span>
<input type="number" name="rounds" id="rounds" min="1" placeholder="Total interval loops in the set">
</label>
</fieldset>
</div>
<!-- Container to hold interval input fields -->
<div class="intervals" id="intervalContainer">
<fieldset class="intervalFieldset c-formField c-formField--interval">
<label class="c-formField-intervalLabel c-formField-label c-formField-label--large">Interval 1: </label>
<div class="c-formField-intervalName">
<label class="c-formField-label" for="intervalName">Name:</label>
<input type="text" name="intervalName" placeholder="-" minlength="1">
</div>
<div class="c-formField-intervalDuration">
<label class="c-formField-label" for="intervalDuration">Duration:</label>
<input class="c-formField-intervalDuration" name="intervalDuration" type="number" placeholder="In seconds"
min="1">
</div>
<input class="c-formField-intervalColor" type="color" value="#01FF70">
<button class="deleteInterval btn btn--ghost c-formField-intervalDelete">Delete</button>
</fieldset>
</div>
<!-- Buttons to add intervals and control the timer -->
<div class="content__buttons">
<button id="addInterval" class="btn btn-outline">+ Add Interval</button>
<button id="createURL" class="btn save">Save timer</button>
</div>
</div>
</details>
<details id="premade" class="c-accordion">
<summary><span>Example timers</span></summary>
<div class="content premade">
<a href="?config=N4IglgdgLgpgTgNwIYBsDOIBcBtUEkC2MWIA6gPZwDWIANCACYCucSUY5EWATAAz%2B96AY3IpKJAMQAWAKwAzOQGYAHCAC%2BtPIWKYQAJRhoodRizYcumAIwDBIEWLiSFUgOxv1AXXpxyTCAwYmMrCftAM5ADuEAAiZuycWDYC9GgwUEFSPoZQAELpkTAwEADK6WhxrAmWMrZqQA"
class="card">
<span class="card__title">Tabatas</span>
<span class="card__description">A traditional tabata-style workout. This consists of 20 second work intervals
followed by 10 seconds of rest.</span>
</a>
<a href="?config=N4IglgdgLgpgTgNwIYBsDOIBcBtUEkC2MWIA8hCADQgAmArnElGAPYWYDsADD9QMYsULOCQDEAVhoAzKeIBMIAL6U8hYpjIyqtBk1bsAzDy79BwsTPnylAXWpwWdCDQyYAjCZACnUGiwDuEAAiusxsWB7G1GgwUK4G9jBoUABCsf4wMBAAyrFoIYxh7G4AHMZcikA"
class="card">
<span class="card__title">7/3 Hangboard repeaters</span>
<span class="card__description">A classic hangboard workout for improving the strength and conditioning of
your fingers. Popular amongst climbers, this style of workout consists of 7 second work intervals followed
by 3 seconds of rest.</span>
</a>
</div>
</details>
<details id="guide" class="c-accordion">
<summary><span>Guide</span></summary>
<div class="guide content">
<h1>User Guide</h1>
<p>Welcome! This app provides you with a free way to create your own custom interval-based workouts. You don't
have to create an account, share your data or pay anything. There will never be any analytics or advertising
either.</p>
<p>In addition to being free, this app is shareable. Any timer you create can be shared simply by pressing
<code>Save</code> and sending the link to whoever you want.
</p>
<p>Below is a step-by-step guide to help you set up and use the timer.</p>
<p>Note: This app is current in beta. This means there could be bugs or missing features. There are already
plans to extend the app to allow you to create more granular, advanced workouts!</p>
<hr>
<h2>Glossary</h2>
<dl>
<dt>Countdown</dt>
<dd>It's the initial timer that starts before your workout begins. It gives you time to prepare before diving
into your exercises.</dd>
<dt>Sets</dt>
<dd>A set consists of multiple rounds of intervals. Once all rounds in a set are completed, there might be a
rest period before moving to the next set.</dd>
<dt>Rounds</dt>
<dd>Each round contains a sequence of intervals. Once all intervals in a round are finished, the next round
begins until all rounds in the set are completed.</dd>
<dt>Intervals</dt>
<dd>An interval is a specific duration of exercise or activity. For instance, you might have an interval for
jogging for 1 minute and another interval for walking for 30 seconds.</dd>
<dt>Rest Between Sets</dt>
<dd>After completing all rounds in a set, you might want to rest before starting the next set. This duration
is
the rest between sets.</dd>
</dl>
<hr>
<h2>Using the Timer</h2>
<ul>
<li><strong>Starting the Timer</strong>: Click on the <code>Start</code> button to begin the timer based on
the
intervals and settings you've set up.</li>
<li><strong>Stopping the Timer</strong>: Click on the <code>Stop</code> button to halt the timer, resetting it
to its initial state.</li>
</ul>
<hr>
<h2>Customizing Your Timer</h2>
<p>Click on the dropdown labeled <code>Customise timer</code> to begin customizing your timer.</p>
<h3>Setting up a Countdown</h3>
<ol>
<li>Look for the field labeled <code>Countdown (seconds):</code>.</li>
<li>Input the number of seconds you'd like the timer to count down from before starting the intervals.</li>
</ol>
<h3>Configuring Sets and Rests</h3>
<ol>
<li>Find the field labeled <code>Sets:</code>.</li>
<li>Input the number of sets you'd like to complete.</li>
<li>In the <code>Rest between sets (seconds):</code> field, input the duration of the rest you'd like between
each set.</li>
</ol>
<h3>Configuring Rounds</h3>
<ol>
<li>Find the field labeled <code>Rounds:</code>.</li>
<li>Input the number of rounds you'd like to complete per set.</li>
</ol>
<h3>Setting up Intervals</h3>
<ol>
<li>In the <code>Interval</code> section, provide a name for the interval in the <code>Name</code> input
field.
</li>
<li>Input the duration of the interval in seconds.</li>
<li>Choose a color for the interval using the color picker. This color will be used as a background when the
interval is active.</li>
<li>To add more intervals, click on the <code>+ Add Interval</code> button. This will create a new set of
fields
for another interval.</li>
<li>If you want to delete an interval, click the <code>Delete</code> button. This will remove the interval
from your list.</li>
<li>Repeat the above steps for each new interval.</li>
</ol>
<hr>
<h2>Saving Your Timer</h2>
<p>Click on the <code>Save timer</code> button under <code>Customise timer</code>. This will save your timer
settings in
the URL. You can bookmark this URL or share it with others. When you or anyone else opens this URL, the timer
will be pre-configured with the settings you saved.</p>
<hr>
<h2>Loading a Timer</h2>
<p>If you have a URL with pre-configured timer settings, simply paste it into your browser's address bar and hit
Enter. The timer will load with the settings embedded in the URL.</p>
<hr>
<h2>Tips</h2>
<ul>
<li>There are some example timer workouts ready to use under the <code>Example timers</code> dropdown.</li>
<li>For a clearer understanding of the remaining time, the timer displays minutes, seconds, and milliseconds.
</li>
<li>The current round and set are displayed on the bottom right and top left of the timer, respectively.</li>
<li>The name of the current interval appears on the bottom left of the timer.</li>
<li>Should any issues or errors arise while setting up the timer, a message displays below the timer.</li>
</ul>
<p>Enjoy your workout! 🏋️♀️🏃♂️🧘♀️</p>
</div>
</details>
<!-- Load timer -->
<!-- <details id="load">
<summary><span>(Optional) Load from QR code</span></summary>
<p>You can load a timer either by scanning a QR code using your camera, or directly uploading one you've saved!</p>
<p>Note: Scanning QR codes displayed on a screen can be inconsistent depending on camera quality and lighting.</p>
<br>
<input type="file" id="uploadQR" accept="image/*" style="display: none;">
<label for="uploadQR" style="cursor: pointer;">Upload QR Code</label>
<br>
<button id="scanQR">Scan QR</button>
<video style="display: none;" id="preview"></video>
</details> -->
</main>
<footer>
<p>Created with ♥ by <a href="https://www.jamieomaguire.com/">Jamie Maguire</a></p>
<p class="copyright">© Copyright 2023 Jamie Maguire</p>
</footer>
<script type="module" src="/main.js"></script>
</body>
</html>