Added Timer and About. Also, moved Add operations to top.
This commit is contained in:
parent
34d8172302
commit
80c06e5b76
5 changed files with 172 additions and 10 deletions
BIN
assets/tone.mp3
Normal file
BIN
assets/tone.mp3
Normal file
Binary file not shown.
52
canvas.js
52
canvas.js
|
@ -1,3 +1,5 @@
|
|||
var tone = new Audio("./assets/tone.mp3");
|
||||
|
||||
document.querySelectorAll(".clock").forEach((clock) => {
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
|
@ -8,6 +10,16 @@ document.querySelectorAll(".clock").forEach((clock) => {
|
|||
ctx.lineCap = "round";
|
||||
update();
|
||||
});
|
||||
document.querySelectorAll(".timer").forEach((clock) => {
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.resetTransform();
|
||||
ctx.translate(32, 32);
|
||||
ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--foreground');
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineCap = "round";
|
||||
update();
|
||||
});
|
||||
function update() {
|
||||
document.querySelectorAll(".clock").forEach((clock, i) => {
|
||||
var canvas = clock.querySelector("canvas");
|
||||
|
@ -87,3 +99,43 @@ function updateMain() {
|
|||
}
|
||||
|
||||
window.requestAnimationFrame(updateMain);
|
||||
|
||||
function updateTimer() {
|
||||
document.querySelectorAll(".timer-enabled").forEach((clock, i) => {
|
||||
var timer = clock.dataset.time;
|
||||
var mins = Math.floor(timer / 60);
|
||||
mins = (mins < 10 ? "0" + mins : mins);
|
||||
var secs = timer % 60;
|
||||
secs = (secs < 10 ? "0" + secs : secs);
|
||||
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--foreground');
|
||||
ctx.resetTransform();
|
||||
ctx.translate(32, 32);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineCap = "round";
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
clock.querySelector(".mins").innerHTML = mins;
|
||||
clock.querySelector(".seconds").innerHTML = secs;
|
||||
ctx.clearRect(-32,-32, 64, 64);
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, 30, 0, Math.PI * 2);
|
||||
ctx.stroke();
|
||||
drawHand(ctx, (secs*Math.PI/30), 16);
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(() => {
|
||||
document.querySelectorAll(".timer-enabled:not(.timer-paused)").forEach((clock, i) => {
|
||||
var timer = clock.dataset.time;
|
||||
clock.dataset.time--;
|
||||
if (timer <= 0) {
|
||||
clock.classList.remove("timer-enabled");
|
||||
tone.play();
|
||||
}
|
||||
});
|
||||
updateTimer();
|
||||
}, 1000);
|
||||
updateTimer();
|
62
index.html
62
index.html
|
@ -19,12 +19,14 @@
|
|||
<div class="header">
|
||||
<div>
|
||||
<button class="material-symbols-outlined hiw" data-title="Menu" onclick="this.parentElement.parentElement.classList.toggle('wide')">menu</button>
|
||||
<sep></sep>
|
||||
<button class="material-symbols-outlined" data-title="Add World Clock" onclick="document.querySelector('.header').classList.remove('wide');document.querySelector('.scr-timezone--').classList.add('open');">add_circle</button>
|
||||
<button class="material-symbols-outlined" data-title="Add Timer" onclick="document.querySelector('.header').classList.remove('wide');document.querySelector('.scr-timer--').classList.add('open');">timer</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="material-symbols-outlined" data-title="Add World Clock" onclick="document.querySelector('.header').classList.remove('wide');document.querySelector('.scr-timezone--').classList.add('open');">add_circle</button>
|
||||
<sep></sep>
|
||||
<button class="material-symbols-outlined" data-title="Customize Color" onclick="document.querySelector('.header').classList.remove('wide');document.querySelector('.scr-dialog--').classList.add('open');">palette</button>
|
||||
<button class="material-symbols-outlined" data-title="Open Fullscreen" onclick="openFullscreen();">fullscreen</button>
|
||||
<button class="material-symbols-outlined" data-title="About" onclick="document.querySelector('.header').classList.remove('wide');document.querySelector('.scr-about--').classList.add('open');">info</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
|
@ -136,6 +138,40 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrim-over-- scr-timer--">
|
||||
<div class="dialog" id="timerdia">
|
||||
<p class="dlg-top">Configure Timer</p>
|
||||
<form id="timerform">
|
||||
<!-- <Peter... the="horse" is h=ere /> -->
|
||||
<input type="number" name="minute" placeholder="05" min="00" value="05" /><span>:</span><input type="number" name="second" placeholder="00" min="00" value="00" max="59" />
|
||||
<div>
|
||||
<input type="submit" name="action" value="DONE"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrim-over-- scr-about--">
|
||||
<div class="dialog" id="aboutdia">
|
||||
<p class="dlg-top">About FunnyClock²</p>
|
||||
<form id="aboutform">
|
||||
<!-- FUCK -->
|
||||
<p>FunnyClock² is the successor of FunnyClock, an application made for my school to show when smartboards are idle.</p>
|
||||
<p>FunnyClock was originally a single-file local webpage hosted on the computers of the teachers, and now with FunnyClock², it's a multi-file customizable suite for clocks and timers.</p>
|
||||
<p class="dlg-top">Special Thanks to</p>
|
||||
<ul>
|
||||
<li>Josh, science and tech teacher</li>
|
||||
<li>Everyone who accepted my pitch for the FunnyClock² app</li>
|
||||
<li>Among Us (Sussy background)</li>
|
||||
<li>Portal 2 (Tile background)</li>
|
||||
<li>Kaboom.js (Mark background)</li>
|
||||
<li>Material Design (UI inspiration)</li>
|
||||
</ul>
|
||||
<div>
|
||||
<input type="submit" name="action" value="OK"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrim--" onclick="document.querySelector('.header').classList.remove('wide')"> </div>
|
||||
<script>
|
||||
var elem = document.documentElement;
|
||||
|
@ -191,6 +227,28 @@ document.querySelector("#color").addEventListener("change", (e) => {
|
|||
document.documentElement.style.setProperty('--background-light', colors[2]);
|
||||
})
|
||||
|
||||
document.querySelector("#timerform").addEventListener("submit", (e) => {
|
||||
event.preventDefault();
|
||||
const formData = new FormData(e.target);
|
||||
var time = (parseInt(formData.get("minute")) * 60) + parseInt(formData.get("second"));
|
||||
document.querySelector(".body").insertAdjacentHTML( "beforeend", `<div class="timer timer-enabled" data-time="${time}" data-orig="${time}">
|
||||
<canvas width="64" height="64"></canvas><!--
|
||||
--><div class="labels">
|
||||
<h1 class="time"><span class="mins">00</span>:<span class="seconds">00</span></h1><br />
|
||||
</div><br />
|
||||
<button class="deleteclock material-symbols-outlined" onclick="this.parentElement.remove()">close</button>
|
||||
<button class="normalclock material-symbols-outlined" onclick="this.parentElement.classList.toggle('timer-paused');">pause</button>
|
||||
<button class="normalclock material-symbols-outlined" onclick="this.parentElement.dataset.time = this.parentElement.dataset.orig;this.parentElement.classList.add('timer-enabled');updateTimer()">refresh</button>
|
||||
</div>`);
|
||||
updateTimer();
|
||||
document.querySelector('.scr-timer--').classList.remove('open');
|
||||
})
|
||||
|
||||
document.querySelector("#aboutform").addEventListener("submit", (e) => {
|
||||
event.preventDefault();
|
||||
document.querySelector('.scr-about--').classList.remove('open');
|
||||
})
|
||||
|
||||
document.querySelector("#timezone").addEventListener("submit", (e) => {
|
||||
event.preventDefault();
|
||||
const formData = new FormData(e.target);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.body .clock {
|
||||
.body .clock, .body .timer {
|
||||
width: 100%;
|
||||
min-height: max-content;
|
||||
border-radius: 8px;
|
||||
|
@ -24,7 +24,7 @@
|
|||
zoom: 1.25;
|
||||
}
|
||||
|
||||
.body .clock::before {
|
||||
.body .clock::before, .body .timer::before {
|
||||
content: "";
|
||||
background-color: #FFFFFF40;
|
||||
position: absolute;
|
||||
|
@ -36,9 +36,21 @@
|
|||
z-index: -1;
|
||||
}
|
||||
|
||||
.body .timer-paused::before {
|
||||
content: "";
|
||||
background-color: #40404040;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
backdrop-filter: blur(8px);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
|
||||
.body .clock h1 {
|
||||
|
||||
.body .clock h1, .body .timer h1 {
|
||||
margin: 0;
|
||||
margin-top: 16px;
|
||||
padding: 0;
|
||||
|
@ -49,12 +61,12 @@
|
|||
|
||||
|
||||
|
||||
.body .clock div.labels {
|
||||
.body .clock div.labels, .body .timer div.labels {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.body .clock div.labels * {
|
||||
.body .clock div.labels *, .body .timer div.labels * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--foreground);
|
||||
|
@ -63,7 +75,7 @@
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.body .clock div.labels .timezone {
|
||||
.body .clock div.labels .timezone, .body .timer div.labels .timezone {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
|
@ -112,3 +124,27 @@ textarea {
|
|||
.deleteclock:active {
|
||||
background-color: #FF0000FF;
|
||||
}
|
||||
|
||||
.normalclock {
|
||||
margin-top: 16px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background-color: #00000040;
|
||||
color: var(--foreground);
|
||||
border-radius: 16px;
|
||||
transition: background-color 0.125s;
|
||||
}
|
||||
|
||||
.normalclock:focus {
|
||||
background-color: #00000030;
|
||||
}
|
||||
|
||||
.normalclock:hover {
|
||||
background-color: #00000010;
|
||||
}
|
||||
|
||||
.normalclock:active {
|
||||
background-color: #00000020;
|
||||
}
|
|
@ -14,7 +14,9 @@
|
|||
|
||||
.dialog {
|
||||
min-width: 320px;
|
||||
max-width: calc(100vw - 64px);
|
||||
min-height: 128px;
|
||||
max-height: calc(100vh - 64px);
|
||||
background-color: var(--background-light);
|
||||
transition: background-color 0.125s;
|
||||
color: var(--foreground);
|
||||
|
@ -22,6 +24,7 @@
|
|||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
pointer-events: auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.dialog p {
|
||||
|
@ -115,3 +118,16 @@ input[type="radio"]:focus + label {
|
|||
background-color: #00000040;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.dialog input[type="number"] {
|
||||
width: 16ch;
|
||||
margin: 8px 0;
|
||||
box-sizing: border-box;
|
||||
height: max-content;
|
||||
max-height: 100%;
|
||||
padding: 8px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background-color: #00000040;
|
||||
color: var(--foreground);
|
||||
}
|
Loading…
Reference in a new issue