作者PsMonkey (痞子军团团长)
看板java
标题[GWT] Animation 再探
时间Thu Oct 8 09:11:58 2009
在〈GWT Animation 初探〉当中,程式已经能让画面看起来有动画的效果,
「表面上」要怎麽使用 Animation 是没有问题了;
不过这样子有些无趣,还是要杀进去 Animation 来了解这一切背後的内幕(?)。
起点当然是 Animation.run(),没有呼叫这个 method,是不会有什麽反应的。
run() 有两个,run(int duration, double startTime) 的
duration 是 Animation 预计持续作用的时间;
startTime 是预计执行的时间。
为甚麽用 startTime 的 data type 是 double 呢?
这点在 Animation 不算是有用到的 Duration.elapsedMillis() 可以找到答案:
Returns the same result as System
#currentTimeMillis(),
but as a double. Because emulated long math is significantly
slower than doubles in web mode, this method is to be preferred.
因为在浏览器上头,使用 double 处理起来比模拟 long 还要快得多
(btw... 为甚麽 Animation 只用了 Duration.currentTimeMillis() 取得时间,
而没有用 Duration.elapsedMillis() 去计算时间差,这我一直想不透 XD)。
另一个 run(int duration) 其实还是呼叫 run(int, double),
只是自动以当下时间传给 startTime。
回到 run(int, double) 的内容,关键点在於下面这段
if (animations == null) {
animations = new ArrayList(); //point-A
animationTimer = new Timer() {
@Override
public void run() {
updateAnimations();
}
};
}
animations.add(this);
这边要回头看一下 Animation 的资料结构。
讲起来有点饶舌。大致上来说,Animation 有一些 static 的 field 跟 method,
目的是统一处理系统当中所有的 Animation object(程式码 point-A)。
这里也可以看到,其实 Animation 里头是用 Timer 来实做的。
Timer 的细节得先跳过,这里只要知道看到
animationTime.schedule(int delayMillis) 就表示隔了 delayMillis 个 ms
就会执行 updateAnimations() 的内容,
而 updateAnimations() 会呼叫 update()。
那麽,势必有需要好好看一下 update() 的内容:
private boolean update(double curTime) {
boolean finished = curTime >= startTime + duration;
if (started && !finished) {
// Animation is in progress.
double progress = (curTime - startTime) / duration;
onUpdate(interpolate(progress));
return false;
}
if (!started && curTime >= startTime) {
// Start the animation.
started = true;
onStart();
// Intentional fall through to possibly end the animation.
}
if (finished) {
// Animation is complete.
onComplete();
started = false;
running = false;
return true;
}
return false;
}
里头依照不同的状况,呼叫了 onUpdate(), onStart() 跟 onComplete()。
嗯?为甚麽只有 onUpdate() 是 abstract 的呢?
因为另外两个到最後还是去呼叫 onUpdate(),
progress 的值给 0 表示刚开始、给 1 表示结束。
接下来就是最诡异的部份啦,传给 onUpdate() 的数值,
居然还要经过 interpolate() 的计算,这又是为甚麽呢?
根据 javadoc 的说法:
Interpolate the linear progress into a more natural easing function.
看个对照图可能比较好懂:
http://rubyurl.com/iVP9
在开始跟结束的部份比较缓和,或许这样比较符合人类视觉观点?
总之,这是为甚麽 Animation 的 javadoc 会说「at a non-fixed frame rate」了。
(顺带提一点,相同的 duration,呼叫 onUpdate() 的次数应该会一样,
但是 progress 值会有差异。这应该是 Timer 先天上无法很精准的缺陷?)
看到这边,Animation 应该可以说没有秘密了。
剩下来就是如何运用的问题了...... [远目]
====
资料来源:
http://pt2club.blogspot.com/2009/10/gwt-animation_07.html
--
侃侃长论鲜窒碍 首页:
http://www.psmonkey.idv.tw
众目睽睽无心颤 Blog:
http://ps-think.blogspot.com
茕居少聊常人事
杀头容易告白难 欢迎参观 Java 版(@ptt.cc) \囧/
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 118.231.90.248