I'm trying to create a simple piano tiles game where tiles translate down from the top to bottom.
What does the code do? I have a startGame function that runs a animate function every 300ms. The animate function creates a tile , get a random index which gets append to the track( nodeList of the 4 lanes ) randomly through the track[random index generated] and finally a move down function within the animate function that translate the tile from top to bottom and gets deleted and cancels the animation when it passes the height of the lane
It works as expected but the animation glitches and shows a fragments of the tile as it comes down. In simple terms it makes the tiles blurry.
Is there a way to smoothing the animation or a better alternative to the request animation frame?
The code HTML
<div class="container">
<div class="lane"></div>
<div class="lane"></div>
<div class="lane"></div>
<div class="lane"></div>
</div>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-Serif;
}
body {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.container {
width: 100vw;
height: 100vh;
background: #de8f5f;
display: flex;
}
.lane {
position: relative;
height: 100%;
width: 25%;
border-right: 1px solid #ffffff30;
}
.lane:last-child {
border: none;
}
.tile {
position: absolute;
background-color: #1f2124;
width: 100%;
}
JavaScript
const track = document.querySelectorAll(".lane");
let previousIndex = -1;
function getRandomLane() {
let index;
do {
index = Math.floor(Math.random() * track.length);
} while (index === previousIndex);
previousIndex = index;
return index;
}
function createTile() {
let span = document.createElement("span");
span.className = "tile";
span.style.cssText = `height: 150px; transform: translateY(-150px);`;
return span;
}
function startGame() {
const length = 300;
animate();
setInterval(animate, length)
}
function animate() {
let tile = createTile();
let position = getRandomLane();
track[position].appendChild(tile);
let posTop = -tile.offsetHeight;
function moveDown() {
posTop += 4;
tile.style.transform = `translateY(${posTop}px)`;
requestAnimationFrame(moveDown);
if (posTop > track[position].offsetHeight) {
tile.remove();
cancelAnimationFrame(animId);
}
}
let animId = requestAnimationFrame(moveDown);
moveDown();
}
startGame(
);