Update index.html
Browse files- index.html +40 -35
index.html
CHANGED
|
@@ -453,34 +453,39 @@
|
|
| 453 |
ctx.fillStyle = '#181818';
|
| 454 |
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
| 455 |
|
| 456 |
-
//
|
| 457 |
function toCanvas(x, y) {
|
| 458 |
return {
|
| 459 |
-
x: x *
|
| 460 |
-
y: -y *
|
| 461 |
};
|
| 462 |
}
|
| 463 |
|
| 464 |
-
//
|
| 465 |
const trackPoints = [
|
| 466 |
-
{x: -1.
|
| 467 |
-
{x:
|
| 468 |
-
{x: 0.
|
| 469 |
-
{x: -0.
|
| 470 |
-
{x: -1.
|
| 471 |
-
{x: -
|
| 472 |
-
{x: -2.
|
| 473 |
-
{x: -
|
| 474 |
-
{x: 1.
|
| 475 |
-
{x:
|
| 476 |
-
{x:
|
| 477 |
-
{x:
|
| 478 |
-
{x: 2.
|
| 479 |
-
{x:
|
| 480 |
-
{x:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
];
|
| 482 |
|
| 483 |
-
//
|
| 484 |
ctx.beginPath();
|
| 485 |
trackPoints.forEach((pt, idx) => {
|
| 486 |
const c = toCanvas(pt.x, pt.y);
|
|
@@ -491,7 +496,7 @@
|
|
| 491 |
ctx.lineWidth = 14;
|
| 492 |
ctx.stroke();
|
| 493 |
|
| 494 |
-
//
|
| 495 |
ctx.beginPath();
|
| 496 |
ctx.setLineDash([6, 6]);
|
| 497 |
trackPoints.forEach((pt, idx) => {
|
|
@@ -504,34 +509,34 @@
|
|
| 504 |
ctx.stroke();
|
| 505 |
ctx.setLineDash([]);
|
| 506 |
|
| 507 |
-
// MAP NODES positioned outside the
|
| 508 |
const nodes = {
|
| 509 |
// Grandstands
|
| 510 |
-
"Hamilton GS": { pos: toCanvas(-
|
| 511 |
-
"Becketts GS": { pos: toCanvas(
|
| 512 |
-
"Stowe GS": { pos: toCanvas(4.
|
| 513 |
-
"Village GS": { pos: toCanvas(-0.
|
| 514 |
-
"Club GS": { pos: toCanvas(0.
|
| 515 |
|
| 516 |
// Food Stalls & Arenas
|
| 517 |
"Main Fan Zone": { pos: toCanvas(-2.8, -1.8), type: "food", label: "π Main Fan Zone" },
|
| 518 |
"Becketts Food": { pos: toCanvas(2.2, 4.0), type: "food", label: "π Becketts Food" },
|
| 519 |
"Village Plaza": { pos: toCanvas(-3.2, 1.2), type: "food", label: "π Village Plaza" },
|
| 520 |
-
"Club Eats": { pos: toCanvas(-1.
|
| 521 |
|
| 522 |
// Intermediate Junction Hubs
|
| 523 |
"Arena Crossroad": { pos: toCanvas(-3.8, -2.8), type: "hub", label: "π Arena Hub" },
|
| 524 |
"Becketts Interchange": { pos: toCanvas(0.2, 3.8), type: "hub", label: "π Becketts Hub" },
|
| 525 |
-
"South Bypass": { pos: toCanvas(-3.
|
| 526 |
|
| 527 |
-
//
|
| 528 |
"Main Gate 1": { pos: toCanvas(-4.8, -2.8), type: "gate", label: "πͺ Main Gate 1" },
|
| 529 |
-
"South Gate 2": { pos: toCanvas(2.5, -4.
|
| 530 |
-
"East Gate 3": { pos: toCanvas(
|
| 531 |
"West Gate 4": { pos: toCanvas(-4.5, 2.2), type: "gate", label: "πͺ West Gate 4" }
|
| 532 |
};
|
| 533 |
|
| 534 |
-
//
|
| 535 |
function drawPath(points, color, isDashed = false) {
|
| 536 |
ctx.beginPath();
|
| 537 |
if (isDashed) ctx.setLineDash([8, 6]);
|
|
@@ -549,7 +554,7 @@
|
|
| 549 |
const pathColorG1 = isGate1Bottleneck ? "#ff4444" : "#00cc66";
|
| 550 |
const pathColorG3 = isGate3Bottleneck ? "#ff4444" : "#00cc66";
|
| 551 |
|
| 552 |
-
//
|
| 553 |
drawPath(["Hamilton GS", "Arena Crossroad"], pathColorG1);
|
| 554 |
drawPath(["Arena Crossroad", "Main Fan Zone"], pathColorG1);
|
| 555 |
drawPath(["Main Fan Zone", "Main Gate 1"], pathColorG1);
|
|
@@ -568,7 +573,7 @@
|
|
| 568 |
drawPath(["Club GS", "Club Eats"], "#00cc66");
|
| 569 |
drawPath(["Club Eats", "South Gate 2"], "#00cc66");
|
| 570 |
|
| 571 |
-
//
|
| 572 |
if (isGate1Bottleneck) {
|
| 573 |
drawPath(["Main Fan Zone", "Arena Crossroad", "South Bypass", "Club Eats", "South Gate 2"], "#a020f0", true);
|
| 574 |
drawPath(["Arena Crossroad", {x: -4.8, y: -0.2}, "West Gate 4"], "#a020f0", true);
|
|
|
|
| 453 |
ctx.fillStyle = '#181818';
|
| 454 |
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
| 455 |
|
| 456 |
+
// Scale and translation to frame the official Silverstone Grand Prix track
|
| 457 |
function toCanvas(x, y) {
|
| 458 |
return {
|
| 459 |
+
x: x * 68 + 400,
|
| 460 |
+
y: -y * 52 + 250
|
| 461 |
};
|
| 462 |
}
|
| 463 |
|
| 464 |
+
// Accurate 18-turn geometry of Silverstone Circuit
|
| 465 |
const trackPoints = [
|
| 466 |
+
{x: -1.0, y: -2.3}, // Hamilton Straight / Grid
|
| 467 |
+
{x: 0.1, y: -2.3}, // Turn 1: Abbey
|
| 468 |
+
{x: 0.7, y: -1.7}, // Turn 2: Farm Curve
|
| 469 |
+
{x: -0.1, y: -1.1}, // Turn 3: Village
|
| 470 |
+
{x: -1.0, y: -1.3}, // Turn 4: The Loop
|
| 471 |
+
{x: -1.1, y: -0.8}, // Turn 5: Aintree
|
| 472 |
+
{x: -2.1, y: 0.5}, // Wellington Straight
|
| 473 |
+
{x: -1.9, y: 1.8}, // Turn 6: Brooklands
|
| 474 |
+
{x: -1.1, y: 2.1}, // Turn 7: Luffield
|
| 475 |
+
{x: -0.5, y: 1.8}, // Turn 8: Woodcote
|
| 476 |
+
{x: 0.5, y: 2.6}, // National Straight
|
| 477 |
+
{x: 1.4, y: 3.2}, // Turn 9: Copse
|
| 478 |
+
{x: 2.8, y: 3.0}, // Turn 10 & 11: Maggotts
|
| 479 |
+
{x: 3.4, y: 2.3}, // Turn 12 & 13: Becketts
|
| 480 |
+
{x: 3.7, y: 1.4}, // Turn 14: Chapel
|
| 481 |
+
{x: 3.5, y: -0.9}, // Hangar Straight
|
| 482 |
+
{x: 3.2, y: -1.8}, // Turn 15: Stowe
|
| 483 |
+
{x: 2.0, y: -3.1}, // Turn 16: Vale
|
| 484 |
+
{x: 0.3, y: -3.2}, // Turn 17 & 18: Club
|
| 485 |
+
{x: -1.0, y: -2.3} // Return to Hamilton Straight
|
| 486 |
];
|
| 487 |
|
| 488 |
+
// Draw asphalt track base
|
| 489 |
ctx.beginPath();
|
| 490 |
trackPoints.forEach((pt, idx) => {
|
| 491 |
const c = toCanvas(pt.x, pt.y);
|
|
|
|
| 496 |
ctx.lineWidth = 14;
|
| 497 |
ctx.stroke();
|
| 498 |
|
| 499 |
+
// Draw racing line
|
| 500 |
ctx.beginPath();
|
| 501 |
ctx.setLineDash([6, 6]);
|
| 502 |
trackPoints.forEach((pt, idx) => {
|
|
|
|
| 509 |
ctx.stroke();
|
| 510 |
ctx.setLineDash([]);
|
| 511 |
|
| 512 |
+
// MAP NODES positioned cleanly outside the circuit perimeter
|
| 513 |
const nodes = {
|
| 514 |
// Grandstands
|
| 515 |
+
"Hamilton GS": { pos: toCanvas(-0.8, -3.3), type: "gs", label: `Hamilton (${hamilton})` },
|
| 516 |
+
"Becketts GS": { pos: toCanvas(4.1, 2.8), type: "gs", label: `Becketts (${becketts})` },
|
| 517 |
+
"Stowe GS": { pos: toCanvas(4.5, -1.8), type: "gs", label: `Stowe (${stowe})` },
|
| 518 |
+
"Village GS": { pos: toCanvas(-0.1, -0.3), type: "gs", label: `Village (${village})` },
|
| 519 |
+
"Club GS": { pos: toCanvas(0.8, -4.1), type: "gs", label: `Club (${club})` },
|
| 520 |
|
| 521 |
// Food Stalls & Arenas
|
| 522 |
"Main Fan Zone": { pos: toCanvas(-2.8, -1.8), type: "food", label: "π Main Fan Zone" },
|
| 523 |
"Becketts Food": { pos: toCanvas(2.2, 4.0), type: "food", label: "π Becketts Food" },
|
| 524 |
"Village Plaza": { pos: toCanvas(-3.2, 1.2), type: "food", label: "π Village Plaza" },
|
| 525 |
+
"Club Eats": { pos: toCanvas(-1.5, -4.1), type: "food", label: "π¦ Club Eats" },
|
| 526 |
|
| 527 |
// Intermediate Junction Hubs
|
| 528 |
"Arena Crossroad": { pos: toCanvas(-3.8, -2.8), type: "hub", label: "π Arena Hub" },
|
| 529 |
"Becketts Interchange": { pos: toCanvas(0.2, 3.8), type: "hub", label: "π Becketts Hub" },
|
| 530 |
+
"South Bypass": { pos: toCanvas(-3.0, -3.8), type: "hub", label: "π South Hub" },
|
| 531 |
|
| 532 |
+
// Gates
|
| 533 |
"Main Gate 1": { pos: toCanvas(-4.8, -2.8), type: "gate", label: "πͺ Main Gate 1" },
|
| 534 |
+
"South Gate 2": { pos: toCanvas(2.5, -4.4), type: "gate", label: "πͺ South Gate 2" },
|
| 535 |
+
"East Gate 3": { pos: toCanvas(4.8, -0.5), type: "gate", label: "πͺ East Gate 3" },
|
| 536 |
"West Gate 4": { pos: toCanvas(-4.5, 2.2), type: "gate", label: "πͺ West Gate 4" }
|
| 537 |
};
|
| 538 |
|
| 539 |
+
// Waypoint drawing function for non-intersecting pedestrian paths
|
| 540 |
function drawPath(points, color, isDashed = false) {
|
| 541 |
ctx.beginPath();
|
| 542 |
if (isDashed) ctx.setLineDash([8, 6]);
|
|
|
|
| 554 |
const pathColorG1 = isGate1Bottleneck ? "#ff4444" : "#00cc66";
|
| 555 |
const pathColorG3 = isGate3Bottleneck ? "#ff4444" : "#00cc66";
|
| 556 |
|
| 557 |
+
// Pedestrian paths around the outside of the circuit
|
| 558 |
drawPath(["Hamilton GS", "Arena Crossroad"], pathColorG1);
|
| 559 |
drawPath(["Arena Crossroad", "Main Fan Zone"], pathColorG1);
|
| 560 |
drawPath(["Main Fan Zone", "Main Gate 1"], pathColorG1);
|
|
|
|
| 573 |
drawPath(["Club GS", "Club Eats"], "#00cc66");
|
| 574 |
drawPath(["Club Eats", "South Gate 2"], "#00cc66");
|
| 575 |
|
| 576 |
+
// Rerouting purple detours along perimeter pathways
|
| 577 |
if (isGate1Bottleneck) {
|
| 578 |
drawPath(["Main Fan Zone", "Arena Crossroad", "South Bypass", "Club Eats", "South Gate 2"], "#a020f0", true);
|
| 579 |
drawPath(["Arena Crossroad", {x: -4.8, y: -0.2}, "West Gate 4"], "#a020f0", true);
|