← back to Model Arena

data/artifacts/2ca024f41f3c/kimi.html

257 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Solar System Orrery</title>
<style>
body {
  margin: 0;
  background: radial-gradient(circle at center, #1a1a2e 0%, #000000 100%);
  color: #fff;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  overflow: hidden;
}
#canvas {
  background: transparent;
  box-shadow: 0 0 50px rgba(0,0,0,0.8);
  border-radius: 4px;
}
#controls {
  margin-top: 20px;
  display: flex;
  gap: 30px;
  align-items: center;
  background: rgba(255,255,255,0.05);
  padding: 15px 30px;
  border-radius: 30px;
  border: 1px solid rgba(255,255,255,0.1);
}
button {
  background: #2a2a4a;
  color: white;
  border: 1px solid #4a4a6a;
  padding: 8px 20px;
  border-radius: 20px;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s;
}
button:hover {
  background: #3a3a6a;
  border-color: #6a6a8a;
}
label {
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
}
input[type="range"] {
  width: 150px;
  cursor: pointer;
}
#tooltip {
  position: absolute;
  background: rgba(0,0,0,0.9);
  color: #fff;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 14px;
  pointer-events: none;
  display: none;
  border: 1px solid rgba(255,255,255,0.2);
  box-shadow: 0 4px 6px rgba(0,0,0,0.3);
  z-index: 10;
}
</style>
</head>
<body>
<canvas id="canvas" width="900" height="700"></canvas>
<div id="controls">
  <button id="pauseBtn">Pause</button>
  <label>
    Speed: <span id="speedVal">1x</span>
    <input type="range" id="speedSlider" min="0" max="5" step="0.1" value="1">
  </label>
</div>
<div id="tooltip"></div>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const tooltip = document.getElementById('tooltip');
const pauseBtn = document.getElementById('pauseBtn');
const speedSlider = document.getElementById('speedSlider');
const speedVal = document.getElementById('speedVal');

const dpr = window.devicePixelRatio || 1;
const width = 900;
const height = 700;
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);

const centerX = width / 2;
const centerY = height / 2;

const planets = [
  { name: 'Mercury', dist: 60, radius: 4, period: 0.24, color: '#A5A5A5', angle: Math.random() * Math.PI * 2 },
  { name: 'Venus', dist: 90, radius: 7, period: 0.62, color: '#E3BB76', angle: Math.random() * Math.PI * 2 },
  { name: 'Earth', dist: 130, radius: 7, period: 1.0, color: '#4F83CC', angle: Math.random() * Math.PI * 2 },
  { name: 'Mars', dist: 170, radius: 5, period: 1.88, color: '#C1440E', angle: Math.random() * Math.PI * 2 },
  { name: 'Jupiter', dist: 240, radius: 18, period: 11.86, color: '#D4A574', angle: Math.random() * Math.PI * 2 },
  { name: 'Saturn', dist: 300, radius: 15, period: 29.5, color: '#EAD6B8', angle: Math.random() * Math.PI * 2, hasRings: true },
  { name: 'Uranus', dist: 360, radius: 10, period: 84, color: '#A6D9F0', angle: Math.random() * Math.PI * 2 },
  { name: 'Neptune', dist: 420, radius: 10, period: 165, color: '#5B5DDF', angle: Math.random() * Math.PI * 2 }
];

let isPaused = false;
let speedMultiplier = 1;
let hoveredPlanet = null;
const mouse = { x: 0, y: 0 };

pauseBtn.addEventListener('click', () => {
  isPaused = !isPaused;
  pauseBtn.textContent = isPaused ? 'Resume' : 'Pause';
});

speedSlider.addEventListener('input', (e) => {
  speedMultiplier = parseFloat(e.target.value);
  speedVal.textContent = speedMultiplier.toFixed(1) + 'x';
});

canvas.addEventListener('mousemove', (e) => {
  const rect = canvas.getBoundingClientRect();
  mouse.x = e.clientX - rect.left;
  mouse.y = e.clientY - rect.top;
});

canvas.addEventListener('mouseleave', () => {
  mouse.x = -1000;
  mouse.y = -1000;
  tooltip.style.display = 'none';
});

function drawSun() {
  ctx.save();
  ctx.shadowBlur = 30;
  ctx.shadowColor = '#FDB813';
  ctx.beginPath();
  ctx.arc(centerX, centerY, 25, 0, Math.PI * 2);
  ctx.fillStyle = '#FDB813';
  ctx.fill();
  
  ctx.shadowBlur = 60;
  ctx.shadowColor = 'rgba(253, 184, 19, 0.5)';
  ctx.beginPath();
  ctx.arc(centerX, centerY, 20, 0, Math.PI * 2);
  ctx.fillStyle = '#FFD700';
  ctx.fill();
  ctx.restore();
}

function drawOrbit(dist) {
  ctx.beginPath();
  ctx.arc(centerX, centerY, dist, 0, Math.PI * 2);
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.08)';
  ctx.lineWidth = 1;
  ctx.stroke();
}

function drawPlanet(planet) {
  const x = centerX + Math.cos(planet.angle) * planet.dist;
  const y = centerY + Math.sin(planet.angle) * planet.dist;
  
  planet.x = x;
  planet.y = y;
  
  ctx.beginPath();
  ctx.arc(x, y, planet.radius, 0, Math.PI * 2);
  ctx.fillStyle = planet.color;
  ctx.fill();
  
  if (hoveredPlanet === planet) {
    ctx.beginPath();
    ctx.arc(x, y, planet.radius + 3, 0, Math.PI * 2);
    ctx.strokeStyle = 'rgba(255, 255, 255, 0.8)';
    ctx.lineWidth = 2;
    ctx.stroke();
  }
  
  if (planet.hasRings) {
    ctx.save();
    ctx.translate(x, y);
    ctx.rotate(Math.PI / 6);
    ctx.beginPath();
    ctx.ellipse(0, 0, planet.radius * 2.2, planet.radius * 0.6, 0, 0, Math.PI * 2);
    ctx.strokeStyle = 'rgba(200, 180, 140, 0.6)';
    ctx.lineWidth = 3;
    ctx.stroke();
    ctx.restore();
  }
}

function update() {
  if (!isPaused) {
    const baseSpeed = 0.005 * speedMultiplier;
    planets.forEach(planet => {
      planet.angle += baseSpeed / planet.period;
    });
  }
}

function checkHover() {
  hoveredPlanet = null;
  let minDist = Infinity;
  
  for (let i = planets.length - 1; i >= 0; i--) {
    const p = planets[i];
    const dx = mouse.x - p.x;
    const dy = mouse.y - p.y;
    const dist = Math.sqrt(dx * dx + dy * dy);
    
    if (dist < p.radius + 5 && dist < minDist) {
      minDist = dist;
      hoveredPlanet = p;
    }
  }
  
  if (hoveredPlanet) {
    tooltip.textContent = hoveredPlanet.name;
    tooltip.style.display = 'block';
    const rect = canvas.getBoundingClientRect();
    tooltip.style.left = (rect.left + hoveredPlanet.x + 15) + 'px';
    tooltip.style.top = (rect.top + hoveredPlanet.y - 15) + 'px';
    canvas.style.cursor = 'pointer';
  } else {
    tooltip.style.display = 'none';
    canvas.style.cursor = 'default';
  }
}

function render() {
  ctx.clearRect(0, 0, width, height);
  
  planets.forEach(p => drawOrbit(p.dist));
  drawSun();
  planets.forEach(drawPlanet);
  checkHover();
}

function animate() {
  update();
  render();
  requestAnimationFrame(animate);
}

animate();
</script>
</body>
</html>