Untitled

 avatar
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