Untitled
unknown
plain_text
10 months ago
13 kB
10
Indexable
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Ball Polygon Animation</title>
<style>
body {
margin: 0;
background: #111;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
canvas {
background: #222;
}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let sides = 3; // start with triangle
let radius = 200;
let ball = { x: 0, y: 0, vx: 2, vy: 2, r: 8 };
function polygonVertices(cx, cy, r, n) {
let verts = [];
for (let i = 0; i < n; i++) {
let angle = (Math.PI * 2 * i) / n - Math.PI / 2;
verts.push({
x: cx + r * Math.cos(angle),
y: cy + r * Math.sin(angle),
});
}
return verts;
}
function drawPolygon(verts) {
ctx.beginPath();
ctx.moveTo(verts[0].x, verts[0].y);
for (let i = 1; i < verts.length; i++) {
ctx.lineTo(verts[i].x, verts[i].y);
}
ctx.closePath();
ctx.strokeStyle = "#0f0";
ctx.lineWidth = 3;
ctx.stroke();
}
function drawBall() {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2);
ctx.fillStyle = "red";
ctx.fill();
}
function reflect(line, vx, vy) {
let dx = line.x2 - line.x1;
let dy = line.y2 - line.y1;
let len = Math.hypot(dx, dy);
dx /= len; dy /= len;
let dot = vx * dx + vy * dy;
let projx = dot * dx;
let projy = dot * dy;
let rx = vx - 2 * (vx - projx);
let ry = vy - 2 * (vy - projy);
return { vx: rx, vy: ry };
}
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
let verts = polygonVertices(canvas.width/2, canvas.height/2, radius, sides);
drawPolygon(verts);
// move ball
ball.x += ball.vx;
ball.y += ball.vy;
drawBall();
// check collisions with polygon edges
for (let i = 0; i < verts.length; i++) {
let v1 = verts[i];
let v2 = verts[(i+1) % verts.length];
let A = v2.y - v1.y;
let B = v1.x - v2.x;
let C = -(A*v1.x + B*v1.y);
let dist = Math.abs(A*ball.x + B*ball.y + C) / Math.hypot(A, B);
if (dist < ball.r) {
let normalLength = Math.hypot(A, B);
let nx = A / normalLength;
let ny = B / normalLength;
let dot = ball.vx * nx + ball.vy * ny;
ball.vx -= 2 * dot * nx;
ball.vy -= 2 * dot * ny;
// speed up
ball.vx *= 1.1;
ball.vy *= 1.1;
// add a side (but cap at 12 for sanity)
if (sides < 12) sides++;
break;
}
}
requestAnimationFrame(update);
}
// Start
ball.x = canvas.width / 2;
ball.y = canvas.height / 2;
update();
</script>
</body>
</html>
}
}
}
}
}
}
}
})
}
}
}
}Editor is loading...
Leave a Comment