Javascript degradation solutions for CSS3 animations
I've been creating a number of small thick client JavaScript apps for an iPad app, which loads the relevant app in a UIWebview. I am now making them cross browser and need to incorporate some fallback开发者_高级运维s for CSS animations and transitions using JavaScript.
My webkit specific implementation uses CSS classes for all animations/transitions, for which the start and end states are known at design time, using add/remove class in javascript and utilising the relevant webkitTransitionEnd/webkitAnimationEnd events.
For 'dynamic' transitions I have a simple 'animate' function which just applies styling properties to relevant elements.
I would like to keep the internal API for appling transitions as similar as possible to the current implementation by simple adding/removing classes etc. I generally have a CSS and js file (both minified) for an app.
So a few questions/points that I would appreciate any input on:
IE7/8 issues - IE9.js
Dynamically adding vendor specific prefixes - so far found 'jquery.css3finalize'.
Transitioning to a class: 'jquery.animateToClass' - seems to search stylesheet(s) every time a class is applied - should relevant classes be cached on further lookups? Is this slow/resource hungry?
For '@keyframe' animations: I'd like to have a javascript object 'representation' of keyframes of each CSS3 animation. Therefore passing a class to the 'doAnimationWithClass' function would use normal css3 animation if available in the browser but if not it would pass the 'object version' to a function that would chain the each key frame transition using css3 transitions (if available) or jQuery.animate (or equivalent), ultimately arriving at the same result.
So for instance:
CSS:
@-webkit-keyframes an-animation {
0% { opacity: 0; }
50% { opacity: 1; }
100% { opacity: 0; }
}
.an-animation {
-webkit-animation-name: an-animation;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: 2;
}
JS:
var animations = {
an-animation: {
keyframes: [
{
duration: '',
timing: 'linear',
props: {
opacity: 0
}
},
{
duration: '0.5s',
timing: 'linear',
props: {
opacity: 1
}
},
{
duration: '0.5s',
timing: 'linear',
props: {
opacity: 0
}
}
]
}
};
var animationClasses = [
an-animation: {
name: 'an-animation';
duration: '1s';
timing: 'linear';
count: 2;
}
];
function doAnimationWithClass(className) {
if (modernizer.cssanimations) {
//normal implementation
}
else {
//lookup class in animationclasses
//lookup relevant animation object in animationHash
//pass to animation chaining function
}
}
The creation of animationHash etc could be done client side, or simply created at design time (with a batch/build file).
Any thoughts or pointers to a library that already does this in a more sensible way would be appreciated.
Yes, that's right. You need to transfer keyframes setting to js object. I think css animation and keyframe is a better way to write animation. JS animation way is hardly to maintain. Here is my workaround solution. And I also write a small tool for translating css keyframes to js object(css keyframes to js object) .
var myFrame = {
'0%': {
left: 0,
top: 0
},
'25%': {
left: 100,
top: 100
},
'50%': {
left: 0,
top: 300
},
'100%': {
left: 0,
top: 0
}
};
var keyframes = {
set: function($el, frames, duration) {
var animate;
animate = function() {
var spendTime;
spendTime = 0;
$.each(frames, function(idx, val) {
var stepDuration, stepPercentage;
stepPercentage = idx.replace('%', '') / 100;
stepDuration = duration * stepPercentage - spendTime;
$el.animate(val, stepDuration);
return spendTime += stepDuration;
});
return setTimeout(animate, duration);
};
return animate();
}
};
keyframes.set($('#mydiv'), myFrame, 2000);
- demo: http://jsbin.com/uzodut/4/watch
Here are some important pointers http://addyosmani.com/blog/css3transitions-jquery/
Blackbingo, you answer served to me perfectly. I added the easing option, to implement a jquery fallback for ie8 in a parallax starfield (see CSS parallax background of stars) like this:
var animations = {
'STAR-MOVE': {
'0%': {
'background-position-x': '5%',
'background-position-y': '5%'
},
'100%': {
'background-position-x': '1300%',
'background-position-y': '600%'
}
}
};
var keyframes = {
set: function($el, frames, duration, easing) {
var animate;
animate = function() {
var spendTime;
spendTime = 0;
$.each(frames, function(idx, val) {
var stepDuration, stepPercentage;
stepPercentage = idx.replace('%', '') / 100;
stepDuration = duration * stepPercentage - spendTime;
$el.animate(val, stepDuration, easing);
return spendTime += stepDuration;
});
return setTimeout(animate, duration);
};
return animate();
}
};
keyframes.set($('.midground'), animations['STAR-MOVE'], 150000,'linear');
keyframes.set($('.foreground'), animations['STAR-MOVE'], 100000,'linear');
精彩评论