174 lines
5.5 KiB
JavaScript
174 lines
5.5 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function() {
|
|
const radarCanvas = document.getElementById('radarCanvas');
|
|
if (radarCanvas) {
|
|
updateRadarData();
|
|
setInterval(updateRadarData, 5000); // Update every 5 seconds
|
|
}
|
|
});
|
|
|
|
function updateRadarData() {
|
|
fetch('api/get_radar_data.php')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data && !data.error) {
|
|
const feeds = data;
|
|
checkProximity(feeds, 0.5);
|
|
drawRadar(feeds);
|
|
updateObjectsTable(feeds);
|
|
} else {
|
|
console.error('Error fetching radar data:', data ? data.error : 'No data received');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Failed to fetch or parse radar data:', error);
|
|
});
|
|
}
|
|
|
|
function toCartesian(angle, distance, canvas) {
|
|
const centerX = canvas.width / 2;
|
|
const centerY = canvas.height / 2;
|
|
const maxCanvasDistance = Math.min(centerX, centerY) * 0.9;
|
|
const MAX_REAL_WORLD_METERS = 5;
|
|
|
|
const distanceInMeters = distance / 100;
|
|
const normalizedDistance = (distanceInMeters / MAX_REAL_WORLD_METERS) * maxCanvasDistance;
|
|
const angleRad = (angle - 90) * (Math.PI / 180);
|
|
const x = centerX + normalizedDistance * Math.cos(angleRad);
|
|
const y = centerY + normalizedDistance * Math.sin(angleRad);
|
|
return { x, y };
|
|
}
|
|
|
|
function updateObjectsTable(feeds) {
|
|
const tableBody = document.getElementById('objectsTableBody');
|
|
if (!tableBody) return;
|
|
|
|
tableBody.innerHTML = '';
|
|
|
|
feeds.forEach((feed, index) => {
|
|
const row = document.createElement('tr');
|
|
row.style.animation = `fadeIn 0.5s ease-in-out ${index * 0.1}s both`;
|
|
|
|
const idCell = document.createElement('td');
|
|
idCell.textContent = feed.entry_id;
|
|
row.appendChild(idCell);
|
|
|
|
const distanceCell = document.createElement('td');
|
|
const distanceInMeters = parseFloat(feed.field2) / 100;
|
|
distanceCell.textContent = distanceInMeters.toFixed(2);
|
|
row.appendChild(distanceCell);
|
|
|
|
const angleCell = document.createElement('td');
|
|
angleCell.textContent = parseFloat(feed.field1).toFixed(2);
|
|
row.appendChild(angleCell);
|
|
|
|
const timeCell = document.createElement('td');
|
|
timeCell.textContent = new Date(feed.created_at).toLocaleTimeString();
|
|
row.appendChild(timeCell);
|
|
|
|
tableBody.appendChild(row);
|
|
});
|
|
}
|
|
|
|
function checkProximity(feeds, distanceThreshold) {
|
|
const alertElement = document.getElementById('proximityAlert');
|
|
const distanceElement = document.getElementById('closestDistance');
|
|
if (!alertElement || !distanceElement) return;
|
|
|
|
let minDistance = Infinity;
|
|
let isClose = false;
|
|
|
|
feeds.forEach(feed => {
|
|
const distanceInMeters = parseFloat(feed.field2) / 100;
|
|
if (distanceInMeters < minDistance) {
|
|
minDistance = distanceInMeters;
|
|
}
|
|
if (distanceInMeters < distanceThreshold) {
|
|
isClose = true;
|
|
}
|
|
});
|
|
|
|
if (isClose) {
|
|
distanceElement.textContent = minDistance.toFixed(2);
|
|
alertElement.classList.remove('d-none');
|
|
} else {
|
|
alertElement.classList.add('d-none');
|
|
}
|
|
}
|
|
|
|
function drawRadar(feeds) {
|
|
const canvas = document.getElementById('radarCanvas');
|
|
if(!canvas) return;
|
|
const ctx = canvas.getContext('2d');
|
|
const width = canvas.width;
|
|
const height = canvas.height;
|
|
const centerX = width / 2;
|
|
const centerY = height / 2;
|
|
const maxDistance = Math.min(centerX, centerY) * 0.9;
|
|
|
|
ctx.fillStyle = '#0b1220';
|
|
ctx.fillRect(0, 0, width, height);
|
|
ctx.strokeStyle = 'rgba(0, 255, 213, 0.3)';
|
|
ctx.lineWidth = 1;
|
|
|
|
for (let i = 1; i <= 4; i++) {
|
|
ctx.beginPath();
|
|
ctx.arc(centerX, centerY, maxDistance * (i / 4), 0, 2 * Math.PI);
|
|
ctx.stroke();
|
|
}
|
|
ctx.beginPath();
|
|
ctx.moveTo(centerX, 0);
|
|
ctx.lineTo(centerX, height);
|
|
ctx.moveTo(0, centerY);
|
|
ctx.lineTo(width, centerY);
|
|
ctx.stroke();
|
|
|
|
feeds.forEach((feed, index) => {
|
|
const angle = parseFloat(feed.field1);
|
|
const distance = parseFloat(feed.field2);
|
|
|
|
if (!isNaN(angle) && !isNaN(distance)) {
|
|
const { x, y } = toCartesian(angle, distance, canvas);
|
|
|
|
// Animation
|
|
let radius = 0;
|
|
let alpha = 0;
|
|
const targetRadius = 5;
|
|
const animationDuration = 500;
|
|
const startTime = Date.now();
|
|
|
|
function animateDot() {
|
|
const elapsedTime = Date.now() - startTime;
|
|
const progress = Math.min(elapsedTime / animationDuration, 1);
|
|
|
|
radius = targetRadius * progress;
|
|
alpha = progress;
|
|
|
|
ctx.fillStyle = `rgba(33, 150, 243, ${alpha})`;
|
|
ctx.beginPath();
|
|
ctx.arc(x, y, radius, 0, 2 * Math.PI);
|
|
ctx.fill();
|
|
|
|
if (progress < 1) {
|
|
requestAnimationFrame(animateDot);
|
|
}
|
|
}
|
|
|
|
setTimeout(animateDot, index * 100);
|
|
}
|
|
});
|
|
}
|
|
|
|
(function () {
|
|
'use strict'
|
|
var forms = document.querySelectorAll('.needs-validation')
|
|
Array.prototype.slice.call(forms)
|
|
.forEach(function (form) {
|
|
form.addEventListener('submit', function (event) {
|
|
if (!form.checkValidity()) {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
}
|
|
form.classList.add('was-validated')
|
|
}, false)
|
|
})
|
|
})(); |