由浅入深-javascript动画原理解析(一)

我很早写了一个javascript动画类,我觉得思路还不错,而且执行效率还不错,下面我将由浅入深的分享其实现。

核心

动画核心原理其实并不复杂,就这么几行代码:

var fx = function (ontween, onend, duration) {
var pos, runTime,
startTime = + new Date,
timer = setInterval(function () {
runTime = + new Date - startTime;
pos = runTime / duration;

if (pos >= 1) {
clearInterval(timer);
onend(pos);
} else {
ontween(pos);
};
}, 13);
};

它把动画时长(duration)分为N份,定期运行回调函数,接下来我们也可以用它来操作元素的CSS值。

演示代码:

<div id="fx" style="width:150px;height:150px;background:#36C;"></div>

<script>
// DEMO
document.getElementById('fx').onclick = function () {
var from = 150; // 开始值
var to = 500; // 目标值
var elemStyle = this.style;
function ontween (pos) {
elemStyle.height = from + (to - from) * pos + 'px';
};
function onend (pos) {
ontween(pos);
};
fx(ontween, onend, 400);
};
</script>

结合上述代码实现了一个简单的高度递增动画,是不是很简单?可以看到fx函数只是用来控制动画进度的抽象层,它与DOM毫无关系。

包装器

上述代码只能实现单个样式动画,对于多个样式动画可以写一个函数包装fx引擎,并且支持完成后的回调函数与动画时长:

var animate = function (elem, css, duration, callback) {
function ontween (pos) {
var obj, val, form, to, name, unit,
i = 0, len = css.length;

for (; i < len; i++) {
obj = css[i];
from = obj[0];
to = obj[1];
name = obj[2];
unit = obj[3];

val = from + (to - from) * pos;
elem.style[name] = val + unit;
};
};

function onend (pos) {
ontween(pos);
callback.call(elem);
};

fx(ontween, onend, duration);
};

演示代码:

<div id="fx" style="width:150px;height:150px;position:absolute;top:20px;left:20px;
background:#36C;color:#FFF;text-align:center; line-height:150px;font-size:12px">FX</div>

<script>
// DEMO
document.getElementById('fx').onclick = function () {
animate(this, [
[150, 500, 'width', 'px'],
[150, 300, 'height', 'px'],
[150, 300, 'lineHeight', 'px'],
[20, 60, 'top', 'px'],
[20, 350, 'left', 'px'],
[12, 36, 'fontSize', 'px']
], 400, function () {
this.innerHTML = 'FX {BY TANGBIN}';
});
};
</script>

fx函数好比一个汽车的引擎,而animate函数则是驾驶室,我们尽可能的让引擎更强大(进度控制。注重性能、扩展性),让驾驶室更舒适(DOM表现层。注重接口优雅)。

原文地址:http://www.planeart.cn


posted @ 2011-11-28 16:37  深蓝色梦想  阅读(1156)  评论(0编辑  收藏