mirror of
https://github.com/SrIzan10/vdo.ninja.git
synced 2026-05-01 11:05:24 +00:00
368 lines
9.4 KiB
HTML
368 lines
9.4 KiB
HTML
<html>
|
|
<head>
|
|
<title>Sensor Data Overlay - VDO.Ninja</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>
|