senty
senty

Reputation: 12847

Control css transition with javascript

There is this progress bar that I am trying to control from javascript. In its demo it has this pretty nice flow, however if I try to set its width with javascript jquery $($0).css({'width': '80%'}), it looses its animation.

.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%;
    }
  }

How can I control its width without losing its animation?

https://jsfiddle.net/u2c8ft0k/

Upvotes: 0

Views: 995

Answers (4)

shmnff
shmnff

Reputation: 739

Something like this?

$('#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>

Upvotes: 1

Nandu Kalidindi
Nandu Kalidindi

Reputation: 6280

You can use Animate API (https://developer.mozilla.org/en-US/docs/Web/API/Element/animate) and control the transitions using Javascript. Check out the JSFiddle in the link or run from the attached code snippet to see if that is what you expect.

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>

Upvotes: 0

Kaiido
Kaiido

Reputation: 136568

What you want is a transition, not an animation, so don't use animation but transition.

var i = 1;
$('#change').click(function() {
  if (i == 1) {
    $('.progress').css('width', '80%');
  } else {
    $('.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: 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>

Upvotes: 3

F&#233;lix Paradis
F&#233;lix Paradis

Reputation: 6011

There's got to be a better way of achieving it, but if you only need to switch between 80% and 30%, this does the trick.

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>

Upvotes: 0

Related Questions