<!DOCTYPE html> <html> <head> <title>Rotating Arrows System</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #1a1a1a; font-family: Arial, sans-serif; color: white; } #container { position: relative; text-align: center; } .screen { display: none; margin-bottom: 20px; } .active { display: block; } .arrow-config { background: rgba(255, 255, 255, 0.1); padding: 15px; margin: 10px; border-radius: 8px; } button { padding: 10px 20px; margin: 5px; font-size: 16px; background: #4a90e2; border: none; border-radius: 5px; color: white; cursor: pointer; transition: all 0.3s ease; } button:hover { background: #357abd; transform: translateY(-2px); } input { width: 60px; padding: 5px; margin: 5px; border: none; border-radius: 3px; background: rgba(255, 255, 255, 0.2); color: white; } input:focus { outline: none; background: rgba(255, 255, 255, 0.3); } canvas { background: #333; border-radius: 8px; margin-top: 20px; } #resetBtn { position: fixed; top: 20px; right: 20px; background: #e74c3c; } #resetBtn:hover { background: #c0392b; } .controls { margin-top: 20px; } h2 { color: #4a90e2; margin-bottom: 20px; } .arrow-config label { display: inline-block; width: 60px; text-align: right; margin-right: 10px; } </style> </head> <body> <button id="resetBtn" onclick="reset()" style="display: none;">Reset</button> <div id="container"> <div id="startScreen" class="screen active"> <h2>Select Number of Arrows</h2> <div> <button onclick="selectArrows(2)">2 Arrows</button> <button onclick="selectArrows(3)">3 Arrows</button> <button onclick="selectArrows(4)">4 Arrows</button> <button onclick="selectArrows(5)">5 Arrows</button> </div> </div> <div id="configScreen" class="screen"> <h2>Configure Arrows</h2> <div id="arrowConfigs"></div> <button onclick="startAnimation()">Start Animation</button> </div> <canvas id="canvas" width="800" height="600" style="display: none;"></canvas> </div> <script> let arrows = []; let animationId = null; let canvas, ctx; let pathPoints = []; class Arrow { constructor(length, speed) { this.length = length * 50; this.speed = speed; this.angle = 0; } } function selectArrows(num) { document.getElementById('startScreen').classList.remove('active'); document.getElementById('configScreen').classList.add('active'); document.getElementById('resetBtn').style.display = 'block'; const configsDiv = document.getElementById('arrowConfigs'); configsDiv.innerHTML = ''; for(let i = 0; i < num; i++) { const speed = (Math.random() * 4 + 1).toFixed(1); const length = (Math.random() * 4 + 1).toFixed(1); const config = document.createElement('div'); config.className = 'arrow-config'; config.innerHTML = ` <h3>Arrow ${i + 1}</h3> <div> <label>Speed:</label> <input type="number" min="0.1" max="5" step="0.1" value="${speed}" id="speed${i}"> </div> <div> <label>Length:</label> <input type="number" min="0.1" max="5" step="0.1" value="${length}" id="length${i}"> </div> `; configsDiv.appendChild(config); } } function startAnimation() { arrows = []; const inputs = document.querySelectorAll('.arrow-config input'); for(let i = 0; i < inputs.length/2; i++) { const speed = parseFloat(document.getElementById(`speed${i}`).value); const length = parseFloat(document.getElementById(`length${i}`).value); arrows.push(new Arrow(length, speed)); } document.getElementById('configScreen').classList.remove('active'); canvas = document.getElementById('canvas'); canvas.style.display = 'block'; ctx = canvas.getContext('2d'); pathPoints = []; if(animationId) cancelAnimationFrame(animationId); animate(); } function animate() { // Clear canvas ctx.fillStyle = '#333'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Start from center let x = canvas.width / 2; let y = canvas.height / 2; let totalAngle = 0; // Draw arrows for(let i = 0; i < arrows.length; i++) { const arrow = arrows[i]; arrow.angle += arrow.speed * 0.02; totalAngle += arrow.angle; // Draw arrow line ctx.beginPath(); ctx.moveTo(x, y); const endX = x + Math.cos(totalAngle) * arrow.length; const endY = y + Math.sin(totalAngle) * arrow.length; ctx.lineTo(endX, endY); ctx.strokeStyle = '#4a90e2'; ctx.lineWidth = 3; ctx.stroke(); // Draw joint ctx.beginPath(); ctx.arc(x, y, 5, 0, Math.PI * 2); ctx.fillStyle = '#2ecc71'; ctx.fill(); // Update start point for next arrow x = endX; y = endY; // Store path point for last arrow if(i === arrows.length - 1) { pathPoints.push({x, y}); if(pathPoints.length > 200) pathPoints.shift(); } } // Draw path if(pathPoints.length > 1) { ctx.beginPath(); ctx.moveTo(pathPoints[0].x, pathPoints[0].y); for(let i = 1; i < pathPoints.length; i++) { const point = pathPoints[i]; ctx.lineTo(point.x, point.y); } ctx.strokeStyle = '#e74c3c'; ctx.lineWidth = 2; ctx.stroke(); } animationId = requestAnimationFrame(animate); } function reset() { if(animationId) { cancelAnimationFrame(animationId); animationId = null; } arrows = []; pathPoints = []; document.getElementById('startScreen').classList.add('active'); document.getElementById('configScreen').classList.remove('active'); document.getElementById('canvas').style.display = 'none'; document.getElementById('resetBtn').style.display = 'none'; const configsDiv = document.getElementById('arrowConfigs'); configsDiv.innerHTML = ''; } // Initialize window.onload = () => { canvas = document.getElementById('canvas'); ctx = canvas.getContext('2d'); }; </script> </body> </html><script async data-explicit-opt-in="true" data-cookie-opt-in="true" src="https://vercel.live/_next-live/feedback/feedback.js"></script>