Spaces:
Running
Running
Upload 9 files
Browse files- src/views/InstructorView.js +60 -1
src/views/InstructorView.js
CHANGED
|
@@ -442,7 +442,7 @@ export function setupInstructorEvents() {
|
|
| 442 |
const yOff = Math.sin(finalAngle) * radius * 0.8;
|
| 443 |
|
| 444 |
const card = document.createElement('div');
|
| 445 |
-
card.className = 'absolute flex flex-col items-center group/card z-10 hover:z-50 transition-all duration-500';
|
| 446 |
|
| 447 |
card.style.left = `calc(50% + ${xOff}px)`;
|
| 448 |
card.style.top = `calc(50% + ${yOff}px)`;
|
|
@@ -476,12 +476,71 @@ export function setupInstructorEvents() {
|
|
| 476 |
</div>
|
| 477 |
`;
|
| 478 |
relativeContainer.appendChild(card);
|
|
|
|
|
|
|
|
|
|
| 479 |
});
|
| 480 |
}
|
| 481 |
|
| 482 |
modal.classList.remove('hidden');
|
| 483 |
});
|
| 484 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 485 |
// Add float animation style if not exists
|
| 486 |
if (!document.getElementById('anim-float')) {
|
| 487 |
const style = document.createElement('style');
|
|
|
|
| 442 |
const yOff = Math.sin(finalAngle) * radius * 0.8;
|
| 443 |
|
| 444 |
const card = document.createElement('div');
|
| 445 |
+
card.className = 'absolute flex flex-col items-center group/card z-10 hover:z-50 transition-all duration-500 cursor-move';
|
| 446 |
|
| 447 |
card.style.left = `calc(50% + ${xOff}px)`;
|
| 448 |
card.style.top = `calc(50% + ${yOff}px)`;
|
|
|
|
| 476 |
</div>
|
| 477 |
`;
|
| 478 |
relativeContainer.appendChild(card);
|
| 479 |
+
|
| 480 |
+
// Enable Drag & Drop
|
| 481 |
+
setupDraggable(card, relativeContainer);
|
| 482 |
});
|
| 483 |
}
|
| 484 |
|
| 485 |
modal.classList.remove('hidden');
|
| 486 |
});
|
| 487 |
|
| 488 |
+
// Helper: Drag & Drop Logic
|
| 489 |
+
function setupDraggable(el, container) {
|
| 490 |
+
let isDragging = false;
|
| 491 |
+
let startX, startY, initialLeft, initialTop;
|
| 492 |
+
|
| 493 |
+
el.addEventListener('mousedown', (e) => {
|
| 494 |
+
isDragging = true;
|
| 495 |
+
startX = e.clientX;
|
| 496 |
+
startY = e.clientY;
|
| 497 |
+
|
| 498 |
+
// Disable transition during drag for responsiveness
|
| 499 |
+
el.style.transition = 'none';
|
| 500 |
+
el.style.zIndex = 100; // Bring to front
|
| 501 |
+
|
| 502 |
+
// Convert current computed position to fixed pixels if relying on calc
|
| 503 |
+
const rect = el.getBoundingClientRect();
|
| 504 |
+
const containerRect = container.getBoundingClientRect();
|
| 505 |
+
|
| 506 |
+
// Calculate position relative to container
|
| 507 |
+
// The current transform is translate(-50%, -50%).
|
| 508 |
+
// We want to set left/top such that the center remains under the mouse offset,
|
| 509 |
+
// but for simplicity, let's just use current offsetLeft/Top if possible,
|
| 510 |
+
// OR robustly recalculate from rects.
|
| 511 |
+
|
| 512 |
+
// Current center point relative to container:
|
| 513 |
+
const centerX = rect.left - containerRect.left + rect.width / 2;
|
| 514 |
+
const centerY = rect.top - containerRect.top + rect.height / 2;
|
| 515 |
+
|
| 516 |
+
// Set explicit pixel values replacing calc()
|
| 517 |
+
el.style.left = `${centerX}px`;
|
| 518 |
+
el.style.top = `${centerY}px`;
|
| 519 |
+
|
| 520 |
+
initialLeft = centerX;
|
| 521 |
+
initialTop = centerY;
|
| 522 |
+
});
|
| 523 |
+
|
| 524 |
+
window.addEventListener('mousemove', (e) => {
|
| 525 |
+
if (!isDragging) return;
|
| 526 |
+
e.preventDefault();
|
| 527 |
+
|
| 528 |
+
const dx = e.clientX - startX;
|
| 529 |
+
const dy = e.clientY - startY;
|
| 530 |
+
|
| 531 |
+
el.style.left = `${initialLeft + dx}px`;
|
| 532 |
+
el.style.top = `${initialTop + dy}px`;
|
| 533 |
+
});
|
| 534 |
+
|
| 535 |
+
window.addEventListener('mouseup', () => {
|
| 536 |
+
if (isDragging) {
|
| 537 |
+
isDragging = false;
|
| 538 |
+
el.style.transition = ''; // Re-enable hover effects
|
| 539 |
+
el.style.zIndex = ''; // Restore z-index rule (or let hover take over)
|
| 540 |
+
}
|
| 541 |
+
});
|
| 542 |
+
}
|
| 543 |
+
|
| 544 |
// Add float animation style if not exists
|
| 545 |
if (!document.getElementById('anim-float')) {
|
| 546 |
const style = document.createElement('style');
|