25

Is there any way to set the from or to of a webkit-keyframe with JavaScript?

3
  • I am also interested in this. I believes he means to define the animation (@-webkit-keyframes for webkit) from Javascript. Spec: w3.org/TR/css3-animations Commented Jul 26, 2010 at 11:00
  • Just noticed right down at the bottom of that spec, there is a DOM interface for this, quoted as "CSS animation is exposed to the CSSOM through a pair of new interfaces describing the keyframes." Does anyone know how this is accessed/used via Javascript? Commented Jul 26, 2010 at 11:10
  • @adam-heath - see my answer for an example of using the DOM interface. Commented Nov 19, 2012 at 11:02

6 Answers 6

14

A solution of sorts:

var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('@-webkit-keyframes slider {'+
'from { left:100px; }'+
'80% { left:150px; }'+
'90% { left:160px; }'+
'to { left:150px; }'+
'}');
cssAnimation.appendChild(rules);
document.getElementsByTagName("head")[0].appendChild(cssAnimation);

Just adds a style definition to the header. Would be much cleaner/better to define it though the DOM if possible.

Edit: Error in Chrome with old method

Sign up to request clarification or add additional context in comments.

2 Comments

Why don't you use the CSSOM API instead?
@EliGrey 7 years later, the browser compatibility of CSSOM is still low.
12

You can use the CSS DOM interface. For instance:

<html>
    <body>
        <style>
        @keyframes fadeout {
            from { opacity:1; }
            to { opacity:0; }
        }
        </style>
        <script text="javascript">
            var stylesheet = document.styleSheets[0];
            var fadeOutRule = stylesheet.cssRules[0];
            alert( fadeOutRule.name ); // alerts "fadeout"

            var fadeOutRule_From = fadeOutRule.cssRules[0];
            var fadeOutRule_To = fadeOutRule.cssRules[1];
            alert( fadeOutRule_From.keyText ); // alerts "0%" ( and not "from" as you might expect)
            alert( fadeOutRule_To.keyText ); // alerts "100%"

            var fadeOutRule_To_Style = fadeOutRule_To.style;

            alert( fadeOutRule_To_Style.cssText ); // alerts "opacity:0;"

            fadeOutRule_To_Style.setProperty('color', 'red'); // add the style color:red
            fadeOutRule_To_Style.removeProperty('opacity'); // remove the style opacity

            alert( fadeOutRule_To_Style.cssText ); // alerts "color:red;"
        </script>
    </body>
</html>

Comments

6

This example covers several different browsers:

var keyFramePrefixes = ["-webkit-", "-o-", "-moz-", ""];
var keyFrames = [];
var textNode = null;

for (var i in keyFramePrefixes){

keyFrames = '@'+keyFramePrefixes[i]+'keyframes cloudsMove {'+
'from {'+keyFramePrefixes[i]+'transform: translate(0px,0px);}'+
'to {'+keyFramePrefixes[i]+'transform: translate(1440px'
'px,0px);}}';

textNode = document.createTextNode(keyFrames);
document.getElementsByTagName("style")[0].appendChild(textNode);
}

Comments

4

The way I handle this is to not set either the from or to of the element style I am manipulating in the css file and before triggering the animation I will set the element style that it should go to with javascript. This way you are free to dynamically manage what stuff should do until we can manage this directly in js. You only need to specify one of the two. The setTimeout allows the application of the css rule to the element before the animation is triggered otherwise you would have a race condition and it wouldn't animate.


#someDiv.slideIn {
    -webkit-animation: slideIn 0.5s ease;
}

@-webkit-keyframes slideIn {
    0% {
        left:0px;
    }

    100% {}
}


var someDiv = document.getElementById('someDiv');
someDiv.style.left = '-50px';
setTimeout(function(){
    someDiv.addClass('slideIn');
},0);

1 Comment

What is the purpose to use setTimeout with 0?
1

To solve this I added a 'webkit animation name' to my CSS selector and then created separate rules for my options, in my example red and yellow colouring:

.spinner {
-webkit-animation-name: spinnerColorRed;
}

@-webkit-keyframes spinnerColorRed {
  from {
    background-color: Black;
  }
  to {
    background-color: Red;
  }
}

@-webkit-keyframes spinnerColorYellow {
  from {
    background-color: Black;
  }
  to {
    background-color: Yellow;
  }
}

Then using jQuery:

$("#link").click(function(event) { 
  event.preventDefault();
  $(".spinner").css("-webkit-animation-name", "spinnerColorYellow");
});

1 Comment

Don't use jQuery where it's not necessary... And this is the case where it's not.
0

Yes, there is a way to do it dynamically with JavaScript. You can use css animation directives in native javascript code with the function Element.animate(). This approach is widely supported across browser, except for IE.

document.getElementById("tunnel").animate([
  // keyframes
  { transform: 'translateY(0px)' },
  { transform: 'translateY(-300px)' }
], {
  // timing options
  duration: 1000,
  iterations: Infinity
});

This function accepts two arguments - keyframes and options. Inside options you can specify the css animation parameters. Inside keyframes you can specify one or many transitional states. In your case with from and to you need two keyframes.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.