Yesterday Chris Heilmann wrote a post on the Mozilla blog about detecting and generating CSS animations using JavaScript. The article features a small example from myself demonstrating the rather verbose technique required to access a CSS animation with code.
Chris ends his article with the following:
I’d love to have a
CSSAnimationscollection for example where you could store different animations in JSON or as a string and have their name as the key. Right now, creating a new rule dynamically and adding it either to the document or append it to the ruleset seems to be the only cross-browser way. Thoughts?
This seemed like a great idea so I set about creating a small JavaScript shim to provide this interface.
CSS Animation Store
The idea is to create a simple interface for accessing CSS Animations from within JavaScript. This is something I’ve done a couple of times in the past with Morf.js and CSSA so had most of the code written already, it just needed wrapping up in the suggested JSON style interface that Chris described.
Download CSS Animation Store from GitHub
Here is the basic interface for the CSS Animation Store (for information on how the script works see below). Include the JavaScript just before the closing </html> and it will expose a new global object called CSSAnimations. The object contains each available CSS Animation currently available.
So, to get an animation named ‘spin’ you would do the following:
var spin = CSSAnimations.spin;
The variable spin now holds an instance of a KeyframeAnimation object, which has the following properties and functions:
keyframesarray ofKeyframeRuleobjectsoriginalgives access to the nativeWebKitCSSKeyframesRuleorMozCSSKeyframesRuleobject this object wrapsgetKeyframeTexts()returns an array of all available keyframe texts, e.g. ['0%', '50%', '100%']getKeyframe(text)returns aKeyframeRulebased on the provided text, e.g.getKeyframe('0%')setKeyframe(text, css)sets the CSS for a keyframe the given text, e.g.setKeyframe('10%', {background: 'red', 'font-size': '2em'})
As you can see, a few of these methods/properties also deal with another type of object called KeyframeRule. This is a wrapping around the WebKitCSSKeyframeRule and MozCSSKeyframeRule (note frame not frames). The KeyframeRule object has the following properties:
cssobject with the CSS for this keyframe, e.g.{background: 'red', 'font-size': '2em'}keyTextthe text name for this frame, e.g.10%originalgives access to the nativeWebKitCSSKeyframeRuleorMozCSSKeyframeRuleobject this object wraps
Examples of use
Getting the CSS for each frame in an animation
var spin = CSSAnimations.spin;
for(var i=0; i<spin.keyframes.length; i++)
console.log(spin.keyframes[i].css);
Adding/modifying a keyframe in an animation
var spin = CSSAnimations.spin;
spin.setKeyframe('10%', {background: 'red', 'font-size': '2em'});
Feedback
Let me know what you think in the comments or on GitHub, I’m also open to suggestions for modifications or additions!
Accessing/creating CSS Animations with native Javascript
Here’s a quick overview for those not wishing to use the CSS Animation Store, or those that want to know how it works under the hood.
Accessing CSS Animations
Accessing keyframe animations is done using the CSSOM. Here’s the function from my CSSA script that I use to access a given CSS Animation:
CSSAnimation.find = function(a) {
var ss = document.styleSheets;
for (var i = ss.length - 1; i >= 0; i--) {
try {
var s = ss[i],
rs = s.cssRules ? s.cssRules :
s.rules ? s.rules :
[];
for (var j = rs.length - 1; j >= 0; j--) {
if ((rs[j].type === window.CSSRule.WEBKIT_KEYFRAMES_RULE || rs[j].type === window.CSSRule.MOZ_KEYFRAMES_RULE) && rs[j].name == a){
return rs[j];
}
}
}
catch(e) { /* Trying to interrogate a stylesheet from another domain will throw a security error */ }
}
return null;
};
You can then use this in code like this:
var animation = CSSAnimation.find("spin"); // Get the animation named 'spin'
The returned object will either be of type WebKitCSSKeyframesRule or MozCSSKeyframesRule depending on the browser you’re using.
Creating CSS Animations
The only way I’ve found to create animations on the fly is a little hacky. It involves crafting the CSS string in code and either inserting it into the CSSOM or appending a style tag to the current HTML document.
Here’s how I do this in my library Morf.js:
// Adds the CSS to the current page
addKeyframeRule = function(rule) {
if (document.styleSheets && document.styleSheets.length)
// Insert the style into the first attached stylesheet
document.styleSheets[0].insertRule(rule, 0);
else
{
// No attached stylesheets so append to the DOM
var style = document.createElement('style');
style.innerHTML = rule;
document.head.appendChild(style);
}
}
Once you’ve crafted your CSS animation string you can then call the above function like this:
var css = '@-webkit-keyframes spin { ... }';
addKeyframeRule(css);

Pingback: yCoder » 通过JavaScript访问和修改CSS3动画