25

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

Gert Grenander
  • 16,866
  • 6
  • 40
  • 43
Ricardo
  • 737
  • 1
  • 11
  • 16
  • I am also interested in this. I believes he means to define the animation (@-webkit-keyframes for webkit) from Javascript. Spec: http://www.w3.org/TR/css3-animations/ – Adam Heath Jul 26 '10 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? – Adam Heath Jul 26 '10 at 11:10
  • @adam-heath - see my answer for an example of using the DOM interface. – Matthew Wilcoxson Nov 19 '12 at 11:02

6 Answers6

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

Adam Heath
  • 4,703
  • 2
  • 35
  • 50
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>
Matthew Wilcoxson
  • 3,432
  • 1
  • 43
  • 48
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);
}
Darius Miliauskas
  • 3,391
  • 4
  • 35
  • 53
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);
mroy
  • 41
  • 1
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");
});
Lucy Luge
  • 21
  • 2
  • 4
    Don't use jQuery where it's not necessary... And this is the case where it's not. – m93a Sep 26 '12 at 15:48
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.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
0xC0DEGURU
  • 1,432
  • 1
  • 18
  • 39