Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Webkit Keyframes Values Using Javascript Variable

I have a piece of JS code to generate random numbers and output them as variables to be used here in place of the rotation values

@-webkit-keyframes rotate {
    0% {-webkit-transform: rotate(-10deg);}
    100% {-webkit-transform: rotate(10deg);}
}

#dog{
/*irrelevant settings*/
-webkit-animation: rotate 5s infinite alternate ease-in-out;
}

The code above works fine however when I try to stick the variables from the javascript into rotate(variable); I cannot get it to work. I am new to this so I'm 90% sure I just haven't got the syntax right for the variable (seriously I am terrible at remembering if something needs brackets, quotes, squigglys etc and I have tried all I can think of).

Or it might be because the variable is local to the function and CSS cannot read that.

So basically I just need some kind stranger to tell me the correct syntax and how to get CSS to read the variable if possible.

Otherwise it looks like I will need the function to create the entirety of:

@-webkit-keyframes rotate {
    0% {-webkit-transform: rotate(-10deg);}
    100% {-webkit-transform: rotate(10deg);}
}

...which might be a bit messy since the random variable will likely be applied to multiple css elements.

Oh and currently the variable is formatted to include the deg after the number so that is not the issue. In fact, for the sake of ease just assume I am using var dogValue = "20deg"; and forget the random element.

Thanks.

like image 911
Sasha Avatar asked Apr 26 '12 22:04

Sasha


3 Answers

Okay, not what your actual code looks like, but you can't throw JavaScript variables into CSS, it won't recognize them.

Instead, you need to create the CSS rules through JavaScript and insert them into the CSSOM (CSS Object Model). This can be done a few ways -- you can either just create a keyframe animation and add it in, or you can overwrite an existing animation. For this sake of this question, I'm going to assume you want to continually overwrite an existing keyframe animation with different rotation values.

I've put together (and documented) a JSFiddle for you to take a look at: http://jsfiddle.net/russelluresti/RHhBz/2/

It starts off running a -10 -> 10 degree rotation animation, but then you can click the button to have it execute a rotation between random values (between -360 and 360 degrees).

This example was hacked together primarily from earlier experimentation done by Simon Hausmann. You can see the source here: http://www.gitorious.org/~simon/qtwebkit/simons-clone/blobs/ceaa977f87947290fa2d063861f90c820417827f/LayoutTests/animations/change-keyframes.html (for as long as that link works, gitorious is pretty bad at maintaining urls).

I've also taken the randomFromTo JavaScript function code from here: http://www.admixweb.com/2010/08/24/javascript-tip-get-a-random-number-between-two-integers/

I've added documentation to the parts of the Simon Hausmann script that I've taken from him (though I've slightly modified them). I've also used jQuery just to attach the click event to my button--all other script is written in native JavaScript.

I've tested this for Chrome 18 and Safari 5.1, and it seems to work fine in both browsers.

Hope this helps.

like image 197
RussellUresti Avatar answered Nov 06 '22 01:11

RussellUresti


In chrome 49 onwards and Firefox 48 onwards you can leverage the new Javascript API element.animate() to push in your keyframe animations.

Please be informed that this API is experimental and doesn't work cross browser except for the aforementioned.

Dated solutions like adding class or injecting keyframes could be leveraged for backward compatibility. A shim for the same was not available immediately.

Yanked the MDN example

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

refer:

  • caniuse.com/#feat=web-animation
  • MDN documentation
like image 41
DDM Avatar answered Nov 06 '22 01:11

DDM


For anyone that is looking for this answer in 2017 here's what's changed in RussellUresti answer.

In his example this won't work anymore:

keyframes.insertRule("0% { -webkit-transform: rotate(" + randomFromTo(-360,360) + "deg); }");
keyframes.insertRule("100% { -webkit-transform: rotate(" + randomFromTo(-360,360) + "deg); }");

This is due to .insertRule() being a non standard name. It is now .appendRule(), so RusselsUresti's code will now be:

keyframes.appendRule("0% { -webkit-transform: rotate(" + randomFromTo(-360,360) + "deg); }");
keyframes.appendRule("100% { -webkit-transform: rotate(" + randomFromTo(-360,360) + "deg); }");

(Simply replace insertRule with appendRule.)

More information on the CSSKeyframeRule can be found here

like image 9
connoraworden Avatar answered Nov 06 '22 00:11

connoraworden