Ways to incorporate physics into CSS animations

Creating a loading screen with CSS and aiming for realistic behavior can be a challenge. Utilizing the

animation-timing-function: cubic-bezier(1, 0, 1, 1)
property gives a decent result, but perfecting it requires understanding how the parameters in cubic-bezier function truly work. Experimenting with different values on sites like this can help achieve desired effects.

In summary, achieving physically accurate behavior in animations can be challenging. While a CSS-only solution is preferred, incorporating JavaScript is also an option if necessary.

Below is an example:

body{
    background-color: #02a2bb;
}

.wrapper {
    padding: 50px;
    text-align: center;
}
.content {
    height: 125px;
    margin: 0 auto;
    position: relative;
    display: inline-block;
}
.ball {
    width: 25px;
    height: 25px;
    display: inline-block;
    border-radius: 50%;
    bottom: 0;
    position: relative;
    background-color: #fff;
    z-index: 1;
}
.ball-shadow {
    width: 20px;
    height: 6px;
    border-radius: 50%;
    position: absolute;
    bottom: 9px;
    left: 50%;
    -webkit-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    transform: translateX(-50%);
}
.animated {
    -webkit-animation-duration: 1s;
    -moz-animation-duration: 1s;
    -ms-animation-duration: 1s;
    -o-animation-duration: 1s;
    animation-duration: 1s;
    -webkit-animation-fill-mode: both;
    -moz-animation-fill-mode: both;
    -ms-animation-fill-mode: both;
    -o-animation-fill-mode: both;
    animation-fill-mode: both;
    -webkit-animation-iteration-count: infinite;
    -moz-animation-iteration-count: infinite;
    -ms-animation-iteration-count: infinite;
    -o-animation-iteration-count: infinite;
    animation-iteration-count: infinite;
}
.animated.jump, .animated.displace, .animated.diffuse-scale {
    -webkit-animation-duration: 3s;
    -moz-animation-duration: 3s;
    -ms-animation-duration: 3s;
    -o-animation-duration: 3s;
    animation-duration: 3s;
}

... (Code continues)

</div>

Suggestion

Consider using a preprocessor like Less or SCSS to define physical variables and characteristics in your animations. These tools allow for easier manipulation of values and simulation of realistic behaviors through mixins or functions. It simplifies the process and keeps the solution purely CSS-based.

Answer №1

Utilizing CSS alone is possible, however, it requires a substantial amount of time to determine the correct values for Bezier curves, keyframe positions, scale adjustments, and more. Additionally, even minor changes in layout, dimensions, or distances can necessitate starting over from scratch.

CSS animations are appealing, but incorporating a small amount of JavaScript code can yield superior results and offer greater flexibility for making modifications:

  • Set a vector for the ball
  • Establish an arbitrary gravity value
  • Calculate the vector movement and bouncing
  • Apply resulting values to the DOM element using transforms (resulting in smoother animation compared to position changes).
  • Animate using requestAnimationFrame, which synchronizes with the monitor and produces animations as smooth as CSS animations.

Sample

This demonstration showcases the basics but excludes shadow effects – that aspect can be explored independently by the reader.

If a more precise floor bounce effect is desired, adjusting the actual position differential post-bounce can achieve this:

