← 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>