Manipulate the timing of css animations using javascript

I am currently working with a progress bar that I need to manipulate using JavaScript. The demo of the progress bar has a smooth animation, but when I try to adjust its width using jQuery $($0).css({'width': '80%'}), the animation disappears.

.progress-bar {
    margin: 0 auto;
    width: 100%;
    height: 10px;
    background-color: #e5e9eb;
}

.progress-bar .progress {
    position: relative;
    background-color: #90ee90;
    height: 10px;
    width: 100%;
    -webkit-animation-duration: 5s;
    -webkit-animation-name: width;
}

.progress-bar .progress .progress-shadow {
    background-image: linear-gradient(to bottom, #eaecee, transparent);
    position: absolute;
    height: 4em;
    width: 100%;
    top: 100%;
    transform: skew(-22.5deg);
    transform-origin: 0 0;
}

@-webkit-keyframes width {
    0%, 100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }

    0% {
        width: 0;
    }

    100% {
        width: 100%;
    }
  }

Is there a way to adjust the width of the progress bar without disrupting its animation?

https://jsfiddle.net/u2c8ft0k/

Answer №1

To achieve the desired effect, utilize a transition instead of an animation. Replace the use of animation with transition.

var count = 1;
$('#change').click(function() {
  if (count == 1) {
    $('.progress').css('width', '80%');
  } else {
    $('.progress').css('width', '30%');
  }

  count == 1 ? count++ : count--

});
.progress-bar {
  margin: 0 auto;
  width: 100%;
  height: 10px;
  background-color: #e5e9eb;
}

.progress-bar .progress {
  position: relative;
  background-color: #90ee90;
  height: 10px;
  width: 0%;
  transition: width 5s cubic-bezier(1, 0, 0.65, 0.85);
}

