JSFiddle - React, Tailwind, and code Playground
HTML
<!DOCTYPE html>
<html>
<head>
<title>Bouncing Ball in Spinning Hexagon</title>
<style>
canvas { border: 1px solid black; }
.controls { margin: 10px; }
.control-group { margin-bottom: 10px; }
label { display: inline-block; width: 120px; }
</style>
</head>
<body>
<div class="controls">
<div class="control-group">
<label>Rotation Speed: </label>
<input type="range" id="rotationSpeed" min="-5" max="5" step="0.1" value="2">
<span id="rotationSpeedValue">2</span>
</div>
<div class="control-group">
<label>Gravity: </label>
<input type="range" id="gravity" min="0" max="1000" step="10" value="500">
<span id="gravityValue">500</span>
</div>
<div class="control-group">
<label>Bounciness: </label>
<input type="range" id="bounciness" min="0" max="1.5" step="0.1" value="0.8">
<span id="bouncinessValue">0.8</span>
</div>
</div>
<canvas id="canvas" width="600" height="600"></canvas>
<script src="dist/main.js"></script>
</body>
</html>
TypeScript
interface Ball {
x: number;
y: number;
vx: number;
vy: number;
}
interface Vertex {
x: number;
y: number;
}
interface Normal {
x: number;
y: number;
}
const canvas = document.getElementById('canvas') as HTMLCanvasElement;
const ctx = canvas.getContext('2d')!;
// Canvas management object
const canvasContext = {
clear() {
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
},
drawHexagon(vertices: Vertex[]) {
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.beginPath();
ctx.moveTo(vertices[0].x, vertices[0].y);
vertices.slice(1).forEach(v => ctx.lineTo(v.x, v.y));
ctx.closePath();
ctx.strokeStyle = '#000';
ctx.stroke();
ctx.restore();
},
drawBall(ball: Ball) {
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.beginPath();
ctx.arc(ball.x, ball.y, BALL_RADIUS, 0, Math.PI * 2);
ctx.fillStyle = '#f00';
ctx.fill();
ctx.restore();
}
};
// Constants
const HEX_RADIUS = 200;
const BALL_RADIUS = 10;
const FRICTION = 0.3;
// State
let hexAngle = 0;
const ball: Ball = {
x: 0,
y: -HEX_RADIUS + BALL_RADIUS * 2,
vx: 50,
vy: -200
};
// Control elements
const rotationSpeedInput = document.getElementById('rotationSpeed') as HTMLInputElement;
const gravityInput = document.getElementById('gravity') as HTMLInputElement;
const bouncinessInput = document.getElementById('bounciness') as HTMLInputElement;
const rotationSpeedValue = document.getElementById('rotationSpeedValue')!;
const gravityValue = document.getElementById('gravityValue')!;
const bouncinessValue = document.getElementById('bouncinessValue')!;
// Event listeners
rotationSpeedInput.addEventListener('input', () => {
rotationSpeedValue.textContent =...