Introduction
I have a project in progress to develop a Bingo game. One of the current tasks involves creating a CSS animation that simulates a rolling ball effect. The objective is to make it appear as though a ball drops from a wheel and rolls from right to left.
The Issue at Hand
The animation itself is functional; however, there is an issue with the "drop-in" position being relative to the containing div. Consequently, each subsequent ball dropping in shifts 75 pixels to the right from its predecessor.
Potential Solutions Attempted
- Experimented with setting the balls' positions to absolute. While this resolved the displacement problem, it caused new balls to overlap existing ones due to the keyframe effectively resetting to left: 0%
. This outcome is not ideal.
- Explored JavaScript solutions aiming to modify the keyframe endpoint by a set distance (+75px) based on the prior ball's position. Regrettably, manipulating animations in this manner appears unfeasible or might have eluded my search efforts.
I am now seeking assistance in devising a suitable resolution for this particular challenge.
Minimal Complete Verifiable Example (MCVE)
const timer = setInterval(rollBall, 2000);
var ballNumber = 1;
function rollBall(){
if(document.getElementById('ball-'+(ballNumber-1))){
document.getElementById('ball-'+(ballNumber-1)).classList.remove('ball-animation');
}
let html = '<div id="ball-'+ballNumber+'" class="ball ball-animation">';
html += '<p class="ball-number">';
html += ballNumber;
html += '</p></div>';
document.getElementById('balls').innerHTML += html;
ballNumber++;
if(ballNumber > 10) {
clearInterval(timer);
document.getElementById('ball-'+(ballNumber-1)).classList.remove('ball-animation');
}
}
.ball {
display: block;
position: relative;
width: 75px;
height: 75px;
background: red;
border-radius: 50%;
background: -webkit-radial-gradient(25px 25px, circle, red, #000);
background: -moz-radial-gradient(25px 25px, circle, red, #000);
background: radial-gradient(25px 25px, circle, red, #000);
/*position: absolute;*/
float: left;
}
.ball-number {
top: -34px;
left: 25px;
font-size: 45px;
color: #fff;
position: absolute;
}
.ball-animation {
-webkit-animation: spin 1750ms linear infinite, moveRightToLeft 2s linear infinite;
-moz-animation: spin 1750ms linear infinite, moveRightToLeft 2s linear infinite;
-ms-animation: spin 1750ms linear infinite, moveRightToLeft 2s linear infinite;
animation: spin 1750ms linear infinite, moveRightToLeft 2s linear;
-webkit-transition: all 1.75s ease;
transition: all 1.75s ease;
}
@keyframes spin {
from { transform: rotate(360deg); }
to { transform: rotate(0deg); }
}
@keyframes moveRightToLeft {
0% { top: -50px; left: 200px; }
10% { top: -40px; left: 180px; }
20% { top: -25px; left: 150px; }
30% { top: 0px; left: 100px; }
100% { left: 0%; }
}
<div id="balls"></div>