<!DOCTYPE html>
<html>
<head>
    <title>ESP32 步进电机控制 - 摇杆版</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        body {
            font-family: Arial;
            text-align: center;
            background-color: #f5f5f5;
            margin: 0;
            padding: 20px;
        }
        h1 {
            color: #333;
        }
        .joystick-container {
            width: 280px;
            height: 280px;
            margin: 20px auto;
            position: relative;
            background-color: #fff;
            border-radius: 50%;
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
            display: flex;
            align-items: center;
            justify-content: center;
        }
        #joystickCanvas {
            width: 100%;
            height: 100%;
            border-radius: 50%;
            cursor: grab;
            touch-action: none;
        }
        #joystickCanvas:active {
            cursor: grabbing;
        }
        .joystick-display {
            font-size: 18px;
            margin: 10px 0;
            padding: 8px;
            background-color: #e0e0e0;
            border-radius: 20px;
            display: inline-block;
        }
        .joystick-display span {
            font-weight: bold;
            color: #4CAF50;
        }
        .control-panel {
            margin: 20px;
            padding: 15px;
            background-color: white;
            border-radius: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }
        select, input, button {
            font-size: 16px;
            margin: 5px;
            padding: 8px 15px;
            border-radius: 5px;
            border: 1px solid #ccc;
        }
        button {
            background-color: #4CAF50;
            color: white;
            border: none;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        button:hover {
            background-color: #45a049;
        }
        button.stop {
            background-color: #f44336;
        }
        button.stop:hover {
            background-color: #d32f2f;
        }
        .mode-group {
            margin: 15px 0;
            padding: 10px;
            background-color: #f9f9f9;
            border-radius: 5px;
        }
        .mode-group label {
            margin-right: 15px;
        }
        input[type="number"] {
            width: 80px;
        }
        footer {
            margin-top: 30px;
            color: #666;
        }
    </style>
</head>
<body>
    <h1>🎮 摇杆控制步进电机</h1>
    
    <div class="joystick-container">
        <canvas id="joystickCanvas" width="280" height="280"></canvas>
    </div>
    <div class="joystick-display">
        X轴: <span id="joyX">0.00</span> | Y轴: <span id="joyY">0.00</span>
    </div>

    <div class="control-panel">
        <div>
            <select id="direction">
                <option value="CW">顺时针 (CW)</option>
                <option value="CCW">逆时针 (CCW)</option>
            </select>
        </div>

        <div class="mode-group">
            <input type="radio" name="mode" id="modeTurn" checked> <label for="modeTurn">圈数</label>
            <input type="number" id="turns" value="1" min="0.1" step="0.1"><br>

            <input type="radio" name="mode" id="modeSteps"> <label for="modeSteps">步数</label>
            <input type="number" id="steps" value="200" min="1"><br>

            <input type="radio" name="mode" id="modeAngle"> <label for="modeAngle">角度 (摇杆Y轴)</label><br>
        </div>

        <div>
            <button onclick="sendCommand()">执行</button>
            <button class="stop" onclick="sendStop()">停止</button>
        </div>
        <p style="font-size:14px; color:#666;">提示：拖动摇杆控制速度，松开即停止</p>
    </div>

    <script>
        const canvas = document.getElementById('joystickCanvas');
        const ctx = canvas.getContext('2d');
        const joyXSpan = document.getElementById('joyX');
        const joyYSpan = document.getElementById('joyY');

        let dragging = false;
        let joyX = 0, joyY = 0;
        const baseRadius = 100;
        const stickRadius = 25;
        const maxDist = baseRadius * 0.7;

        function drawJoystick() {
            ctx.clearRect(0, 0, 280, 280);
            ctx.beginPath();
            ctx.arc(140, 140, baseRadius, 0, 2 * Math.PI);
            ctx.fillStyle = '#ddd';
            ctx.fill();
            ctx.strokeStyle = '#333';
            ctx.lineWidth = 2;
            ctx.stroke();

            ctx.beginPath();
            ctx.strokeStyle = '#aaa';
            ctx.lineWidth = 1;
            ctx.moveTo(140 - baseRadius, 140);
            ctx.lineTo(140 + baseRadius, 140);
            ctx.stroke();
            ctx.beginPath();
            ctx.moveTo(140, 140 - baseRadius);
            ctx.lineTo(140, 140 + baseRadius);
            ctx.stroke();

            let headX = 140 + joyX * maxDist;
            let headY = 140 + joyY * maxDist;
            ctx.beginPath();
            ctx.arc(headX, headY, stickRadius, 0, 2 * Math.PI);
            ctx.fillStyle = '#4CAF50';
            ctx.fill();
            ctx.strokeStyle = '#333';
            ctx.lineWidth = 2;
            ctx.stroke();

            ctx.beginPath();
            ctx.arc(140, 140, 6, 0, 2 * Math.PI);
            ctx.fillStyle = '#333';
            ctx.fill();
        }

        function handleStart(e) {
            e.preventDefault();
            dragging = true;
        }

        function handleMove(e) {
            if (!dragging) return;
            e.preventDefault();

            const rect = canvas.getBoundingClientRect();
            const clientX = e.touches ? e.touches[0].clientX : e.clientX;
            const clientY = e.touches ? e.touches[0].clientY : e.clientY;
            let x = clientX - rect.left - 140;
            let y = clientY - rect.top - 140;

            const distance = Math.sqrt(x*x + y*y);
            if (distance > maxDist) {
                x = x * maxDist / distance;
                y = y * maxDist / distance;
            }

            joyX = x / maxDist;
            joyY = y / maxDist;

            joyXSpan.innerText = joyX.toFixed(2);
            joyYSpan.innerText = joyY.toFixed(2);

            drawJoystick();
        }

        function handleEnd(e) {
            if (!dragging) return;
            dragging = false;
            // 1. 先发送当前摇杆位置的速度（此时 joyY 还是拖动时的值）
            sendJoystickCommand(joyY);
            // 2. 再将摇杆视觉回中
            joyX = 0;
            joyY = 0;
            joyXSpan.innerText = '0.00';
            joyYSpan.innerText = '0.00';
            drawJoystick();
        }
        canvas.addEventListener('mousedown', handleStart);
        canvas.addEventListener('mousemove', handleMove);
        canvas.addEventListener('mouseup', handleEnd);
        canvas.addEventListener('mouseleave', handleEnd);
        canvas.addEventListener('touchstart', handleStart);
        canvas.addEventListener('touchmove', handleMove);
        canvas.addEventListener('touchend', handleEnd);

        drawJoystick();

        // 发送摇杆指令（Y轴速度）
        function sendJoystickCommand(yValue) {
            let dir = yValue >= 0 ? 'CW' : 'CCW';
            let speed = Math.abs(yValue).toFixed(2);
            // 注意：后端通过 value 参数接收速度因子
            fetch(`/control?mode=joystick&dir=${dir}&value=${speed}`)
                .then(response => response.text())
                .then(data => console.log('摇杆指令:', data))
                .catch(err => console.error('摇杆指令错误:', err));
        }

        // 圈数/步数/角度模式发送
        function sendCommand() {
            let url = '/control?';
            const dir = document.getElementById('direction').value;
            url += 'dir=' + dir;

            if (document.getElementById('modeTurn').checked) {
                const turns = document.getElementById('turns').value;
                url += '&mode=turn&value=' + turns;
            } else if (document.getElementById('modeSteps').checked) {
                const steps = document.getElementById('steps').value;
                url += '&mode=steps&value=' + steps;
            } else if (document.getElementById('modeAngle').checked) {
                // 将摇杆Y轴映射到0~360度
                let angle = (joyY + 1) * 180;
                angle = Math.min(360, Math.max(0, angle));
                url += '&mode=angle&value=' + angle.toFixed(1);
            }

            fetch(url)
                .then(response => response.text())
                .then(data => console.log('响应:', data))
                .catch(err => console.error('错误:', err));
        }

        function sendStop() {
            fetch('/control?action=stop')
                .then(response => response.text())
                .then(data => console.log('停止:', data))
                .catch(err => console.error('错误:', err));
        }

        document.getElementById('modeAngle').addEventListener('change', function() {
            if (this.checked) {
                alert('请拖动摇杆设定角度，然后点击“执行”按钮发送。');
            }
        });
    </script>
    <footer>ESP32 + TB6600 步进电机控制器 | 摇杆模式已启用</footer>
</body>
</html>