Files
dodgeball-tracker/frontend/main.js
T

101 lines
2.8 KiB
JavaScript

import anime from "https://esm.sh/animejs@3.2.2";
import m from "https://esm.sh/mithril@2.2.2"
const second = 1000;
const canvasWidth = Number.parseFloat(document.querySelector("svg").getAttribute("width"));
const canvasHeight = Number.parseFloat(document.querySelector("svg").getAttribute("height"));
function gaussianRandom(mean=0, stdev=1) {
const u = 1 - Math.random(); // Converting [0,1) to (0,1]
const v = Math.random();
const z = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v );
// Transform to the desired mean and standard deviation:
return z * stdev + mean;
}
function* brownian(n){
let x = 0;
for(let i = 0; i < n; i ++){
x += gaussianRandom(0, 10);
console.log(x);
yield x;
}
}
function* pseudoBrownian(n, limit){
let x = 0;
for(let i = 0; i < n; i ++){
let delta = gaussianRandom(0, 10);
if(Math.abs(x + delta) > limit){
delta = -1 * delta
}
x += delta;
yield x;
}
}
function* keyFrames(duration, framePerSeconds){
const deltaX = canvasWidth / (duration * framePerSeconds);
const limit = 0.75 * (canvasHeight / 2);
for(const deltaY of pseudoBrownian(duration * framePerSeconds, limit)){
yield {translateX: `+=${deltaX}`, translateY: deltaY};
}
}
const duration = 60;
const timeline = anime.timeline({
duration: duration * second,
autoplay: false,
easing: 'linear'});
for(let i = 1; i <= 12; i++){
timeline.add({
targets: `#rect-${i}`,
keyframes: Array.from(keyFrames(duration, 30)),
}, 0)
}
document.querySelector('#play').onclick = timeline.play;
document.querySelector('#pause').onclick = timeline.pause;
document.querySelector('#seek').onclick = function(){
const seekVal = Number.parseFloat(second * document.querySelector('#seek-value').value);
timeline.pause();
timeline.seek(seekVal);
}
function generatePoints(points, frames){
const lst = [];
for(const point of points.points){
if(frames.indexOf(point.frameIndex) !== -1){
lst.push(m("circle", {cx: point.x, cy: point.y, r: 3}));
}
}
return m("g", lst);
}
function getTimeStamp(points, frameId){
for(const point of points.points){
if(point.frameIndex === frameId){
return `${point.frameTimestamp / 1000} seconds`;
}
}
}
const url = "/dodgeball-tracker/outputs/output.json";
const resp = await fetch(url);
const points = await resp.json();
function range(min, max){
const ret = [];
while(min < max){
ret.push(min);
min ++;
}
return ret
}
m.render(document.getElementById("first"), generatePoints(points, range(-10, 400)));
m.render(document.getElementById("first-ts"), m("span", getTimeStamp(points, 80)));