Spaces:
Running
Running
Upload 9 files
Browse files- src/views/InstructorView.js +20 -51
src/views/InstructorView.js
CHANGED
|
@@ -408,64 +408,33 @@ export function setupInstructorEvents() {
|
|
| 408 |
monster = getNextMonster(s.monster_stage || 0, totalLikes, total, s.monster_id);
|
| 409 |
}
|
| 410 |
|
| 411 |
-
//
|
| 412 |
-
//
|
| 413 |
-
const minR = 220;
|
| 414 |
-
const maxR = 350;
|
| 415 |
-
|
| 416 |
-
// Angle: Evenly distributed + Jitter
|
| 417 |
-
let baseAngle = (index / total) * 2 * Math.PI;
|
| 418 |
-
const angleJitter = (Math.random() - 0.5) * 0.5;
|
| 419 |
-
let finalAngle = baseAngle + angleJitter;
|
| 420 |
-
|
| 421 |
-
// Collision Avoidance for Bottom Label (approx 90 deg / PI/2)
|
| 422 |
-
// Expanded exclusion zone for better label clearance (60 to 120 degrees)
|
| 423 |
-
const deg = finalAngle * (180 / Math.PI) % 360;
|
| 424 |
-
const normalizedDeg = deg < 0 ? deg + 360 : deg;
|
| 425 |
-
|
| 426 |
-
// 1. Avoid Instructor Label (Bottom Center: 60-120 deg)
|
| 427 |
-
if (normalizedDeg > 60 && normalizedDeg < 120) {
|
| 428 |
-
// Push angle strictly out of the zone
|
| 429 |
-
const distTo60 = Math.abs(normalizedDeg - 60);
|
| 430 |
-
const distTo120 = Math.abs(normalizedDeg - 120);
|
| 431 |
-
|
| 432 |
-
if (distTo60 < distTo120) {
|
| 433 |
-
finalAngle = (60 - 15) * (Math.PI / 180); // Move to 45 deg
|
| 434 |
-
} else {
|
| 435 |
-
finalAngle = (120 + 15) * (Math.PI / 180); // Move to 135 deg
|
| 436 |
-
}
|
| 437 |
-
}
|
| 438 |
|
| 439 |
-
//
|
| 440 |
-
|
| 441 |
-
|
| 442 |
|
| 443 |
-
|
| 444 |
-
|
| 445 |
|
| 446 |
-
//
|
| 447 |
-
//
|
| 448 |
-
|
| 449 |
-
// Push angle strictly out of the zone
|
| 450 |
-
const distTo0 = Math.abs(normFinalDeg - 0);
|
| 451 |
-
const distTo90 = Math.abs(normFinalDeg - 90);
|
| 452 |
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
}
|
| 459 |
|
| 460 |
-
//
|
| 461 |
-
|
| 462 |
-
|
| 463 |
|
| 464 |
-
//
|
| 465 |
-
|
| 466 |
-
if (shiftNormFinalDeg > 80 && shiftNormFinalDeg < 100) {
|
| 467 |
-
radius += 60;
|
| 468 |
-
}
|
| 469 |
|
| 470 |
const xOff = Math.cos(finalAngle) * radius;
|
| 471 |
const yOff = Math.sin(finalAngle) * radius * 0.8;
|
|
|
|
| 408 |
monster = getNextMonster(s.monster_stage || 0, totalLikes, total, s.monster_id);
|
| 409 |
}
|
| 410 |
|
| 411 |
+
// --- FIXED: Even Arc Distribution (Safe Zone: 135 deg to 405 deg) ---
|
| 412 |
+
// Avoids Bottom Right (0-90) and Bottom Center (90-120) entirely
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
|
| 414 |
+
// Safe Arc Range: Starts at 135 deg (Bottom Left) -> Goes CW -> Ends at 405 deg (45 deg, Bottom Right)
|
| 415 |
+
// Total Span = 270 degrees
|
| 416 |
+
// If many students, use double ring
|
| 417 |
|
| 418 |
+
const safeStartAngle = 135 * (Math.PI / 180);
|
| 419 |
+
const safeSpan = 270 * (Math.PI / 180);
|
| 420 |
|
| 421 |
+
// Distribute evenly
|
| 422 |
+
// If only 1 student, put at top (270 deg / 4.71 rad)
|
| 423 |
+
let finalAngle;
|
|
|
|
|
|
|
|
|
|
| 424 |
|
| 425 |
+
if (total === 1) {
|
| 426 |
+
finalAngle = 270 * (Math.PI / 180);
|
| 427 |
+
} else {
|
| 428 |
+
const step = safeSpan / (total - 1);
|
| 429 |
+
finalAngle = safeStartAngle + (step * index);
|
| 430 |
}
|
| 431 |
|
| 432 |
+
// Radius: Fixed base + slight variation for "natural" look (but not overlap causing)
|
| 433 |
+
// Double ring logic if crowded
|
| 434 |
+
let radius = minR + (index % 2) * 40; // Zigzag radius (220, 260, 220...) to minimize overlap
|
| 435 |
|
| 436 |
+
// Reduce zigzag if few students
|
| 437 |
+
if (total < 10) radius = minR + (index % 2) * 20;
|
|
|
|
|
|
|
|
|
|
| 438 |
|
| 439 |
const xOff = Math.cos(finalAngle) * radius;
|
| 440 |
const yOff = Math.sin(finalAngle) * radius * 0.8;
|