File size: 2,637 Bytes
ff50694
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// 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";
    }
};