JavaScript Animate
Sort of an old topic for these times, but I thought I’d share a small snippet I wrote about a year ago for the live updating Twitter widgets which required a tad bit of animation without the use of a library. Of course, anyone doing a large amount of animation will use some JavaScript library or, when available in a browser – CSS transitions.
Ultimately, the goal for the widgets – which would end up on thousands of websites, was to make them as lightweight as possible – so you can’t just go around and make jQuery, YUI, or Prototype a requirement.
Thus, a simple animation class was in order. One that will work in any browser that supports JavaScript – and can animate any CSS property that is enumerable. Eg: height, weight, font-size, top, left… not color, background-image, text-decoration, etc.
大概意思就是使用JavaScript做动画比用JS库和CSS滤镜要好很多,这是一个兼容多数浏览器的实例。
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>JavaScript Animation Example</title>
<script type="text/javascript">
/**
* @constructor Animate
* @param {HTMLElement} el the element we want to animate
* @param {String} prop the CSS property we will be animating
* @param {Object} opts a configuration object
* object properties include
* from {Int}
* to {Int}
* time {Int} time in milliseconds
* callback {Function}
*/
function Animate(el, prop, opts) {
this.el = el;
this.prop = prop;
this.from = opts.from;
this.to = opts.to;
this.time = opts.time;
this.callback = opts.callback;
this.animDiff = this.to - this.from;
}
/**
* @private
* @param {String} val the CSS value we will set on the property
*/
Animate.prototype._setStyle = function(val) {
switch (this.prop) {
case 'opacity':
this.el.style[this.prop] = val;
this.el.style.filter = 'alpha(opacity=' + val * 100 + ')';
break;
default:
this.el.style[this.prop] = val + 'px';
break;
};
};
/**
* @private
* this is the tweening function
*/
Animate.prototype._animate = function() {
var that = this;
this.now = new Date();
this.diff = this.now - this.startTime;
if (this.diff > this.time) {
this._setStyle(this.to);
if (this.callback) {
this.callback.call(this);
}
clearInterval(this.timer);
return;
}
this.percentage = (Math.floor((this.diff / this.time) * 100) / 100);
this.val = (this.animDiff * this.percentage) + this.from;
this._setStyle(this.val);
};
/**
* @public
* begins the animation
*/
Animate.prototype.start = function() {
var that = this;
this.startTime = new Date();
this.timer = setInterval(function() {
that._animate.call(that);
}, 4);
};
/**
* @static
* @boolean
* allows us to check if native CSS transitions are possible
*/
Animate.canTransition = function() {
var el = document.createElement('twitter');
el.style.cssText = '-webkit-transition: all .5s linear;';
return !!el.style.webkitTransitionProperty;
}();
</script>
<style type="text/css">
a {
color: blue;
}
#doc {
width: 500px;
font: 14px 'helvetica neue', helvetica, arial, sans-serif;
margin: 0 auto;
}
#test {
width: 300px;
height: 300px;
background-color: green;
}
</style>
</head>
<body>
<div id="doc">
<p><a class="animated" href="#" id="click">click to test</a></p>
<div id="test"></div>
</div>
<script type="text/javascript">
(function() {
var blocking = false;
document.getElementById('click').onclick = function(e) {
if (blocking) {
return false;
}
blocking = true;
var that = this;
var el = document.getElementById('test');
var from = this.className == 'animated' ? 1 : 0;
var to = from == 1 ? 0 : 1;
// relevant stuffs
if (Animate.canTransition) {
el.style.webkitTransition = 'opacity 0.5s ease-out';
el.style.opacity = to;
blocking = false;
that.className = that.className == 'animated' ? '' : 'animated';
} else {
new Animate(el, 'opacity', {
from: from,
to: to,
time: 500,
callback: function() {
that.className = that.className == 'animated' ? '' : 'animated';
blocking = false;
}
}).start();
}return false;
};
}());
</script>
</body>
</html>

浙公网安备 33010602011771号