if (pos.y > bottom) {
    var diff = pos.y - bottom;
    pos.y = bottom - diff;
    ...

For multiple elements requiring similar animation, creating an object capable of instantiating references to animate, perform calculations, etc., proves beneficial.

To alter the direction, starting point, gravity, etc., simply update the corresponding values; playback will proceed seamlessly.

Intermediate Step Example for Generating CSS Keyframes

The above code can be adapted to compute numbers for a CSS-animation sequence.

Numerous frames can be normalized within a defined range, computations run based on frame count, data extracted per every specified interval (e.g., every 10 frames), including bounces, followed by formatting these figures into keyframes.

Incorporating top and bottom positions is pivotal, detectable through monitoring the vector’s y-value directional change (not illustrated here).

This approach serves as an interim procedure to generate associated CSS rules which will subsequently be utilized:

var v = {x: 2.3, y: 1},       // some vector
    pos = {x: 100, y: 20},    // some position
    g = 0.5,                  // some gravity
    absorption = 0.7,         // friction/absorption
    bottom = 150,             // floor collision
    frames = 0,               // to reset animation (for demo)
    maxFrames = 220,          // normalization parameter
    step = 10,                // interval specifier
    heights = [],             // storage array
    css = "";                 // CSS animation construction

// CSS-frame calculation
for(var i = 0; i <= maxFrames; i++) {
  var t = i / maxFrames;
  pos.x += v.x;              
  pos.y += v.y;
  v.y += g;                   

  if (pos.y > bottom) {
    pos.y = bottom;
    v.y = -v.y * absorption;
    heights.push({pst: t * 100, y: pos.y});
  }  
  else if (!(i % step)) {heights.push({pst: t * 100, y: pos.y})}  
}

// Formatting height-array into CSS
css += "@keyframes demo {\n";
for(i = 0; i < heights.length; i++) {
  var e = heights[i];
  css += "  " + e.pst.toFixed(3) + "% {transform: translateY(" + e.y.toFixed(3) + "px)}\n";
}
css += "}";

document.write("<pre>" + css + "</pre>");

Applying the resultant CSS to the final page yields the following outcome, showcasing solely the non-prefixed version during this demonstration:

(Advanced tweaking may be needed for optimal results, though the fundamental concept remains valid.)

div  {
  animation: demo 3s linear infinite;
  width:20px;
  height:20px;
  border-radius:50%;
  background:rgb(0, 148, 243);
  position:fixed;
  left:100px;
}

@keyframes demo {
  0.000% {transform: translateY(21.000px)}
  4.545% {transform: translateY(58.500px)}
  ...
}
<div></div>

Considering the precision required for such animations, I personally recommend leveraging JavaScript support over CSS due to its accuracy and adaptability to evolving demands.

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

Storing specific items in an array for easy access on the following page

I have some code that extracts specific keys and values from a row and then sends them to the next page. let HistoryData = []; for (const [key, value] of Object.entries(this.Items)) { HistoryData.push(value) } this.$router.push( ...

Using jQuery to reload the page following a PHP form submission

Currently facing an issue as I am trying to load the same page submitted by PHP, specifically in a comment section. After users submit their message, I want to display the existing comments along with the new one. The problem arises because I'm not u ...

What methods can be used to determine if a bound function is equal when performing unit testing?

I am looking to verify that when I pass an argument to a function, it is indeed a function reference even though the function reference is passed using the bind() method. Take a look at this shortened code snippet that needs to be tested: initialize: fun ...

Arranging search results in Django from the get_queryset method

I am currently using Django 2.2.10 as my framework for a project. I have implemented a search bar that returns search results to the show page, utilizing the `get_queryset(self)` method in the SearchResultsView (ListView) class. I have configured paginate_ ...

The tooltip for the Google+ button stopped working

After setting up my Portfolio, I added a Google+ button. However, the page lacks styling and there seems to be an issue with the tooltip causing delays. Can anyone help me identify where the problem lies? ...

Creating a striking two-tone border pattern in an HTML document

Looking to create a design with a straight line that features two colors and a slanted line in between. Here is an example of the desired result: https://i.stack.imgur.com/9ys6e.png ...

Both if and else statements are carrying out code in JavaScript/jQuery

The second if statement is functioning correctly, but the first one always triggers the else statement and never stands alone. This jQuery function is enclosed within another function that is invoked under the "$(document).ready" command. I resorted to u ...

Text that appears as an HTML button is displayed after being compiled using the $

I am attempting to generate a pop up dialog with two buttons using JS code in angular. The script below is what I am using to create the buttons... var html = $('<button ng-click = "cancelAlert()" > Cancel</button > <button ng-click="c ...

What are the best strategies for mastering conditional promises in Angular?

I've been struggling with a problem in angularjs for several hours now. Here's the pseudo code I'm working with: doSomething(param){ var res; if(param = "ok"){ //perform some api calls with promises res = promise r ...

What is the proper way to nest HTML comments within one another?

This question is bothering me because I want to comment out a piece of code but it's not working as expected. Here is the code snippet: <!-- {if $scenes} <!-- Scenes --> {include file="$tpl_dir./scenes.tpl" ...

When attempting to display the details of each restaurant on my detail page, I encountered the error "Cannot read property 'name_restaurant' of undefined."

I have set up dynamic routing for a ProductDetail page, where each restaurant has its own details that should be displayed. The routing is functional, but I am facing difficulty in retrieving data from Firestore using the restaurant's ID. PS: Althoug ...

NG0303: Unable to establish a connection with 'ngbTooltip' as it is not recognized as a valid property of 'button'

ERROR: 'NG0303: Can't bind to 'ngbTooltip' since it isn't a known property of 'button'.' Encountering this issue in my Angular 12 project when running local tests, the ngbTooltip error is present in all .spec files. ...

Dealing with the challenge of duplicate posts in JqWidgets context menu within a nested grid scenario

I have encountered a double posting issue in the JqWidgets context menu for a nested grid. The event is triggering multiple times (where "n" is the number of times I clicked the context menu). In addition, if I place the event handler method outside the c ...

Applying CSS transitions and transforms to SVG elements

Having trouble animating an SVG group with CSS transitions after applying a CSS transform? Check out my code below and let me know if you spot the issue. Inline SVG Code <a href="javascript:void(0)" class="hub-icon-container"> <svg xmlns="ht ...

The Server Side Rendering in (Vue+Express) faltered due to inconsistencies in hydration

While browsing Vue's official website, I came across a concise example demonstrating how to implement server-side rendering (SSR) using Vue. (https://stackblitz.com/edit/vue-ssr-example-qaztqn?file=package.json) Intrigued by this example, I decided ...

Can a function be called from outside its parent function?

I was pondering the possibility of calling a function from outside its parent function: var $element = $( '.element' ); function myFunction( element ) { var width; function onResize() { width = element.width(); } onResi ...

Opacity is causing issues with hover effects in CSS

I'm facing an unusual CSS challenge. Check out this simple code snippet below that showcases the issue: <html> <head> <style> .hover { float: right; } .hover:hover { background-color: blue; ...

How can I include text input within a select option using angular-material?

I am in the process of developing a form that allows users to input personal information. One feature I would like to include is a dropdown list for phone numbers and fax numbers associated with the individual, giving users the option to choose from thos ...

Using Three.js to control the camera's position and direction

Despite hours of searching, I have been unable to find a solution to a fundamental issue in Three.js. I know the position of the camera (my eyes), the direction the camera is facing (my eyes), and the direction my head is pointing. I need to create the cam ...

Exploring web pages with JavaScript events

I am currently trying to compile a list of singles that were released in the year 2018 from allmusic.com. While accessing their advanced search page and setting the parameters is simple enough, the challenge lies in extracting the information manually. Th ...