145 lines
4.8 KiB
HTML
145 lines
4.8 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="en">
|
||
|
|
||
|
<head>
|
||
|
<meta charset="UTF-8">
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
<title>Trajectory Prediction Browser Test</title>
|
||
|
<style>
|
||
|
body {
|
||
|
background: black;
|
||
|
}
|
||
|
|
||
|
#field {
|
||
|
background: white;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
<canvas id="field" width="1500" height="1500">
|
||
|
|
||
|
</canvas>
|
||
|
|
||
|
<script>
|
||
|
// map the field to coordinates of our dummy tracker
|
||
|
const field_range = { x: [-10, 10], y: [-10, 10] }
|
||
|
|
||
|
// Create WebSocket connection.
|
||
|
const trajectory_socket = new WebSocket(`ws://${window.location.hostname}:{{ ws_port }}/ws/trajectory`);
|
||
|
const prediction_socket = new WebSocket(`ws://${window.location.hostname}:{{ ws_port }}/ws/prediction`);
|
||
|
let is_moving = false;
|
||
|
const fieldEl = document.getElementById('field');
|
||
|
|
||
|
let current_data = {}
|
||
|
// Listen for messages
|
||
|
prediction_socket.addEventListener("message", (event) => {
|
||
|
// console.log("Message from server ", event.data);
|
||
|
current_data = JSON.parse(event.data);
|
||
|
});
|
||
|
|
||
|
function getMousePos(canvas, evt) {
|
||
|
const rect = canvas.getBoundingClientRect();
|
||
|
return {
|
||
|
x: evt.clientX - rect.left,
|
||
|
y: evt.clientY - rect.top
|
||
|
};
|
||
|
}
|
||
|
function mouse_coordinates_to_position(coordinates) {
|
||
|
const x_range = field_range.x[1] - field_range.x[0]
|
||
|
const x = (coordinates.x / fieldEl.clientWidth) * x_range + field_range.x[0]
|
||
|
const y_range = field_range.y[1] - field_range.y[0]
|
||
|
const y = (coordinates.y / fieldEl.clientWidth) * y_range + field_range.y[0]
|
||
|
return { x: x, y: y }
|
||
|
}
|
||
|
function position_to_canvas_coordinate(position) {
|
||
|
const x_range = field_range.x[1] - field_range.x[0]
|
||
|
const y_range = field_range.y[1] - field_range.y[0]
|
||
|
return {
|
||
|
x: (position.x - field_range.x[0]) * fieldEl.width / x_range,
|
||
|
y: (position.y - field_range.y[0]) * fieldEl.width / y_range,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// helper function so we can spread
|
||
|
function coord_as_list(coord) {
|
||
|
return [coord.x, coord.y]
|
||
|
}
|
||
|
|
||
|
|
||
|
let tracker = {}
|
||
|
let person_counter = 0
|
||
|
|
||
|
class Person {
|
||
|
constructor(id) {
|
||
|
this.id = id;
|
||
|
this.history = [];
|
||
|
this.prediction = []
|
||
|
}
|
||
|
|
||
|
addToHistory(position) {
|
||
|
this.history.push(position);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fieldEl.addEventListener('mousedown', (event) => {
|
||
|
person_counter++;
|
||
|
tracker[person_counter] = new Person(person_counter);
|
||
|
is_moving = true;
|
||
|
|
||
|
const mousePos = getMousePos(fieldEl, event);
|
||
|
const position = mouse_coordinates_to_position(mousePos)
|
||
|
tracker[person_counter].addToHistory(position);
|
||
|
trajectory_socket.send(JSON.stringify(tracker))
|
||
|
});
|
||
|
fieldEl.addEventListener('mousemove', (event) => {
|
||
|
if (!is_moving) return;
|
||
|
const mousePos = getMousePos(fieldEl, event);
|
||
|
const position = mouse_coordinates_to_position(mousePos)
|
||
|
tracker[person_counter].addToHistory(position);
|
||
|
trajectory_socket.send(JSON.stringify(tracker))
|
||
|
});
|
||
|
document.addEventListener('mouseup', (e) => {
|
||
|
is_moving = false;
|
||
|
tracker = {}
|
||
|
})
|
||
|
|
||
|
const ctx = fieldEl.getContext("2d");
|
||
|
function drawFrame() {
|
||
|
ctx.clearRect(0, 0, fieldEl.width, fieldEl.height);
|
||
|
ctx.save();
|
||
|
for (let id in current_data) {
|
||
|
const person = current_data[id];
|
||
|
if (person.history.length > 1) {
|
||
|
const hist = structuredClone(person.history)
|
||
|
// draw current position:
|
||
|
ctx.beginPath()
|
||
|
ctx.arc(
|
||
|
...coord_as_list(position_to_canvas_coordinate(hist[hist.length - 1])),
|
||
|
5, //radius
|
||
|
0, 2 * Math.PI);
|
||
|
ctx.fill()
|
||
|
|
||
|
ctx.beginPath()
|
||
|
ctx.lineWidth = 3;
|
||
|
ctx.strokeStyle = "#325FA2";
|
||
|
|
||
|
ctx.moveTo(...coord_as_list(position_to_canvas_coordinate(hist.shift())));
|
||
|
for (const position of hist) {
|
||
|
ctx.lineTo(...coord_as_list(position_to_canvas_coordinate(position)))
|
||
|
}
|
||
|
ctx.stroke();
|
||
|
}
|
||
|
}
|
||
|
ctx.restore();
|
||
|
|
||
|
window.requestAnimationFrame(drawFrame);
|
||
|
}
|
||
|
|
||
|
window.requestAnimationFrame(drawFrame);
|
||
|
</script>
|
||
|
</body>
|
||
|
|
||
|
</html>
|