What is the method for altering a CSS element's keyframe animation while it is currently running?

My little mouse speed detector, although not perfect, provides me with the current mouse speed every 100ms in the variable window.mouseSpeed.t. I decided to implement this feature because I wanted to create a whimsical animation at the bottom edge of the screen. This animation involves a bar that grows with higher speeds and shrinks with lower speeds, all to be animated using Element.animate(). However, I have encountered a problem: How can I change the end keyframe of the Animation while the animation is running? My goal is to smoothly transition the bar's length.

// Below is the code that I wish to animate.

// Tracking mouse speed (I hope this code isn't too terrible):
document.addEventListener('DOMContentLoaded', trackMouseSpeed, {once:true});
function trackMouseSpeed() {
    var speedX = NaN;
    var speedY = NaN;
    var posX = NaN;
    var posY = NaN;
    var speed = NaN;

    document.addEventListener("mousemove", function(ev){
        speedX += Math.abs(ev.movementX);
        speedY += Math.abs(ev.movementY);
        speed = 10*Math.sqrt(ev.movementX**2+ev.movementY**2);
        window.mousePosition = {x:posX = ev.clientX,y:posY = ev.clientY};
    }, false);

    setInterval(function(){
        [window.mouseSpeed, window.mousePosition] = [{x:speedX,y:speedY,t:speed}, {x:posX,y:posY}];
        speed = totalX = totalY = 0;
    }, 100);
    window.trackMouseSpeed = () => {return {speed:window.mouseSpeed, pos:window.mousePosition};};
    return {speed:window.mouseSpeed, pos:window.mousePosition};
}

// --- This is the code I want to have animated: ---
setInterval(() => {
  document.querySelector('div#mouseSpeedIndicator').style.width = window.mouseSpeed.t+'px';
}, 100);
div#mouseSpeedIndicator {
  position: fixed;
  bottom: 0px;
  left: 0px;
  height: 33px;
  background-color: green;
  max-width: 100vh;
  border: 0px solid green;
  border-top-right-radius: 10px;
}
<!-- What I currently have -->
<div id="mouseSpeedIndicator"></div>

Answer №1

Initially, a minor adjustment such as a single additional line of code within the transition CSS property like so ...

transition: width 1s ease-out;

... is all that is needed; no necessity for extensive JavaScript calculations and manipulation of the Document Object Model (DOM).

Although, the original poster's script could be significantly streamlined with or without using an external helper function like throttle (such as lodash _.throttle or underscorejs _.throttle) where the latter option would postpone the execution of the specified function in the OP's script, which in this case is the 'mousemove' event listener.

Prior to being throttled (or even without throttling), this event listener could be implemented as a bound function responsible for determining the speed value and updating the appearance of the indicator node.

function updateSpeedIndicatorFromBoundData(evt) {
  const { movementX, movementY } = evt;
  const { element, timer } = this;

  // Prevent nullification of indicator.
  clearTimeout(timer);

  // Calculate `speed`.
  const speed = 10 * Math.sqrt(movementX**2 + movementY**2);

  // Update indicator appearance.
  element.style.width = `${ speed }px`;

  // Schedule delayed nullification of indicator.
  this.timer = setTimeout(() => element.style.width = 0, 110);
}

function initializeSpeedIndicator() {
  document
    .addEventListener(
      'mousemove',
     
      // Create throttled version of the newly bound handler.
      _.throttle(
        
        // Define handler function with contextual data binding.
        updateSpeedIndicatorFromBoundData.bind({
          
          element: document.querySelector('#speedIndicator'),
          timer: null,
    
        }), 100
      ),
      false
    );
}

// - Initialization of the indicator does not require
//   the use of 'DOMContentLoaded'.
initializeSpeedIndicator();
div#speedIndicator {
  position: fixed;
  top: 0px;
  left: 0px;
  height: 33px;
  background-color: green;
  max-width: 100vh;
  border: 0px solid green;
  border-bottom-right-radius: 10px;

  /* Suggested modification(s) */

  transition: width 1s ease-out;
  /* transition: width .5s ease-in; */
  /* transition: width .5s ease-in-out; */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

<div id="speedIndicator"></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

What causes the accordion class to activate panels with varying names?

Why are some of my accordions triggering other accordions when they have different names? I've been working on resolving the issue where opening the second accordion in the second, third, or fourth panel closes the second accordion in the first panel ...

The absence of data in a c# web api controller is causing issues with jQuery AJAX post requests

When I am sending data to a c# web api controller, I use the following method: $.ajax({ type: "POST", url: "menuApi/menu/Cost", data: JSON.stringify(order), contentType: "application/json", success: function (data) { window.alert(&apo ...

