.table {
height: calc(100% – 50px);
position: relative;
}
.table svg {
position:absolute;
background: #666;
inset: 0 0 0 0;
z-index:1;
width: 100%;
height: 100%;
}
const table = document.querySelector(‘#table’);
const ball = document.querySelector(‘#table #ball’);
const ballRadius = parseInt(ball.getAttribute(‘r’));
const ballSpeed = 4;
let [directionX, directionY] = [ballSpeed, ballSpeed];
function moveBall(timestamp) {
const cx = parseInt(ball.getAttribute(‘cx’));
const cy = parseInt(ball.getAttribute(‘cy’));
const leftLimit = ballRadius;
const rightLimit = table.offsetWidth – ballRadius;
const topLimit = ballRadius;
const bottomLimit = table.offsetHeight – ballRadius;
const [nextCX, nextCY] = [cx + directionX, cy + directionY];
if (nextCX < leftLimit || nextCX > rightLimit) {
directionX = -directionX;
}
if (nextCY < topLimit || nextCY > bottomLimit ) {
directionY = -directionY;
}
const [xPos, yPos] = [cx + directionX, cy + directionY];
ball.setAttribute(‘cx’, xPos);
ball.setAttribute(‘cy’, yPos);
requestAnimationFrame(moveBall);
}
requestAnimationFrame(moveBall);
const table = document.querySelector(‘#table’);
const ball = document.querySelector(‘#table #ball’);
const ballRadius = parseInt(ball.getAttribute(‘r’));
const ballSpeed = 4;
let [directionX, directionY] = [ballSpeed, ballSpeed];
function moveBall(timestamp) {
const cx = parseInt(ball.getAttribute(‘cx’));
const cy = parseInt(ball.getAttribute(‘cy’));
const leftLimit = ballRadius;
const rightLimit = table.offsetWidth – ballRadius;
const topLimit = ballRadius;
const bottomLimit = table.offsetHeight – ballRadius;
const [nextCX, nextCY] = [cx + directionX, cy + directionY];
if (nextCX < leftLimit || nextCX > rightLimit) {
directionX = -directionX;
}
if (nextCY < topLimit || nextCY > bottomLimit ) {
directionY = -directionY;
}
const [xPos, yPos] = [cx + directionX, cy + directionY];
ball.setAttribute(‘cx’, xPos);
ball.setAttribute(‘cy’, yPos);
requestAnimationFrame(moveBall);
}
requestAnimationFrame(moveBall);
\.touch-area {
position: absolute;
inset: 50% 0 0 0;
z-index: 1;
}
import { TouchX } from ‘@elementsx/touch-x’;
const player = document.querySelector(‘#player’);
player.setAttribute(‘x’, 50);
player.setAttribute(‘y’, table.offsetHeight – ballRadius);
const touchArea = document.querySelector(‘#touch-area’);
new TouchX(touchArea); // this fires x-swipe event…
let touchStart = 0; // used to calculate player moving distance
document.body.addEventListener(‘x-swipe’, event => {
const { x0, x2, type } = event.detail;
if (type === ‘start’) {
touchStart = parseInt(player.getAttribute(‘x’));
}
else if (type === ‘move’) {
let x = touchStart + (x2 – x0);
x = x < 0 ? 0 : x;
x = x > table.offsetWidth – 80 ? table.offsetWidth – 80 : x;
player.setAttribute(‘x’, x);
}
});
function moveBall(timeframe) {

if (nextCY < topLimit) {
directionY = -directionY;
}
if (detectCollision(ball, player)) {
directionY = -directionY;
}
if (yPos > table.offsetHeight) { // player lost
alert(‘Ooops’);
} else {
ball.setAttribute(‘cx’, xPos);
ball.setAttribute(‘cy’, yPos);
requestAnimationFrame(moveBall);
}
}

function detectCollision(ball, paddle) {
const cx = parseInt(ball.getAttribute(‘cx’));
const cy = parseInt(ball.getAttribute(‘cy’));
const r = parseInt(ball.getAttribute(‘r’));
const [x1, y1, w1, h1] = [cx – r, cy – r, r * 2, r * 2];
const x2 = parseInt(paddle.getAttribute(‘x’));
const y2 = parseInt(paddle.getAttribute(‘y’));
const w2 = parseInt(paddle.getAttribute(‘width’));
const h2 = parseInt(paddle.getAttribute(‘height’));
const colliding = x1 < (x2 + w2) && (x1 + w1) > x2 &&
y1 < (y2 + h2) && (y1 + h1) > y2;
return colliding;
}

const computer = document.querySelector(‘#computer’);
let [computerHit, playerHit] = [false, false];
let computerSpeed = 5;
if (playerHit && detectCollision(ball, computer)) {
directionY = -directionY;
[computerHit, playerHit] = [true, false];
} else if (computerHit && detectCollision(ball, player)) {
directionY = -directionY;
[computerHit, playerHit] = [false, true];
}
function serveBall() {
const rand = ballRadius +
Math.floor((table.offsetWidth – ballRadius) * Math.random());
computer.setAttribute(‘x’, rand – 40);
ball.setAttribute(‘cy’, ballRadius + 10);
ball.setAttribute(‘cx’, rand);
computerHit = true;
[directionX, directionY] = [ballSpeed, ballSpeed];
setTimeout(moveBall, 3000);
}
const computer = document.querySelector(‘#computer’);
let [computerHit, playerHit] = [false, false];
let computerSpeed = 5;
if (playerHit && detectCollision(ball, computer)) {
directionY = -directionY;
[computerHit, playerHit] = [true, false];
} else if (computerHit && detectCollision(ball, player)) {
directionY = -directionY;
[computerHit, playerHit] = [false, true];
}
function serveBall() {
const rand = ballRadius +
Math.floor((table.offsetWidth – ballRadius) * Math.random());
computer.setAttribute(‘x’, rand – 40);
ball.setAttribute(‘cy’, ballRadius + 10);
ball.setAttribute(‘cx’, rand);
computerHit = true;
[directionX, directionY] = [ballSpeed, ballSpeed];
setTimeout(moveBall, 3000);
}

Computer 0
:0 Player

if (yPos < 0) { // computer lost
playerScore++;
touchArea.querySelector(‘.player’).innerText = playerScore;
serveBall();
} else if (yPos > table.offsetHeight) { // plaer lost
computerScore++;
touchArea.querySelector(‘.computer’).innerText = computerScore;
serveBall();
}
function serveBall() {
if (playerScore >= 7 || computerScore >= 7) {
const msg = playerScore >= 7 ?
‘You Win !!!’ : ‘Computer Win :(‘;
alert(msg);
}
….
}