Bug 632072 - Do not create new functions for every kinetic pan [r=mfinkle]

This commit is contained in:
Benjamin Stover 2011-02-07 09:53:27 -08:00
parent 031a8ec104
commit 6018215dc9

View File

@ -859,90 +859,87 @@ KineticController.prototype = {
this._velocity.set(0, 0);
},
isActive: function isActive() {
return this._active;
_startTimer: function _startTimer() {
this._active = true;
mozRequestAnimationFrame(this);
},
_startTimer: function _startTimer() {
let self = this;
_calcP: function _calcP(v0, a, t) {
// Important traits for this function:
// p(t=0) is 0
// p'(t=0) is v0
//
// We use exponential to get a smoother stop, but by itself exponential
// is too smooth at the end. Adding a polynomial with the appropriate
// weight helps to balance
let c = this._exponentialC;
return v0 * Math.exp(-t / c) * -c + a * t * t + v0 * c;
},
_calcV: function _calcV(v0, a, t) {
let c = this._exponentialC;
return v0 * Math.exp(-t / c) + 2 * a * t;
},
onBeforePaint: function onBeforePaint(timeStamp) {
let lastp = this._position; // track last position vector because pan takes deltas
let v0 = this._velocity; // initial velocity
let a = this._acceleration; // acceleration
let c = this._exponentialC;
let p = new Point(0, 0);
let px = 0;
let py = 0;
let dx, dy, t, realt;
function calcP(v0, a, t) {
// Important traits for this function:
// p(t=0) is 0
// p'(t=0) is v0
//
// We use exponential to get a smoother stop, but by itself exponential
// is too smooth at the end. Adding a polynomial with the appropriate
// weight helps to balance
return v0 * Math.exp(-t / c) * -c + a * t * t + v0 * c;
// Someone called end() on us between timer intervals
// or we are paused.
if (!this.isActive() || this._paused)
return;
// To make animation end fast enough but to keep smoothness, average the ideal
// time frame (smooth animation) with the actual time lapse (end fast enough).
// Animation will never take longer than 2 times the ideal length of time.
realt = timeStamp - this._initialTime;
this._time += this._updateInterval;
t = (this._time + realt) / 2;
// Calculate new position.
px = this._calcP(v0.x, a.x, t);
py = this._calcP(v0.y, a.y, t);
dx = Math.round(px - lastp.x);
dy = Math.round(py - lastp.y);
// Test to see if movement is finished for each component.
if (dx * a.x > 0) {
dx = 0;
lastp.x = 0;
v0.x = 0;
a.x = 0;
}
// Symmetric to above case.
if (dy * a.y > 0) {
dy = 0;
lastp.y = 0;
v0.y = 0;
a.y = 0;
}
this._calcV = function(v0, a, t) {
return v0 * Math.exp(-t / c) + 2 * a * t;
}
let callback = {
onBeforePaint: function kineticHandleEvent(timeStamp) {
// Someone called end() on us between timer intervals
// or we are paused.
if (!self.isActive() || self._paused)
return;
// To make animation end fast enough but to keep smoothness, average the ideal
// time frame (smooth animation) with the actual time lapse (end fast enough).
// Animation will never take longer than 2 times the ideal length of time.
realt = timeStamp - self._initialTime;
self._time += self._updateInterval;
t = (self._time + realt) / 2;
// Calculate new position.
p.x = calcP(v0.x, a.x, t);
p.y = calcP(v0.y, a.y, t);
dx = Math.round(p.x - lastp.x);
dy = Math.round(p.y - lastp.y);
// Test to see if movement is finished for each component.
if (dx * a.x > 0) {
dx = 0;
lastp.x = 0;
v0.x = 0;
a.x = 0;
}
// Symmetric to above case.
if (dy * a.y > 0) {
dy = 0;
lastp.y = 0;
v0.y = 0;
a.y = 0;
}
if (v0.x == 0 && v0.y == 0) {
self.end();
} else {
let panStop = false;
if (dx != 0 || dy != 0) {
try { panStop = !self._panBy(-dx, -dy, true); } catch (e) {}
lastp.add(dx, dy);
}
if (panStop)
self.end();
else
mozRequestAnimationFrame(this);
}
if (v0.x == 0 && v0.y == 0) {
this.end();
} else {
let panStop = false;
if (dx != 0 || dy != 0) {
try { panStop = !this._panBy(-dx, -dy, true); } catch (e) {}
lastp.add(dx, dy);
}
};
this._active = true;
this._paused = false;
mozRequestAnimationFrame(callback);
if (panStop)
this.end();
else
mozRequestAnimationFrame(this);
}
},
isActive: function isActive() {
return this._active;
},
start: function start() {
@ -978,7 +975,6 @@ KineticController.prototype = {
let currentVelocityY = 0;
if (this.isActive()) {
// If active, then we expect this._calcV to be defined.
let currentTime = Date.now() - this._initialTime;
currentVelocityX = Util.clamp(this._calcV(this._velocity.x, this._acceleration.x, currentTime), -kMaxVelocity, kMaxVelocity);
currentVelocityY = Util.clamp(this._calcV(this._velocity.y, this._acceleration.y, currentTime), -kMaxVelocity, kMaxVelocity);