Spaces:
Paused
Paused
| // Agent Cursor Animation Module | |
| APP.ui.cursor = {}; | |
| APP.ui.cursor.ensureAgentCursorOverlay = function () { | |
| const { $ } = APP.core.utils; | |
| if ($("#agentCursor")) return; | |
| const el = document.createElement("div"); | |
| el.id = "agentCursor"; | |
| el.style.cssText = ` | |
| position: fixed; | |
| width: 12px; | |
| height: 12px; | |
| border-radius: 50%; | |
| background: linear-gradient(135deg, rgba(34, 211, 238, 0.9), rgba(124, 58, 237, 0.9)); | |
| box-shadow: 0 0 20px rgba(34, 211, 238, 0.6), 0 0 40px rgba(124, 58, 237, 0.4); | |
| pointer-events: none; | |
| z-index: 10000; | |
| opacity: 0; | |
| display: none; | |
| transition: opacity 0.3s ease; | |
| `; | |
| document.body.appendChild(el); | |
| }; | |
| APP.ui.cursor.setCursorVisible = function (visible) { | |
| const { $ } = APP.core.utils; | |
| const { state } = APP.core; | |
| APP.ui.cursor.ensureAgentCursorOverlay(); | |
| const el = $("#agentCursor"); | |
| if (!el) return; | |
| state.ui.agentCursor.visible = visible; | |
| el.style.opacity = visible ? "1" : "0"; | |
| el.style.display = visible ? "block" : "none"; | |
| }; | |
| APP.ui.cursor.moveCursorToRect = function (rect) { | |
| const { state } = APP.core; | |
| const { $, now } = APP.core.utils; | |
| if (state.ui.cursorMode === "off") return; | |
| APP.ui.cursor.ensureAgentCursorOverlay(); | |
| const el = $("#agentCursor"); | |
| if (!el) return; | |
| const c = state.ui.agentCursor; | |
| c.visible = true; | |
| c.target = rect; | |
| c.t0 = now(); | |
| el.style.opacity = "1"; | |
| el.style.display = "block"; | |
| }; | |
| APP.ui.cursor.tickAgentCursor = function () { | |
| const { state } = APP.core; | |
| const { $, clamp, now } = APP.core.utils; | |
| const el = $("#agentCursor"); | |
| if (!el || state.ui.cursorMode !== "on" || !state.ui.agentCursor.visible) return; | |
| const c = state.ui.agentCursor; | |
| if (!c.target) return; | |
| const tx = c.target.left + c.target.width * 0.72; | |
| const ty = c.target.top + c.target.height * 0.50; | |
| // Smooth spring physics | |
| const dx = tx - (c.x * window.innerWidth); | |
| const dy = ty - (c.y * window.innerHeight); | |
| c.vx = (c.vx + dx * 0.0018) * 0.85; | |
| c.vy = (c.vy + dy * 0.0018) * 0.85; | |
| const px = (c.x * window.innerWidth) + c.vx * 18; | |
| const py = (c.y * window.innerHeight) + c.vy * 18; | |
| c.x = clamp(px / window.innerWidth, 0.02, 0.98); | |
| c.y = clamp(py / window.innerHeight, 0.02, 0.98); | |
| el.style.transform = `translate(${c.x * window.innerWidth}px, ${c.y * window.innerHeight}px)`; | |
| // Hide after settling | |
| const settle = Math.hypot(dx, dy); | |
| if (settle < 6 && (now() - c.t0) > 650) { | |
| el.style.opacity = "0.75"; | |
| } | |
| }; | |