Meta Description" name="description" />
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kinetic Physics Calculator</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body { margin: 0; overflow: hidden; background: #0f172a; font-family: sans-serif; }
canvas { display: block; }
#ui { position: absolute; top: 20px; left: 20px; color: white; pointer-events: none; }
.controls { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 10px; pointer-events: auto; }
button { background: #3b82f6; padding: 10px 20px; border-radius: 8px; color: white; cursor: pointer; transition: 0.2s; }
button:hover { background: #60a5fa; }
</style>
</head>
<body>
<div id="ui">
<h1 class="text-2xl font-bold">Kinetic Calculator</h1>
<p>Click the screen to spawn numbers. Let them collide!</p>
<div id="result" class="text-4xl mt-4 text-blue-400">0</div>
</div>
<div class="controls">
<button onclick="setOp('+')">+</button>
<button onclick="setOp('-')">-</button>
<button onclick="setOp('*')">×</button>
<button onclick="setOp('/')">÷</button>
<button onclick="clearAll()" class="bg-red-600">Clear</button>
</div>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const resultEl = document.getElementById('result');
let operator = '+';
let circles = [];
function setOp(op) { operator = op; }
function clearAll() { circles = []; resultEl.innerText = "0"; }
function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }
window.onresize = resize;
resize();
class Circle {
constructor(x, y, val) {
this.x = x; this.y = y; this.val = val;
this.vx = (Math.random() - 0.5) * 10;
this.vy = (Math.random() - 0.5) * 10;
this.radius = 25 + Math.log(val + 1) * 5;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = '#3b82f6';
ctx.fill();
ctx.fillStyle = 'white';
ctx.textAlign = 'center';
ctx.fillText(this.val, this.x, this.y + 5);
}
update() {
this.x += this.vx; this.y += this.vy;
if (this.x < this.radius || this.x > canvas.width - this.radius) this.vx *= -1;
if (this.y < this.radius || this.y > canvas.height - this.radius) this.vy *= -1;
}
}
window.onclick = (e) => {
circles.push(new Circle(e.clientX, e.clientY, Math.floor(Math.random() * 9) + 1));
};
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < circles.length; i++) {
circles[i].update();
circles[i].draw();
for (let j = i + 1; j < circles.length; j++) {
const dx = circles[i].x - circles[j].x;
const dy = circles[i].y - circles[j].y;
if (Math.hypot(dx, dy) < circles[i].radius + circles[j].radius) {
const a = circles[i].val, b = circles[j].val;
let res = 0;
if (operator === '+') res = a + b;
if (operator === '-') res = a - b;
if (operator === '*') res = a * b;
if (operator === '/') res = a / b;
circles[i].val = res;
circles[i].radius = 25 + Math.log(Math.abs(res) + 1) * 5;
circles.splice(j, 1);
resultEl.innerText = res;
break;
}
}
}
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
```
3
2
128KB
402KB
415.0ms
128.0ms
415.0ms