最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

css - How to change the execution time of an infinite animation(in CSS3) smoothly with Javascript - Stack Overflow

programmeradmin5浏览0评论

I have searched through a lot of questions related to my question in stackoverflow but i haven't found one yet that answers my question with plain JavaScript (not using libraries of any kind).

My problem is that I have an infinite animation with CSS3 i.e.:

.clockwiseAnimation {
    top: 270px;
    left: 200px;
    position: absolute;

    -webkit-animation: clockwise 4s linear infinite; /* Chrome, Safari 5 */
    -moz-animation: clockwise 4s linear infinite; /* Firefox 5-15 */
    -o-animation: clockwise 4s linear infinite; /* Opera 12+ */
    animation: clockwise 4s linear infinite; /* Chrome, Firefox 16+, IE 10+, Safari 5 */
}
@-webkit-keyframes clockwise {
    from { -webkit-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -webkit-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-moz-keyframes clockwise {
    from { -moz-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -moz-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-o-keyframes clockwise {
    from { -o-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -o-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@keyframes clockwise {
    from { transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}

This animation allows me to spin (clockwise) whatever tag that has the class "clockwiseAnimation".

What I want to do is to change the time of execution (I'll call it speed) of the animation with javascript like:

HTML:

<span id="someID" class="clockwiseAnimation">sometext</span>

JavaScript:

var style = document.getElementById("someID").style,
speed = 6; 
//obviously the speed is dynamic within my site (through an `<input type="range">`)
//for the purposes of this example I set the speed to a different value(6seconds) than the original value(4seconds).
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";

It works when I pause and then play(by play I mean UNPAUSE not restart) the animation, i.e.:

var style = document.getElementById("someID").style;
some = 6; //it is dynamic (as I pointed out before)

//pause
style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "paused";

//change speed
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";  

//play (== UNPAUSE) //UPDATE: Added the timeout because I can't get it to work any other way.
setTimeout(function(){
            style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "running";
        },1);

UPDATED:

And it works! BUT, it has a big RANDOM jump in the animation, meaning that when I change the "speed" with the "<input type="range"> slider" the element jumps to a random location (not the beginning nor the end of the animation just a random location).

NOTE: Pause and play works very smooth without changing the "speed" of the animation.

My question(s): Can I change the "speed" of the animation smoothly WITH JavaScript? (WITHOUT the jumping) If the answer is: "There is not a way to do it smoothly throughout the animation execution", then: Is there a way to change it in the next iteration of the infinite animation? If so: Then how can I tell it to start in the next iteration and how to know which is the next iteration if I set the animation to infinite (animation-iteration-count property of the element that is doing the animation always returns "infinite").

Here is an example. I hope it helps.

I have searched through a lot of questions related to my question in stackoverflow but i haven't found one yet that answers my question with plain JavaScript (not using libraries of any kind).

My problem is that I have an infinite animation with CSS3 i.e.:

.clockwiseAnimation {
    top: 270px;
    left: 200px;
    position: absolute;

    -webkit-animation: clockwise 4s linear infinite; /* Chrome, Safari 5 */
    -moz-animation: clockwise 4s linear infinite; /* Firefox 5-15 */
    -o-animation: clockwise 4s linear infinite; /* Opera 12+ */
    animation: clockwise 4s linear infinite; /* Chrome, Firefox 16+, IE 10+, Safari 5 */
}
@-webkit-keyframes clockwise {
    from { -webkit-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -webkit-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-moz-keyframes clockwise {
    from { -moz-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -moz-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-o-keyframes clockwise {
    from { -o-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -o-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@keyframes clockwise {
    from { transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}

This animation allows me to spin (clockwise) whatever tag that has the class "clockwiseAnimation".

What I want to do is to change the time of execution (I'll call it speed) of the animation with javascript like:

HTML:

<span id="someID" class="clockwiseAnimation">sometext</span>

JavaScript:

var style = document.getElementById("someID").style,
speed = 6; 
//obviously the speed is dynamic within my site (through an `<input type="range">`)
//for the purposes of this example I set the speed to a different value(6seconds) than the original value(4seconds).
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";

It works when I pause and then play(by play I mean UNPAUSE not restart) the animation, i.e.:

var style = document.getElementById("someID").style;
some = 6; //it is dynamic (as I pointed out before)

//pause
style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "paused";

//change speed
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";  

//play (== UNPAUSE) //UPDATE: Added the timeout because I can't get it to work any other way.
setTimeout(function(){
            style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "running";
        },1);

UPDATED:

And it works! BUT, it has a big RANDOM jump in the animation, meaning that when I change the "speed" with the "<input type="range"> slider" the element jumps to a random location (not the beginning nor the end of the animation just a random location).

NOTE: Pause and play works very smooth without changing the "speed" of the animation.

My question(s): Can I change the "speed" of the animation smoothly WITH JavaScript? (WITHOUT the jumping) If the answer is: "There is not a way to do it smoothly throughout the animation execution", then: Is there a way to change it in the next iteration of the infinite animation? If so: Then how can I tell it to start in the next iteration and how to know which is the next iteration if I set the animation to infinite (animation-iteration-count property of the element that is doing the animation always returns "infinite").

Here is an example. I hope it helps.

Share Improve this question edited Jan 23, 2014 at 23:06 pgarciacamou asked Jan 23, 2014 at 1:47 pgarciacamoupgarciacamou 1,73222 silver badges41 bronze badges 2
  • 1 Maybe easing functions will do what you want: kirupa./html5/easing_functions_css3.htm – Steve Wellens Commented Jan 23, 2014 at 1:58
  • That tutorial allowed me to understand MORE about the animations but what I'm trying to do is changing them through js without jumping through points in the animation when modifying it. – pgarciacamou Commented Jan 23, 2014 at 18:10
Add a ment  | 

4 Answers 4

Reset to default 1

What may be occurring is that the animation-duration "change" could be "jumping" to the point in the animation corresponding to the "changed" @keyframes - based on the total "changed" animation duration..

If the animation-duration began from (or 0%) proceeded to to (or 100%), the corresponding @keyframes "position" may be changed as well.

For example if the original animation-duration was 4s (or, 4000ms) at approximately 2s (or, 2000ms), the corresponding keyframes may be at approximately 50%, or

at 2 seconds into 4 second animation 50% { -webkit-transform: rotate(180deg) translateX(150px) rotate(-180deg); }

when the animation-duration is dynamically changed, the corresponding keyframes may be "changed" to the matching % point, or, a larger duration span for the same effect. The animated element may appear to go forwards or backwards, or hve a "jumping" due to it re-positioning itself within the "changed" corresponding keyframes and animations.

There is also 1s setTimeout function, that may or may not actually have a 1s duration.

It may be possible to "smoothly" "jump" to the newly "changed" position within the lengthier animation-duration the suggested transition effect or requestAnimationFrame (http://www.w3/TR/animation-timing/).

..

Try this:

html

<input type="range" id="speedSlider" min="2000" max="6000" value="4000">

css

    input {
    -webkit-transform: rotate(180deg);  
    top : 50px;
    position : absolute;
}

.clockwiseAnimation {
 /* top: 270px;
    left: 200px; */
    left : 50%;
    top : 50%;
    position:absolute;

   /* css animation (no change) */
}

js

var speedSlider = document.getElementById("speedSlider");
    speedSlider.addEventListener("change", changeSpeed, false);
    function changeSpeed(e){
        var speed = Math.floor(speedSlider.value);
        var element = document.getElementById("span");
        var style = element.style;
        style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "paused";
        style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = String(speed) + "ms";
            style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "running";
    }

With CSS: http://jsbin./UsunIMa/1/

CSS properties transition and animation allow you to pick the easing function.

div {
  transition:         all 600ms cubic-bezier(0.77, 0, 0.175, 1); 
  /* or */
  animation: clockwise 4s cubic-bezier(0.77, 0, 0.175, 1) infinite;
}

use setTimeout to add animation class to your required element with the removal of animation class as a callback.

Maybe jQuery queue could help you.

Here it is

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论