Files
dodgeball-tracker/frontend/main.js
T
2024-11-04 18:50:34 -05:00

143 lines
3.9 KiB
JavaScript

import m from "https://esm.sh/mithril@2.2.2"
import colormap from "https://esm.sh/colormap@2.3.2"
import {range} from "./util.js";
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};
}
}
function generatePoints(points, frames){
const lst = [];
const colors = colormap({
colormap: 'viridis',
nshades: new Set(points.map(p => p.objectId)).size,
format: 'hex',
alpha: 1
});
for(const point of points){
if(frames.indexOf(point.frameIndex) !== -1){
lst.push(m("text", {x: point.y, y: point.x, fill: colors[point.objectId]}, point.objectId));
}
}
return m("g", lst);
}
function getTimeStamp(points, frameId){
for(const point of points){
if(point.frameIndex === frameId){
return `${point.frameTimestamp / 1000} seconds`;
}
}
}
// const url = "/dodgeball-tracker/outputs/output-lmbn_n_cuhk03_d.json";
// const resp = await fetch(url);
// const points = await resp.json();
function getCourtLines(){
return [
m("line", {x1: 450, x2: 450, y1: 0, y2: 450, class: "court-border"}),
m("line", {x1: 300, x2: 300, y1: 0, y2: 450, class: "return-line"}),
m("line", {x1: 600, x2: 600, y1: 0, y2: 450, class: "return-line"})
]
}
class WorkingTabs{
#datasets = []
async oninit(){
const url = "/dodgeball-tracker/outputs/index.json"
this.#datasets = (await m.request({method: "GET", url: url}))?.index ?? [];
}
tabs(){
return m("div.tabs",
m("ul",
m("li.is-active", m("a", "Info")),
m("li", m("a", "Video Player"))));
}
info(){
const options = this.#datasets.map(ds => m('option', {value: ds.id}, ds.label));
return m("div.field",
m("label.label", "Dataset"),
m("div.control",
m("div.select",
m("select", options))));
}
view(){
return m("div",
this.tabs(),
this.info())
}
}
const Court = {
view: function(){
const margin = 50
return m("svg.court-side", { width: 900 + 2 * margin, height: 450 + 2 * margin}, [
m("g.court-border#court", {transform: `translate(${margin} ${margin})`}, [
m("rect", {width: 900, height: 450, style: 'background-color: pink;'}),
getCourtLines()
])
])
}
}
// m.render(document.getElementById("new"), drawCourt());
// m.render(document.getElementById("first"), generatePoints(points.points, range(-10, 400)));
// m.render(document.getElementById("first-ts"), m("span", getTimeStamp(points.points, 80)));
const Main = {
view: function(){
return m("div", [
m("h1.title.is-1", "DodgeBall Tracker"),
m("div.columns.is-centered",
m("m.column.is-three-quarters",
m(Court),
m(WorkingTabs)))
])
}
}
m.mount(document.body, Main);