Files
archived-vdo.ninja/examples/sensoroverlay.html
2023-12-19 10:14:38 -05:00

367 lines
9.4 KiB
HTML

<html>
<head>
<title>Video with sensor overlayed data</title>
<meta charset="UTF-8">
<style>
body{
padding:0;
margin:0;
background-color: #0000;
}
iframe {
border:0;
margin:0;
padding:0;
display:block;
}
#vdoninja {
width:100%;
height:100%;
}
#container {
border:0;
margin:0;
padding:0;
display:block;
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
}
#overlay{
border:0;
margin:0;
padding:0;
display:block;
text-align:right;
position:absolute;
top:100px;
right:0;
z-index: 10;
color: white;
font-size:300%;
}
#canvas{
border:0;
margin:0;
padding:0;
display:block;
width:20%;
text-align:right;
height:100px;
position:absolute;
top:0;
right:0;
z-index: 5;
}
</style>
</head>
<body id="main">
<div id="overlay"></div>
<canvas id="canvas"></canvas>
<div id="container"></div>
<div id="map-container" style="position: relative;">
<iframe
id="mapFrame"
src="your_map_url"
width="600"
height="450"
style="position: absolute; top: 0; left: 0; border: 0; width: 600px; height: 450px; display:none;">
</iframe>
<div style="position: absolute; top: 0; left: 0; width: 600px; height: 450px; z-index: 10; cursor: default;">
</div>
<span id="marker" style="position: absolute; top: 50px; left: 50%; transform: translate(-50%, calc(-50% - 15px)); font-size: 30px;display:none;">📍</span>
</div>
</div>
<script>
function getColor(value) {
var hue = (Math.abs(value*100+50)).toString(10);
return ["hsl(", hue, ",100%,50%)"].join("");
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var height = context.canvas.height;
var width = context.canvas.width;
canvas.history_accel = [];
canvas.history_speed = [];
var canvasNew = true
function plotData(speed, accel) {
canvas.history_accel.push(accel);
canvas.history_speed.push(speed);
canvas.history_accel = canvas.history_accel.slice(-1 * canvas.width);
canvas.history_speed = canvas.history_speed.slice(-1 * canvas.width);
var maxSpeed = Math.max(...canvas.history_speed);
var interval = 10;
var target = canvas.target || (interval*1.5);
if (target && (maxSpeed > target)){
canvas.target = maxSpeed*1.5; // set it higher than it needs to be, so it doens't jump around a lot
var yScale = height / canvas.target;
context.clearRect(0, 0, width, height);
var w = 1;
var x = width - w;
for (var i = 0; i<canvas.history_speed.length;i++){
var accel = canvas.history_accel[i];
var speed = canvas.history_speed[i];
var val = (10-accel)/10;
if (val>1){val=1;}
else if (val<0){val=0;}
var color = getColor(val);
var y = height - speed * yScale;
context.fillStyle = color;
context.fillRect(x, y, w, height);
context.fillStyle = "#DDD5";
context.fillRect(x, y-2, w, 4);
if (y-5>0){
context.fillStyle = "#FFF3";
context.fillRect(x, y+2, w, 1);
}
var imageData = context.getImageData(w, 0, x, height);
context.putImageData(imageData, 0, 0);
context.clearRect(x, 0, w, height);
}
for (var tt = interval; tt<canvas.target;tt+=interval){
var y = parseInt(height - tt * yScale);
context.fillStyle = "#0555";
context.fillRect(0, y, width, 1);
}
return;
}
var val = (10-accel)/10;
if (val>1){val=1;}
else if (val<0){val=0;}
var color = getColor(val);
var yScale = height / target;
var w = 1;
var x = width - w;
var y = height - speed * yScale;
context.fillStyle = color;
context.fillRect(x, y, w, height);
context.fillStyle = "#DDD5";
context.fillRect(x, y-2, w, 4);
if (y-5>0){
context.fillStyle = "#FFF3";
context.fillRect(x, y+2, w, 1);
}
context.fillStyle = "#0555";
if (canvasNew){
canvasNew = false;
for (var tt = interval; tt<target;tt+=interval){
var y = parseInt(height - tt * yScale);
context.fillRect(0, y, width, 1);
}
} else {
for (var tt = interval; tt<target;tt+=interval){
var y = parseInt(height - tt * yScale);
context.fillRect(x, y, w, 1);
}
}
var imageData = context.getImageData(w, 0, x, height);
context.putImageData(imageData, 0, 0);
context.clearRect(x, 0, w, height);
}
function loadIframe(url=false){
var iframe = document.createElement("iframe");
if (url){
var iframesrc = url;
} else {
var iframesrc = document.getElementById("viewlink").value;
}
iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;";
if (iframesrc==""){
iframesrc="./";
}
iframe.src = iframesrc;
iframe.id = "vdoninja";
document.getElementById("container").appendChild(iframe);
var outputWindow = document.getElementById("overlay");
var sensors = {};
//////////// LISTEN FOR EVENTS
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
var mapBounds = null;
function calculateBBox(lat, lon) {
// Calculate bounding box (bbox) based on the new latitude and longitude
// This requires some geographic calculations to ensure the map is centered
// and zoomed appropriately around the new marker position.
var delta = 0.05; // Determines the zoom level. Smaller delta = higher zoom
mapBounds = {};
mapBounds.left = lon - delta;
mapBounds.bottom = lat - delta;
mapBounds.right = lon + delta;
mapBounds.top = lat + delta;
return `${mapBounds.left},${mapBounds.bottom},${mapBounds.right},${mapBounds.top},`;
}
function isMarkerOutsideMapBounds(markerLat, markerLon) {
if (!mapBounds){return true;}
return (
markerLon < mapBounds.left ||
markerLon > mapBounds.right ||
markerLat < mapBounds.bottom ||
markerLat > mapBounds.top
);
}
function convertLatLngToPixel(lat, lon, mapBounds, mapWidth, mapHeight) {
// Calculate the range of the map in both dimensions
var lonRange = mapBounds.right - mapBounds.left;
var latRange = mapBounds.top - mapBounds.bottom;
// Calculate the position of the latitude and longitude relative to the map bounds
var relativeX = (lon - mapBounds.left) / lonRange;
var relativeY = (mapBounds.top - lat) / latRange; // Invert latitude because screen coordinates go top to bottom
// Convert these relative positions into pixel values
var x = relativeX * mapWidth;
var y = relativeY * mapHeight;
return { x: x, y: y };
}
function updateMap(lat, lon) {
var iframemap = document.getElementById('mapFrame');
iframemap.style = "filter: invert(90%)";
var src = 'https://www.openstreetmap.org/export/embed.html?bbox=' + calculateBBox(lat, lon) + '&layer=mapnik';
iframemap.src = src;
iframemap.onload = function(){
iframemap.style.display = "block";
document.getElementById("marker").style.display = "block";
}
}
function updateMarkerPosition(lat, lon) {
if (isMarkerOutsideMapBounds(lat,lon)) {
updateMap(lat, lon); // Function to load a new map image
}
// Convert lat, lon to pixel coordinates
var mapWidth = 600; // Width of your map in pixels
var mapHeight = 450; // Height of your map in pixels
var pixelCoords = convertLatLngToPixel(lat, lon, mapBounds, mapWidth, mapHeight);
// Update marker position
var marker = document.getElementById("marker");
marker.style.left = pixelCoords.x + 'px';
marker.style.top = pixelCoords.y + 'px';
// Check if marker is outside the current map bounds
}
eventer(messageEvent, function (e) {
if (e.source != iframe.contentWindow){return} // reject messages send from other iframes
if ("sensors" in e.data){
//console.log(e.data.sensors);
var speed = 0;
var lat = null;
var lon = null;
if (e.data.sensors.pos){
speed = e.data.sensors.pos.speed;
lat = e.data.sensors.pos.lat || null;
lon = e.data.sensors.pos.lon || null;
// e.data.sensors.pos.alt
// e.data.sensors.pos.t
}
if (isNaN(speed)) {
speed = 0;
}
var accel = 0;
if (e.data.sensors.lin){
accel += Math.pow(e.data.sensors.lin.x, 2);
accel += Math.pow(e.data.sensors.lin.y, 2);
accel += Math.pow(e.data.sensors.lin.z, 2);
}
if (accel){
accel = Math.pow(accel,0.5);
}
if (isNaN(accel)){
accel = 0;
}
plotData(speed, accel);
outputWindow.innerHTML = "";
speed = parseInt(speed*100)/100;
outputWindow.innerHTML += "speed: "+speed+"m/s<br />";
accel = parseInt(accel*100)/100;
outputWindow.innerHTML += "acceleration: " + accel + "m/s^2<br />";
if ((lat!==null) && (lon!==null)){
updateMarkerPosition(lat, lon);
}
//for (var key in e.data.sensors.lin) {
// outputWindow.innerHTML += key + " lin: " + e.data.sensors.lin[key] + "<br />";
//}
//for (var key in e.data.sensors.acc) {
// outputWindow.innerHTML += key + " acc: " + e.data.sensors.acc[key] + "<br />";
//}
//for (var key in e.data.sensors.mag) {
// outputWindow.innerHTML += key + " magnet: " + e.data.sensors.mag[key] + "<br />";
//}
//for (var key in e.data.sensors.ori) {
// outputWindow.innerHTML += key + " orientation: " + e.data.sensors.ori[key] + "<br />";
//}
}
});
}
loadIframe("../"+window.location.search);
</script>
</body>
</html>