JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Bouncing Yellow Ball in Rotating Square</title>
  <style>
    body {
      margin: 0;
      background-color: #f0f0f0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
    }
    canvas {
      border: 2px solid black;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="800" height="600"></canvas>

  <script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    // Ball properties
    let ball = {
      x: 100,
      y: 100,
      vx: 4,   // velocity along x-axis
      vy: 3,   // velocity along y-axis
      radius: 10
    };

    const squareCenterX = canvas.width / 2;
    const squareCenterY = canvas.height / 2;
    const squareSize = 250; // width and height of the square
    let theta = 0;          // rotation angle in radians
    const rotationSpeed = 0.01;

    /**
     * Handle collision with square's boundaries.
     */
    function handleCollision(ball, cx, cy, theta, s) {
      const radius = ball.radius;
      const edgeDistance = (s / 2) - radius; // distance from center to valid edge

      let dx = ball.x - cx;
      let dy = ball.y - cy;

      // Transform the ball's position into square local coordinates
      let xLocal = dx * Math.cos(theta) + dy * Math.sin(theta);
      let yLocal = -dx * Math.sin(theta) + dy * Math.cos(theta);

      let normalX = 0, normalY = 0;

      if (xLocal > edgeDistance) {
        // Right edge
        normalX = Math.cos(theta);
        normalY = Math.sin(theta);
        xLocal = edgeDistance;
      } else if (xLocal < -edgeDistance) {
        // Left edge
        normalX = -Math.cos(theta);
        normalY = -Math.sin(theta);
        xLocal = -edgeDistance;
      } else if (yLocal > edgeDistance) {
        // Top edge
        normalX = -Math.sin(theta);
        normalY = Math.cos(theta);
        yLocal = edgeDistance;
      } else if...