Translating elements using request animation frame

25 Views Asked by At

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(
);
0

There are 0 best solutions below