simulator / index.html
kolaslab's picture
Update index.html
1f8f55e verified
raw
history blame
8.58 kB
<!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>