128 lines
4.0 KiB
HTML
128 lines
4.0 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Runway Diagram with Wind Arrow</title>
|
|
<style>
|
|
body {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100vh;
|
|
background-color: #f4f4f4;
|
|
}
|
|
canvas {
|
|
background: white;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<canvas id="compass" width="300" height="300"></canvas>
|
|
|
|
<script>
|
|
const canvas = document.getElementById("compass");
|
|
const ctx = canvas.getContext("2d");
|
|
const centerX = canvas.width / 2;
|
|
const centerY = canvas.height / 2;
|
|
let windDirection = 0; // Initial wind direction in degrees
|
|
|
|
function drawCompass() {
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
|
// Draw runways
|
|
drawRunway(220, 120, 12, -20); // 22/04 runway moved to the left
|
|
drawRunway(280, 90, 8, 0, 40); // 10/28 runway moved down
|
|
|
|
// Draw wind direction arrow
|
|
drawArrow(windDirection);
|
|
}
|
|
|
|
function drawRunway(angle, length, width, xShift, yShift = 0) {
|
|
const radian = (angle - 90) * (Math.PI / 180); // Convert to radians
|
|
|
|
// Calculate runway endpoints with xShift (left/right) and yShift (up/down)
|
|
const xStart = centerX - length * Math.cos(radian) + xShift;
|
|
const yStart = centerY - length * Math.sin(radian) + yShift;
|
|
const xEnd = centerX + length * Math.cos(radian) + xShift;
|
|
const yEnd = centerY + length * Math.sin(radian) + yShift;
|
|
|
|
// Draw runway as a thick line
|
|
ctx.strokeStyle = "#333";
|
|
ctx.lineWidth = width;
|
|
ctx.beginPath();
|
|
ctx.moveTo(xStart, yStart);
|
|
ctx.lineTo(xEnd, yEnd);
|
|
ctx.stroke();
|
|
|
|
// Correctly assign runway numbers at each end
|
|
drawRunwayNumber(angle, xStart, yStart, radian, -20);
|
|
drawRunwayNumber(angle + 180, xEnd, yEnd, radian, 20);
|
|
}
|
|
|
|
function drawRunwayNumber(angle, x, y, radian, extension) {
|
|
const runwayNumber = Math.round(angle / 10) % 36; // Convert heading to runway number
|
|
|
|
// Move the number along the extended centerline
|
|
const xOffset = x + extension * Math.cos(radian);
|
|
const yOffset = y + extension * Math.sin(radian);
|
|
|
|
ctx.font = "14px Arial";
|
|
ctx.fillStyle = "black";
|
|
ctx.textAlign = "center";
|
|
ctx.textBaseline = "middle";
|
|
ctx.fillText(runwayNumber.toString().padStart(2, "0"), xOffset, yOffset);
|
|
}
|
|
|
|
function drawArrow(angle) {
|
|
const arrowLength = 80; // Extended to pass through center
|
|
const radian = (angle + 90) * (Math.PI / 180); // Adjusted for correct direction
|
|
|
|
// Compute start and end points for the arrow
|
|
const xStart = centerX - arrowLength * Math.cos(radian);
|
|
const yStart = centerY - arrowLength * Math.sin(radian);
|
|
const xEnd = centerX + arrowLength * Math.cos(radian);
|
|
const yEnd = centerY + arrowLength * Math.sin(radian);
|
|
|
|
// Draw main arrow line
|
|
ctx.strokeStyle = "red";
|
|
ctx.lineWidth = 3;
|
|
ctx.beginPath();
|
|
ctx.moveTo(xStart, yStart);
|
|
ctx.lineTo(xEnd, yEnd);
|
|
ctx.stroke();
|
|
|
|
// Draw arrowhead at the end
|
|
ctx.fillStyle = "red";
|
|
ctx.beginPath();
|
|
ctx.moveTo(xEnd, yEnd);
|
|
ctx.lineTo(
|
|
xEnd - 12 * Math.cos(radian - Math.PI / 6),
|
|
yEnd - 12 * Math.sin(radian - Math.PI / 6)
|
|
);
|
|
ctx.lineTo(
|
|
xEnd - 12 * Math.cos(radian + Math.PI / 6),
|
|
yEnd - 12 * Math.sin(radian + Math.PI / 6)
|
|
);
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
}
|
|
|
|
function updateWindDirection(degrees) {
|
|
windDirection = degrees % 360;
|
|
drawCompass();
|
|
}
|
|
|
|
// Initial draw
|
|
drawCompass();
|
|
|
|
// Example: Update wind direction dynamically every 2 seconds
|
|
setInterval(() => {
|
|
updateWindDirection(Math.random() * 360); // Random wind direction
|
|
}, 2000);
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|