Node.js Friendship NetworkIncorporating Friendships in Node

Currently, I have successfully set up a real-time chat application using node.js and socket.io. My next goal is to allow users to create accounts, search for other users by username, and send friend requests to start chatting. I have tried searching onlin ...

For each error that occurs when there is only one item in the array during a post request

My nodejs server has a JSON schema like this: var UserSchema = new Schema({ nick: String, deviceId: String, visivel: Boolean, checks: [{date: {type:String},log: {type:Number},lng: {type:Number}}] }); In the Post code ...

I am unable to align the image in the center, what could be causing it not to center properly?

Why does my code center in mobile view but not in Desktop? How can I solve this issue? I have tried using display: block; margin: auto; width:100%; and text-align: center;, but it did not work. let $slides, interval, $selectors, $btns, currentIndex, ne ...

Creating a Circle with Pixi.js v4 and Typerscript in IONIC 2

I have been attempting to create a custom class in TypeScript that utilizes PIXI.js to draw circles. Below is the code for my home.ts class: import { Component, ViewChild, ElementRef } from '@angular/core'; import { NavController } from 'i ...

The Angular-ui typeahead feature is delivering accurate results when the backspace key is pressed

I've been using Angular-UI typeahead and it's been working fine, but I've noticed a strange behavior when I hit the backspace key - it gives the correct results. For example, if I type sector 4 The result is Sector 1 Sector 2 ...

Obtaining a worldwide JavaScript variable through AJAX JSON query

Hello, I have encountered an issue while using this code for my AJAX JSON request. When attempting to make jsonObj a global variable and then console.log() it, the debugger console shows that it is always coming up as undefined. To explain my question fur ...

Unable to display "xyz" using console.log() function upon button click

Why isn't the JavaScript function being executed in this code snippet? <form> <select type="text" name="month" id="month"> <option value="01">January</option> <option value="02">February</option> ...

Angular data binding between an input element and a span element

What is the best way to connect input texts with the innerHTML of a span in Angular6? Typescript file ... finance_fullname: string; ... Template file <input type="text" id="finance_fullname" [(ngModel)]="finance_fullname"> <span class="fullnam ...

Ensure to update the canvas prior to the function finishing

Is there a way to update the canvas element while inside a JavaScript function without waiting for the function to return? It can be frustrating when you want to keep the function running but also need to update the canvas element in real time. ...

Using Formik inside Material-UI's table components

My goal is to design a material UI table where each cell acts as a Formik input. However, I've encountered errors with Material UI when attempting to use a Formik Object within TableBody or TableItem tags. Here's an example image of what I' ...

What is the optimal method for transmitting data for a substantially large music playlist via HTTP?

I am currently in the process of developing an online music player. My main challenge lies in retrieving a comprehensive list of songs from the database and transmitting it to the user. The user should have the ability to create playlists on-the-go, hence ...

How can I modify the text that appears when hovering over an element?

Can the displayed text be altered on mouse hover? For instance, can I change the text of a H1 tag when hovering over it using HTML, CSS, and JavaScript? ...

Is there a way to recursively call a function to output JavaScript data?

In my recursive function, I am trying to return specific data after the function is completed. // Initializing my Database settings var coachdb = new AWS.DynamoDB({ ... }); // Keeping track of the current parameter's array index. var pos = 0; fun ...

Developing an interactive selector within the on() event handler

My goal is to utilize the on() event for managing dynamically created code. It functions properly when the selector is hardcoded in the on() event. However, I aim to enable it to select different elements depending on which box they choose. $("body").on( ...

Is it possible to include a base url for imports in React JS?

Conventional method for adding imports: import Sample from ‘../../../components/signup’ I want to simplify imports by removing the front dots and slashes: import Component from ‘components/signup’ Is there a way to set a base URL for imports to ...

Fetching JSON data from an external URL using AngularJS

Check out this URL that shows JSON data in the browser: I attempted to store the data in a variable with the following code: $http.get('http://api.geosvc.com/rest/US/84606/nearby?apikey=4ff687893a7b468cb520b3c4e967c4da&d=20&pt=PostalCode& ...

`CSS Toggle Smooth Transition Effect`

I am working on creating 2 CSS toggle buttons that currently have a fade in and out effect when clicked. I would like them to have a sliding animation from right to left instead. Below is the HTML, CSS, and a link to a fiddle containing my code. Thank yo ...

Emailer: Missing Salutation

While attempting to send emails using Node with Nodemailer (https://github.com/nodemailer/nodemailer), the sendMail call from the Nodemailer transporter is throwing an error message of Greeting never received when connected to an Ethereal test email accoun ...