Positioning elements in CSS with a rolling ball animation

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>

Answer №1

A unique approach utilizing only CSS is demonstrated here, with the use of an intermediary div called zone to manage the movement of the ball.

By allowing these elements to have different sizes, keyframes can be set in percentages so that adjustments can be made for various ending points while maintaining a consistent starting point.

.container {
    width: 600px;
    height: 350px;
    border: solid 1px red;
    position: relative;
}

.zone {
    position: absolute;
    top: 0px;
    right: 0px;
    bottom: 40px;
    left: 40px;
    border: solid 1px green;
    animation: move 3s linear infinite;
}

.zone:nth-child(2) {
    left: calc(40px * 2);
}

.zone:nth-child(3) {
    left: calc(40px * 3);
}
.zone:nth-child(4) {
    left: calc(40px * 4);
}

.ball {
    width: 40px;
    height: 40px;
    border-radius: 100%;
    background-color: blue;
    right: 0px;
    position: absolute;
}

@keyframes move {
    from {transform: translate(0px, 0px);}
    50% {transform: translate(-100px, 100%);}
    to {transform: translate(-100%, 100%);}
}
<div class="container">
  <div class="zone">
    <div class="ball">1</div>
  </div>
  <div class="zone">
    <div class="ball">2</div>
  </div>
  <div class="zone">
    <div class="ball">3</div>
  </div>
  <div class="zone">
    <div class="ball">4</div>
  </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

IBM Watson Conversation and Angular Integration

After recently diving into Angular, I am eager to incorporate a Watson conversation bot into my angular module. Unfortunately, I'm facing an issue with including a library in Angular. To retrieve the Watson answer, I am utilizing botkit-middleware-wat ...

The functionality of CSS transform appears to be malfunctioning on Firefox browser

My website, located at , features a logo that is centered within a compressed header. I achieved the centering effect using the following CSS command: .html_header_top.html_logo_center .logo { transform: translate(-63%, -2%); } This setup works perfe ...

Unable to position a div alongside a fluid div with minimum and maximum widths

Within this container, there is a div. #leftBanner { height: 100%; background-color: #CCC; width: 22%; min-width: 245px; max-width: 355px; float: left; } This particular div doesn't cooperate when I try to float another div next to it. While I could ...

Creating Space in CSS between Two Widgets

Is there a way to align the managers tab under the checkers and stockers areas on this page? The current setup has the manager button overlapping with both of them. If anyone has any suggestions on how to address this issue, I'm all ears. Thank you! ...

Is it considered a bad habit to utilize custom CSS on Bootstrap classes?

Imagine I have the following code snippet in my index.html file, and I am utilizing Bootstrap: <head> bootstrap stylesheet main.css stylesheet ... <button class="btn btn-primary">Button</button The class "btn-primary" is used to style the ...

How can I fix the issue of clearInterval not functioning properly in an Electron JS application?

The clearInterval function is not working properly in this code. What can be done to fix this issue? var inter; ipcMain.on("start-stop",(err,data)=>{ console.log(data.data) function start(){ inter = setInterval(fu ...

When converting with wkhtmltopdf, elements may lose their original positioning

I am currently using wkhtmltopdf to create a .pdf file for printing HTML code. However, I am facing an issue where the HTML elements are getting rearranged and not staying in their original positions when I generate the pdf. Here is my code snippet for ge ...

Is there a way to adjust the slide length in JQuery's slideUp function using pixels? It seems like

At the bottom of a page, I have a fixed position div element. There is another div below it, but it is hidden outside of the page margins. I am attempting to slide both divs upwards so that the bottom one becomes visible (moving out of the margin). However ...

What is the best method for testing routes implemented with the application router in NextJS? My go-to testing tool for this is vitest

Is it possible to test routes with vitest on Next.js version 14.1.0? I have been unable to find any information on this topic. I am looking for suggestions on how to implement these tests in my project, similar to the way I did with Jest and React Router ...

Tips for sending and retrieving parameters using the POST technique

Currently, I am in the process of building a user authentication form for my website using Javascript. I am utilizing Vue JS on the client-side and NodeJS with ExpressJS on the server-side. For the server-side functionality, I have implemented the followi ...

Display the following information as you iterate through an array in TypeScript within a React component

Currently, I am working on adding data to two separate arrays in a React TypeScript project. const [deviceNames, setDeviceNames] = useState<Array<string>>([]) const [serialNumbers, setSerialNumbers] = useState<Array<string>>([]) ...

A guide on seamlessly incorporating FlotJs functionalities into a ReactJs application

Having trouble integrating Flot charts into React due to a '$.plot' is not a function error. Here's the code I'm using: Script tags Index.html <script src="dist/libs/js/jquery.min.js"></script> <script src="dist/libs/js ...

Tips for concealing elements beyond div boundaries

First and foremost, I want to mention that my focus is on studying frontend development, so I could really use some assistance with a task. I am looking to create a tab slider where the content on the left and right will flank it, ensuring the tab slider ...

Steps for incorporating one item into another object

I'm struggling to add an object to another object. I've created an object with two properties and now I want to assign it to another object. $scope.urlMappings = {}; $scope.Mapping = function() { ...

How can successful AJAX requests access PHP data?

Do you know how I can run a basic PHP code using AJAX and receive the data back from the PHP page in the AJAX success function? I am facing an issue where I am not getting anything in the AJAX success callback from the PHP page, and it's really bothe ...

Using optional chaining on the left side in JavaScript is a convenient feature

Can the optional chaining operator be used on the left side of an assignment (=) in JavaScript? const building = {} building?.floor?.apartment?.number = 3; // Is this functionality supported? ...

What are the steps to create a button with similar design using css3?

How can I create a button with the same lower part as shown in this picture? I've already achieved 50% of it with border-radius, but need help expanding the lower part to match. Any suggestions? https://i.sstatic.net/3ZJFS.jpg .list{ height: 280px; ...

Trigger route handlers on both, successful authentication and failure, when using passport.js with a Node.js and Express.js REST API

Check out this simple login/token process using passport basic strategy for a Rest API: The Route: router.get('/token', authenticate.basic, controller.token); Authenticate Basic Strategy: authenticate.basic = passport.authenticate('basic ...

Use two queries to apply filters to entries in NextJS

Greetings to all! I am currently working on a project in NextJS that involves showcasing a portfolio of works generated from JSON data. [ { "title": "WordPress Plugin for Yandex Recommender Widget", "image" ...

Trigger the rowContextMenu in Tabulator Table by clicking a Button

Is there a way to add a button at the end of a table that, when clicked, opens a rowContextMenu below the button? Additionally, can the rowContextMenu pop up when right-clicking anywhere on the row? I have attempted some solutions without success. Here is ...