From 520fab5c932c563dcf2fc21d453ca25227bcffa3 Mon Sep 17 00:00:00 2001 From: didier amyot Date: Mon, 5 Feb 2024 17:20:35 -0500 Subject: [PATCH] started new ui --- frontend/index-old.html | 90 ++++++++++++++++++++++++++ frontend/index.html | 16 +---- frontend/main-old.js | 118 ++++++++++++++++++++++++++++++++++ frontend/main.js | 139 ++++++++++++++++++++++++++++++++++++++-- frontend/style.css | 4 ++ 5 files changed, 348 insertions(+), 19 deletions(-) create mode 100644 frontend/index-old.html create mode 100644 frontend/main-old.js diff --git a/frontend/index-old.html b/frontend/index-old.html new file mode 100644 index 0000000..23ac777 --- /dev/null +++ b/frontend/index-old.html @@ -0,0 +1,90 @@ + + + + + Dodgeball Tracker + + + + + + + + + +

Dodgeball Tracker

+ +
+ +

+
+ + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + +
+ + + \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html index 15b27cc..1cefe89 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -2,29 +2,17 @@ - Animation + Dodgeball Tracker + -

Hello, world!

-

-
- - -
- - - - - \ No newline at end of file diff --git a/frontend/main-old.js b/frontend/main-old.js new file mode 100644 index 0000000..f031426 --- /dev/null +++ b/frontend/main-old.js @@ -0,0 +1,118 @@ +import anime from "https://esm.sh/animejs@3.2.2"; +import m from "https://esm.sh/mithril@2.2.2" +import colormap from "https://esm.sh/colormap@2.3.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 = []; + 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 range(min, max){ + const ret = []; + while(min < max){ + ret.push(min); + min ++; + } + return ret +} + +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"}) + ] +} + + +m.render(document.getElementById("first"), generatePoints(points.points, range(-10, 400))); +m.render(document.getElementById("first-ts"), m("span", getTimeStamp(points.points, 80))); \ No newline at end of file diff --git a/frontend/main.js b/frontend/main.js index 9638bf2..0eeec6e 100644 --- a/frontend/main.js +++ b/frontend/main.js @@ -2,6 +2,72 @@ 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"; + +// 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 = []; const colors = colormap({ @@ -26,11 +92,74 @@ function getTimeStamp(points, frameId){ } } -const url = "/dodgeball-tracker/outputs/output-lmbn_n_cuhk03_d.json"; -const resp = await fetch(url); -const points = await resp.json(); +// const url = "/dodgeball-tracker/outputs/output-lmbn_n_cuhk03_d.json"; +// const resp = await fetch(url); +// const points = await resp.json(); -m.render(document.getElementById("first"), generatePoints(points.points, range(-10, 400))); -m.render(document.getElementById("first-ts"), m("span", getTimeStamp(points.points, 80))); \ No newline at end of file +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{ + + tabs(){ + return m("div.tabs", + m("ul", + m("li.is-active", m("a", "Info")), + m("li", m("a", "Video Player")))); + } + + info(){ + const options = [ + m("option", "one"), + m("option", "two"), + ] + 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); \ No newline at end of file diff --git a/frontend/style.css b/frontend/style.css index d7a1533..68bcd18 100644 --- a/frontend/style.css +++ b/frontend/style.css @@ -5,6 +5,10 @@ fill: gray; } +.court-side { + background-color: pink; +} + .return-line { stroke: blue; stroke-width: 2px;