.progress-bar .progress .progress-shadow {
  background-image: linear-gradient(to bottom, #eaecee, transparent);
  position: absolute;
  height: 4em;
  width: 100%;
  top: 100%;
  transform: skew(-22.5deg);
  transform-origin: 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container text-center">
  <div class="progress-bar">
    <div class="progress">
      <div class="progress-shadow"></div>
    </div>
  </div>
</section>

<br /><br /><br /><br /><br /><br />
<button id="change">Change Width</button>

Answer №2

Is this what you had in mind?

$('#change-0').click(function() {
  $('.progress').css('width', '0%');
});
$('#change-50').click(function() {
  $('.progress').css('width', '50%');
});
$('#change-100').click(function() {
  $('.progress').css('width', '100%');
});
.progress-bar {
    margin: 0 auto;
    width: 100%;
    height: 10px;
    background-color: #e5e9eb;
}
.progress {
    position: relative;
    background-color: #90ee90;
    height: 10px;
    width: 0%;
    transition: width 2s;
}
.progress-shadow {
    background-image: linear-gradient(to bottom, #eaecee, transparent);
    position: absolute;
    height: 4em;
    width: 100%;
    top: 100%;
    transform: skew(-22.5deg);
    transform-origin: 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container text-center">
  <div class="progress-bar">
    <div class="progress">
      <div class="progress-shadow"></div>
    </div>
  </div>
</section>
<br /><br /><br /><br />
<button id="change-0">0%</button>
<button id="change-50">50%</button>
<button id="change-100">100%</button>

Answer №3

There must be a more efficient way to accomplish this task, but if you only require switching between 80% and 30%, then this solution works well.

var i = 1;
$('#change').click(function() {
if (i == 1) {
    $('.progress-bar .progress').css('-webkit-animation-duration', 'initial'); 
    $('.progress-bar .progress').css('-webkit-animation-name', 'initial'); 

    $('.progress-bar .progress').css('-webkit-animation-duration', '1s'); 
    $('.progress-bar .progress').css('-webkit-animation-name', 'widthEighty'); 

   
    $('.progress').css('width', '80%');
  } else {
  $('.progress-bar .progress').css('-webkit-animation-duration', 'initial'); 
    $('.progress-bar .progress').css('-webkit-animation-name', 'initial'); 

    $('.progress-bar .progress').css('-webkit-animation-duration', '1s'); 
    $('.progress-bar .progress').css('-webkit-animation-name', 'widthThirty'); 

  $('.progress').css('width', '30%');
  }
  
  i == 1 ? i++ : i--

});
.progress-bar {
    margin: 0 auto;
    width: 100%;
    height: 10px;
    background-color: #e5e9eb;
}

.progress-bar .progress {
    position: relative;
    background-color: #90ee90;
    height: 10px;
    width: 100%;
    -webkit-animation-duration: 1s;
    -webkit-animation-name: width;
}

.progress-bar .progress .progress-shadow {
    background-image: linear-gradient(to bottom, #eaecee, transparent);
    position: absolute;
    height: 4em;
    width: 100%;
    top: 100%;
    transform: skew(-22.5deg);
    transform-origin: 0 0;
}

@-webkit-keyframes width {
    0%, 100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }

    0% {
        width: 0;
    }

    100% {
        width: 100%;
    }
}

@-webkit-keyframes widthEighty {
    0%, 100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }

    0% {
        width: 30%;
    }

    100% {
        width: 80%;
    }
}

@-webkit-keyframes widthThirty {
    0%, 100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }

    0% {
        width: 80%;
    }

    100% {
        width: 30%;
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container text-center">
  <div class="progress-bar">
    <div class="progress">
      <div class="progress-shadow"></div>
    </div>
  </div>
</section>

<br /><br /><br /><br /><br /><br />
<button id="change">Change Width</button>

Answer №4

Utilize the Animate API (https://developer.mozilla.org/en-US/docs/Web/API/Element/animate) and manage transitions with Javascript. Explore the JSFiddle provided in the link or execute the code snippet to see if it meets your expectations.

https://jsfiddle.net/xfct4rpx/2/

var i = 1;

var progress = document.getElementsByClassName("progress")[0];

$('#change').click(function() {
if (i == 1) {
    progress.animate([{width: "0%"}, {width: "30%"}], {duration: 5000, easing: "cubic-bezier(1, 0, 0.65, 0.85)"})
    setTimeout(() => {progress.style.width = "30%"}, 5000)
  //$('.progress').css('width', '30%');
  } else {
    progress.animate([{width: "30%"}, {width: "80%"}], {duration: 5000, easing: "cubic-bezier(1, 0, 0.65, 0.85)"})
    setTimeout(() => {progress.style.width = "80%"}, 5000)
  //$('.progress').css('width', '30%');
  }
  
  i == 1 ? i++ : i--

});
.progress-bar {
    margin: 0 auto;
    height: 10px;
    background-color: #e5e9eb;
}

.progress {
    position: relative;
    background-color: #90ee90;
    height: 10px;
    width: 0%;
}

.progress-shadow {
    background-image: linear-gradient(to bottom, #eaecee, transparent);
    position: absolute;
    height: 4em;
    top: 100%;
    width: 100%;
    transform: skew(-22.5deg);
    transform-origin: 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container text-center">
  <div class="progress-bar">
    <div class="progress">
      <div class="progress-shadow"></div>
    </div>
  </div>
</section>

<br /><br /><br /><br /><br /><br />
<button id="change">Change Width</button>

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

Self-contained VUE app

Can Vue.js be built as a standalone application so that I am not reliant on backend services from my web hosting provider? In essence, I would like to avoid having to start up the app through npm and instead simply open the index.html file from the dist f ...

Issue with showing an input field following the button click

I'm having a bit of trouble with this function that should add an input element to a div. I've tried using appendChild and also concatenating the object to innerHTML, but no luck so far. Could it be something my beginner's mind is missing? f ...

Stop the occurrence of OpenCPU javascript error pop-up notifications

I'm currently experiencing an error related to CORs during a test deployment of OpenCPU. While I may create a separate question for this issue in the future, for now, I am wondering if it is possible for the deployment to fail without alerting the end ...

Interactive CSS Video Gallery Slideshow

Is there a way to create a slideshow video gallery using CSS? I've looked everywhere but all I find are slideshow image galleries. If anyone has any resources or tips on how to do this, please share! This is the kind of video gallery I'm looking ...

Using jQuery to swap out intricate background designs

I'm attempting to use jQuery to change the background-color of an element from: background: transparent linear-gradient(#C0B 45%, #C0B) to: background-color:#000; Unfortunately, my attempt to remove the background property with .removeAttr() has n ...

Slider-activated Pie Chart Controller

I have successfully created a pie chart using highchart and javascript, allowing me to adjust each slice individually using a slider. However, I am facing an issue where I want the maximum value of the pie to be 100%, with the other sliders contributing to ...

Cipher/decipher URL Redirect Parameter

While sending the return URL as a query string parameter, it looks like this: http://localhost:50316/TripNestFinal/Login.aspx?ReturnUrl=~/Account/AccountSettings.aspx However, I am seeking a way to encode ~/Account/AccountSettings.aspx in a manner that wi ...

Open the window by using the `Window.open` method, then find and

Is there a way to open a document, not in a new window but on the same page using JavaScript.Window.Open()? Could it be possible to display the document within a specific div element that is obtained with getElementById? For example: document.getElementB ...

Error in material mapping: glDrawElements is trying to access vertices that are out of range in attribute 2

I have developed an algorithm that allows users to input data or a function and then generates a graphical representation of the function. It essentially creates a surface map, similar to the one you can see here. The graphing functionality is working well ...

Locate the specific version of a JavaScript library within compiled JS files

The dist folder houses the results of running npm install. If I don't have access to the original package.json file used during the compilation of the distributable, how can I determine the version of a particular library that was utilized in the ins ...

How to create a transparent background image in a Jekyll theme without impacting the visibility of the foreground

I'm new to HTML and CSS, currently working with a Jekyll boostrap landing theme from GitHub to create a static responsive website. I'm looking to change the background image on the theme and make it transparent to enhance the visibility of the fo ...

Proceed to the following part - JQuery

I am currently working on a horizontal layout and trying to use jQuery to navigate to different HTML sections when an anchor is clicked. My goal is to jump to the next section upon clicking. While I have seen examples of this being done vertically, I am s ...

Upcoming examination on SEO using React testing library

Currently, I am in the process of testing out my SEO component which has the following structure: export const Seo: React.FC<Props> = ({ seo, title, excerpt, heroImage }) => { const description = seo?.description || excerpt const pageTitle = s ...

Is it possible to achieve a callback with jQuery after loading?

Currently, I am working with PHP and jQuery and have successfully implemented the following code. $(".design").load("<?php echo get_bloginfo('url'); ?>/?addmod_ajax=1",{ menu: 'layout', }); This is my desired action. I woul ...

Encountering parameter issues while working with Google Maps React in TypeScript

Currently, I'm utilizing TypeScript in this particular file. import React, {Component} from 'react' import {Map, InfoWindow, Marker, GoogleApiWrapper, mapEventHandler, markerEventHandler} from 'google-maps-react'; import { coordina ...

Exploring First-Person Shooter Rotation with THREE.JS

I recently attempted to create a rotation system for a First Person Shooter game using THREE.JS. However, I encountered a strange issue where the camera would pause momentarily before returning, especially at certain rotations. When checking the rotation ...

### Setting Default String Values for Columns in TypeORM MigrationsDo you want to know how to

I'm working on setting the default value of a column to 'Canada/Eastern' and making it not nullable. This is the current setup for the column: queryRunner.addColumn('users', new TableColumn({ name: 'timezone_name', ...

Is there a way to deactivate the Edge mini menu while selecting text in a React application?

I have recently been working on a React web application and managed to create a specialized text selection menu. However, I am facing a challenge in programmatically disabling the default text selection mini menu in React. The image attached illustrates bo ...

Personalized Horizontal Radio Button Design

I have been struggling to achieve the desired design for radio buttons but without success. https://i.sstatic.net/TU7Ks.png Despite using bootstrap for my website, I am only able to achieve this: https://i.sstatic.net/WbzqS.png This is the code I am cu ...

Click the navigation bar to toggle it on and off

I have a script that creates a navbar. Currently, the dropdown menu only opens when hovered over. The issue arises when accessing this on a mobile browser, as the dropdown menu does not open. How can I modify this script to make the dropdown menu open wh ...