ping.clerie.de/index.html

167 lines
4.6 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>ping.clerie.de</title>
<style>
#canvas {
width: 100%;
height: 100%;
display: block;
position: fixed;
top: 0;
left: 0;
z-index: -9999;
}
</style>
</head>
<body>
<h1>ping.clerie.de</h1>
<span id="audio_toggle">🕨</span>
<canvas id="canvas" width="500" height="50"></canvas>
<ul id="ping">
</ul>
<p><small>Is it already broken yet? <a href="https://git.clerie.de/clerie/ping.clerie.de">Host yourself :3</a></small></p>
<script>
function httpGet(url, loaded, error) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url + ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime(), true);
xmlHttp.onload = () => {
loaded();
};
xmlHttp.onerror = () => {error();};
xmlHttp.send(null);
}
function displayPing(text) {
document.getElementById("ping").innerHTML += "<li>" + text + "</li>";
}
let ac;
let gain;
let osc;
let withAudio = false;
let audio_toggle = document.getElementById("audio_toggle");
audio_toggle.onclick = () => {
if (!withAudio) {
ac = new AudioContext();
osc = ac.createOscillator();
gain = ac.createGain();
osc.connect(gain);
gain.connect(ac.destination)
gain.gain.setValueAtTime(0, ac.currentTime);
osc.start();
audio_toggle.innerText = "🕪";
withAudio = true;
} else {
osc.stop();
audio_toggle.innerText = "🕨";
withAudio = false;
}
}
let playing = false;
function beepOn() {
if (!playing) {
if (withAudio) {
gain.gain.setValueCurveAtTime([0,1], ac.currentTime, 0.08);
}
playing = true;
}
}
function beepOff() {
if (playing) {
if (withAudio) {
gain.gain.setValueCurveAtTime([1,0], ac.currentTime, 0.08);
}
playing = false;
}
}
let reachability = [];
let reachability_size = 10;
let cv = document.getElementById("canvas");
cv.width = window.innerWidth;
cv.height = window.innerHeight;
let ctx = canvas.getContext('2d');
let zoom = 10;
function resizeCanvas() {
cv.width = window.innerWidth;
cv.height = window.innerHeight;
}
window.onresize = resizeCanvas;
function plotLoop() {
let currentTime = (new Date()).getTime();
ctx.lineWidth = 4;
ctx.clearRect(0, 0, cv.width, cv.height);
ctx.beginPath();
if (reachability.length >= 1 && reachability[reachability.length-1][1] === undefined) {
ctx.moveTo(cv.width - ((currentTime - reachability[reachability.length-1][0]) / zoom), cv.height/2);
} else {
ctx.moveTo(cv.width, cv.height/2);
}
for (let i = reachability.length-1; i > 0; i--) {
if (reachability[i][0] !== undefined) {
ctx.lineTo(cv.width - ((currentTime - reachability[i][1]) / zoom), cv.height/2);
}
ctx.moveTo(cv.width - ((currentTime - reachability[i][0]) / zoom), cv.height/2);
if (cv.width - ((currentTime - reachability[i][0]) / zoom) < 0) {
reachability_size = reachability.length - i;
break;
}
}
ctx.lineTo(0, cv.height/2);
ctx.stroke();
window.requestAnimationFrame(plotLoop);
}
function loop() {
setTimeout(() => {
beepOn();
let startTime = (new Date()).getTime();
if (reachability.length > reachability_size-1) {
reachability = reachability.slice(-reachability_size-1);
}
reachability.push([startTime, undefined]);
httpGet("https://ping.clerie.de/ping",
() => {
let endTime = (new Date()).getTime();
reachability[reachability.length-1][1] = endTime;
let rtt = endTime - startTime;
if (rtt < 1000) {
setTimeout(() => {
beepOff();
loop();
}, 1000 - rtt);
} else {
loop();
}
},
() => {
loop();
}
);
}, 1000);
}
loop();
window.requestAnimationFrame(plotLoop);
</script>
</body>
</html>