JSFiddle - React, Tailwind, and code Playground
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>PingPong</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
</head>
<body>
<div id="container">
<div id="ball"></div>
<div id="paddle-a" class="paddle"></div>
</div>
<script type="text/javascript" src="./script.js" />
</body>
</html>
CSS
#container {
background: green;
position: fixed;
width: 100vw;
height: 100vh;
padding: 0;
margin:0;
}
#ball {
width: 50px;
height: 50px;
border-radius: 50%;
background-color: white;
position: absolute;
}
.paddle {
position: absolute;
background: red;
width: 20px;
height: 100px;
}
Babel + JSX
// found here: http://paulbourke.net/geometry/pointlineplane/
const intersect = (x1, y1, x2, y2, x3, y3, x4, y4) => {
// Check if none of the lines are of length 0
if ((x1 === x2 && y1 === y2) || (x3 === x4 && y3 === y4)) {
return false;
}
denominator = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
// Lines are parallel
if (denominator === 0) {
return false;
}
let ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator;
let ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator;
// is the intersection along the segments
if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
return false;
}
// Return a object with the x and y coordinates of the intersection
let x = x1 + ua * (x2 - x1);
let y = y1 + ua * (y2 - y1);
return { x, y };
};
class Paddle {
constructor(name, element, x, y) {
this.name = name;
this.element = element;
this.x = x || 0;
this.y = y || 0;
this.lastX = 0;
this.lastY = 0;
this.vx = 0;
this.vy = 0;
this.nextX = 0;
this.nextY = 0;
this.w = this.element.getBoundingClientRect().width;
this.h = this.element.getBoundingClientRect().height;
this.isDown = false;
this.addEvents();
}
addEvents() {
window.addEventListener("pointermove", e => {
if (this.isDown) {
this.lastX = this.x;
this.lastY = this.y;
this.x = e.x;
this.y = e.y;
}
});
this.element.addEventListener("pointerdown", e => {
this.isDown = true;
});
this.element.addEventListener("pointerup", () => {
this.isDown = false;
});
}
render() {
this.vx = this.x - this.lastX;
this.vy = this.y - this.lastY;
// predict next point
this.nextX = this.x + this.vx;
this.nextY = this.y + this.vy;
this.element.setAttribute(
"style",
`transform: translate(${this.x}px, ${this.y}px)`
);
}
}
class Ball {
constructor(x, y) {
this.element =...