зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central into cedar
This commit is contained in:
Коммит
ce22cb5ea2
|
@ -6214,6 +6214,14 @@ MOZ_ARG_DISABLE_BOOL(universalchardet,
|
|||
MOZ_UNIVERSALCHARDET=,
|
||||
MOZ_UNIVERSALCHARDET=1 )
|
||||
|
||||
if test -n "${JAVA_BIN_PATH}"; then
|
||||
dnl Look for javac and jar in the specified path.
|
||||
JAVA_PATH="$JAVA_BIN_PATH"
|
||||
else
|
||||
dnl No path specified, so look for javac and jar in $JAVA_HOME & $PATH.
|
||||
JAVA_PATH="$JAVA_HOME/bin:$PATH"
|
||||
fi
|
||||
|
||||
MOZ_PATH_PROG(JAVA, java, :, [$JAVA_PATH])
|
||||
MOZ_PATH_PROG(JAVAC, javac, :, [$JAVA_PATH])
|
||||
MOZ_PATH_PROG(JAR, jar, :, [$JAVA_PATH])
|
||||
|
|
|
@ -762,12 +762,6 @@ public:
|
|||
*/
|
||||
virtual ThebesLayer* AsThebesLayer() { return nsnull; }
|
||||
|
||||
/**
|
||||
* Dynamic cast to a ContainerLayer. Returns null if this is not
|
||||
* a ContainerLayer.
|
||||
*/
|
||||
virtual ContainerLayer* AsContainerLayer() { return nsnull; }
|
||||
|
||||
/**
|
||||
* Dynamic cast to a ShadowLayer. Return null if this is not a
|
||||
* ShadowLayer. Can be used anytime.
|
||||
|
@ -1035,8 +1029,6 @@ public:
|
|||
|
||||
// These getters can be used anytime.
|
||||
|
||||
virtual ContainerLayer* AsContainerLayer() { return this; }
|
||||
|
||||
virtual Layer* GetFirstChild() { return mFirstChild; }
|
||||
virtual Layer* GetLastChild() { return mLastChild; }
|
||||
const FrameMetrics& GetFrameMetrics() { return mFrameMetrics; }
|
||||
|
|
|
@ -59,9 +59,7 @@ enum LayerState {
|
|||
LAYER_ACTIVE,
|
||||
// Force an active layer even if it causes incorrect rendering, e.g.
|
||||
// when the layer has rounded rect clips.
|
||||
LAYER_ACTIVE_FORCE,
|
||||
// Special layer that is metadata only.
|
||||
LAYER_ACTIVE_EMPTY
|
||||
LAYER_ACTIVE_FORCE
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,7 +84,6 @@ enum Type {
|
|||
TYPE_REMOTE,
|
||||
TYPE_REMOTE_SHADOW,
|
||||
TYPE_SCROLL_LAYER,
|
||||
TYPE_SCROLL_INFO_LAYER,
|
||||
TYPE_SELECTION_OVERLAY,
|
||||
TYPE_SOLID_COLOR,
|
||||
TYPE_TABLE_CELL_BACKGROUND,
|
||||
|
|
|
@ -1836,25 +1836,6 @@ nsDisplayScrollLayer::~nsDisplayScrollLayer()
|
|||
}
|
||||
#endif
|
||||
|
||||
nsDisplayScrollInfoLayer::nsDisplayScrollInfoLayer(
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList,
|
||||
nsIFrame* aForFrame,
|
||||
nsIFrame* aViewportFrame)
|
||||
: nsDisplayScrollLayer(aBuilder, aList, aForFrame, aViewportFrame)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
MOZ_COUNT_CTOR(nsDisplayScrollInfoLayer);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
nsDisplayScrollInfoLayer::~nsDisplayScrollInfoLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsDisplayScrollInfoLayer);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, nsDisplayItem* aItem,
|
||||
const nsRect& aRect)
|
||||
|
|
|
@ -1836,30 +1836,6 @@ private:
|
|||
nsIFrame* mViewportFrame;
|
||||
};
|
||||
|
||||
/**
|
||||
* Like nsDisplayScrollLayer, but only has metadata on the scroll frame. This
|
||||
* creates a layer that has no Thebes child layer, but still allows the
|
||||
* compositor process to know of the scroll frame's existence.
|
||||
*/
|
||||
class nsDisplayScrollInfoLayer : public nsDisplayScrollLayer
|
||||
{
|
||||
public:
|
||||
nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
|
||||
nsIFrame* aForFrame, nsIFrame* aViewportFrame);
|
||||
NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER)
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayScrollInfoLayer();
|
||||
#endif
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
{
|
||||
return mozilla::LAYER_ACTIVE_EMPTY;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* nsDisplayClip can clip a list of items, but we take a single item
|
||||
* initially and then later merge other items into it when we merge
|
||||
|
|
|
@ -1961,8 +1961,7 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
dirtyRect.IntersectRect(aDirtyRect, mScrollPort);
|
||||
|
||||
// Override the dirty rectangle if the displayport has been set.
|
||||
PRBool usingDisplayport =
|
||||
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &dirtyRect);
|
||||
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &dirtyRect);
|
||||
|
||||
nsDisplayListCollection set;
|
||||
|
||||
|
@ -1977,42 +1976,30 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
// range of 20 pixels to eliminate many gfx scroll frames from becoming a
|
||||
// layer.
|
||||
//
|
||||
PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||
nsRect scrollRange = GetScrollRange();
|
||||
ScrollbarStyles styles = GetScrollbarStylesFromFrame();
|
||||
mShouldBuildLayer =
|
||||
(XRE_GetProcessType() == GeckoProcessType_Content &&
|
||||
(styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN ||
|
||||
styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN) &&
|
||||
(!mIsRoot || !mOuter->PresContext()->IsRootContentDocument()));
|
||||
(scrollRange.width >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel) ||
|
||||
scrollRange.height >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel))) &&
|
||||
(!mIsRoot || !mOuter->PresContext()->IsRootContentDocument());
|
||||
|
||||
if (ShouldBuildLayer()) {
|
||||
// Note that using StackingContext breaks z order, so the resulting
|
||||
// rendering can be incorrect for weird edge cases!
|
||||
|
||||
nsDisplayList list;
|
||||
if (usingDisplayport) {
|
||||
// Once a displayport is set, assume that scrolling needs to be fast
|
||||
// so create a layer with all the content inside. The compositor
|
||||
// process will be able to scroll the content asynchronously.
|
||||
//
|
||||
// Note that using StackingContext breaks z order, so the resulting
|
||||
// rendering can be incorrect for weird edge cases!
|
||||
rv = mScrolledFrame->BuildDisplayListForStackingContext(
|
||||
aBuilder, dirtyRect + mOuter->GetOffsetTo(mScrolledFrame), &list);
|
||||
|
||||
rv = mScrolledFrame->BuildDisplayListForStackingContext(
|
||||
aBuilder, dirtyRect + mOuter->GetOffsetTo(mScrolledFrame), &list);
|
||||
|
||||
nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollLayer(
|
||||
aBuilder, &list, mScrolledFrame, mOuter);
|
||||
set.Content()->AppendNewToTop(layerItem);
|
||||
} else {
|
||||
// If there is no displayport set, there is no reason here to force a
|
||||
// layer that needs a memory-expensive allocation, but the compositor
|
||||
// process would still like to know that it exists.
|
||||
|
||||
nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollInfoLayer(
|
||||
aBuilder, &list, mScrolledFrame, mOuter);
|
||||
set.Content()->AppendNewToTop(layerItem);
|
||||
|
||||
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set);
|
||||
}
|
||||
} else {
|
||||
nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollLayer(
|
||||
aBuilder, &list, mScrolledFrame, mOuter);
|
||||
set.Content()->AppendNewToTop(layerItem);
|
||||
} else
|
||||
{
|
||||
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set);
|
||||
}
|
||||
|
||||
|
|
|
@ -139,8 +139,13 @@ FindViewForId(const ViewMap& aMap, ViewID aId)
|
|||
static const FrameMetrics*
|
||||
GetFrameMetrics(Layer* aLayer)
|
||||
{
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
return container ? &container->GetFrameMetrics() : NULL;
|
||||
// Children are not container layers, so they don't have frame metrics. Give
|
||||
// them a blank metric.
|
||||
if (!aLayer->GetFirstChild())
|
||||
return NULL;
|
||||
|
||||
ContainerLayer* container = static_cast<ContainerLayer*>(aLayer);
|
||||
return &container->GetFrameMetrics();
|
||||
}
|
||||
|
||||
static nsIntPoint
|
||||
|
@ -341,9 +346,10 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
|
|||
nsFrameLoader* aFrameLoader, Layer* aLayer,
|
||||
float aXScale = 1, float aYScale = 1)
|
||||
{
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
if (!container)
|
||||
if (!aLayer->GetFirstChild())
|
||||
return;
|
||||
|
||||
ContainerLayer* container = static_cast<ContainerLayer*>(aLayer);
|
||||
const FrameMetrics metrics = container->GetFrameMetrics();
|
||||
const ViewID scrollId = metrics.mScrollId;
|
||||
|
||||
|
|
|
@ -395,9 +395,9 @@ pref("dom.max_script_run_time", 20);
|
|||
pref("devtools.errorconsole.enabled", false);
|
||||
|
||||
// kinetic tweakables
|
||||
pref("browser.ui.kinetic.updateInterval", 16);
|
||||
pref("browser.ui.kinetic.exponentialC", 1400);
|
||||
pref("browser.ui.kinetic.polynomialC", 100);
|
||||
pref("browser.ui.kinetic.updateInterval", 30);
|
||||
pref("browser.ui.kinetic.decelerationRate", 20);
|
||||
pref("browser.ui.kinetic.speedSensitivity", 80);
|
||||
pref("browser.ui.kinetic.swipeLength", 160);
|
||||
|
||||
// zooming
|
||||
|
|
|
@ -60,13 +60,6 @@ const kAxisLockRevertThreshold = 0.8;
|
|||
// Same as NS_EVENT_STATE_ACTIVE from nsIEventStateManager.h
|
||||
const kStateActive = 0x00000001;
|
||||
|
||||
// After a drag begins, kinetic panning is stopped if the drag doesn't become
|
||||
// a pan in 300 milliseconds.
|
||||
const kStopKineticPanOnDragTimeout = 300;
|
||||
|
||||
// Max velocity of a pan. This is in pixels/millisecond.
|
||||
const kMaxVelocity = 6;
|
||||
|
||||
/**
|
||||
* MouseModule
|
||||
*
|
||||
|
@ -212,21 +205,19 @@ MouseModule.prototype = {
|
|||
this._targetScrollInterface = targetScrollInterface;
|
||||
|
||||
// Do tap
|
||||
if (!this._kinetic.isActive()) {
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("TapDown", true, true);
|
||||
event.clientX = aEvent.clientX;
|
||||
event.clientY = aEvent.clientY;
|
||||
let success = aEvent.target.dispatchEvent(event);
|
||||
if (success) {
|
||||
this._recordEvent(aEvent);
|
||||
this._target = aEvent.target;
|
||||
this._mouseOverTimeout.once(kOverTapWait);
|
||||
this._longClickTimeout.once(kLongTapWait);
|
||||
} else {
|
||||
// cancel all pending content clicks
|
||||
this._cleanClickBuffer();
|
||||
}
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("TapDown", true, true);
|
||||
event.clientX = aEvent.clientX;
|
||||
event.clientY = aEvent.clientY;
|
||||
let success = aEvent.target.dispatchEvent(event);
|
||||
if (success) {
|
||||
this._recordEvent(aEvent);
|
||||
this._target = aEvent.target;
|
||||
this._mouseOverTimeout.once(kOverTapWait);
|
||||
this._longClickTimeout.once(kLongTapWait);
|
||||
} else {
|
||||
// cancel all pending content clicks
|
||||
this._cleanClickBuffer();
|
||||
}
|
||||
|
||||
// Do pan
|
||||
|
@ -337,8 +328,11 @@ MouseModule.prototype = {
|
|||
if (dragData.isPan()) {
|
||||
// Only pan when mouse event isn't part of a click. Prevent jittering on tap.
|
||||
this._kinetic.addData(sX - dragData.prevPanX, sY - dragData.prevPanY);
|
||||
this._dragBy(this.dX, this.dY);
|
||||
// dragBy will reset dX and dY values to 0.
|
||||
if (!this._waitingForPaint) {
|
||||
this._dragBy(this.dX, this.dY);
|
||||
this.dX = 0;
|
||||
this.dY = 0;
|
||||
}
|
||||
|
||||
// Let everyone know when mousemove begins a pan
|
||||
if (!oldIsPan && dragData.isPan()) {
|
||||
|
@ -367,7 +361,6 @@ MouseModule.prototype = {
|
|||
let dragData = this._dragData;
|
||||
dragData.setDragStart(aEvent.screenX, aEvent.screenY, aDraggable);
|
||||
this._kinetic.addData(0, 0);
|
||||
this._dragStartTime = Date.now();
|
||||
if (!this._kinetic.isActive())
|
||||
this._dragger.dragStart(aEvent.clientX, aEvent.clientY, aEvent.target, this._targetScrollInterface);
|
||||
},
|
||||
|
@ -384,15 +377,13 @@ MouseModule.prototype = {
|
|||
// mousedown/mouseup event previous to this one. In this case, we
|
||||
// want the kinetic panner to tell our drag interface to stop.
|
||||
|
||||
if (dragData.isPan()) {
|
||||
if (Date.now() - this._dragStartTime > kStopKineticPanOnDragTimeout)
|
||||
this._kinetic._velocity.set(0, 0);
|
||||
// Start kinetic pan.
|
||||
this._kinetic.start();
|
||||
} else {
|
||||
this._kinetic.end();
|
||||
if (!dragData.isPan() && !this._kinetic.isActive()) {
|
||||
// There was no pan and no kinetic scrolling, so just stop dragger.
|
||||
this._dragger.dragStop(0, 0, this._targetScrollInterface);
|
||||
this._dragger = null;
|
||||
} else if (dragData.isPan()) {
|
||||
// Start kinetic pan.
|
||||
this._kinetic.start();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -403,21 +394,12 @@ MouseModule.prototype = {
|
|||
* the dragger of dragMove()s.
|
||||
*/
|
||||
_dragBy: function _dragBy(dX, dY, aIsKinetic) {
|
||||
let dragged = true;
|
||||
let dragData = this._dragData;
|
||||
if (!this._waitingForPaint || aIsKinetic) {
|
||||
let dragData = this._dragData;
|
||||
dragged = this._dragger.dragMove(dX, dY, this._targetScrollInterface, aIsKinetic);
|
||||
if (dragged && !this._waitingForPaint) {
|
||||
this._waitingForPaint = true;
|
||||
mozRequestAnimationFrame(this);
|
||||
}
|
||||
this.dX = 0;
|
||||
this.dY = 0;
|
||||
let dragged = this._dragger.dragMove(dX, dY, this._targetScrollInterface, aIsKinetic);
|
||||
if (dragged && !this._waitingForPaint) {
|
||||
this._waitingForPaint = true;
|
||||
mozRequestAnimationFrame(this);
|
||||
}
|
||||
if (!dragData.isPan())
|
||||
this._kinetic.pause();
|
||||
|
||||
return dragged;
|
||||
},
|
||||
|
||||
|
@ -834,9 +816,10 @@ function KineticController(aPanBy, aEndCallback) {
|
|||
// How often do we change the position of the scroll pane? Too often and panning may jerk near
|
||||
// the end. Too little and panning will be choppy. In milliseconds.
|
||||
this._updateInterval = Services.prefs.getIntPref("browser.ui.kinetic.updateInterval");
|
||||
// Constants that affect the "friction" of the scroll pane.
|
||||
this._exponentialC = Services.prefs.getIntPref("browser.ui.kinetic.exponentialC");
|
||||
this._polynomialC = Services.prefs.getIntPref("browser.ui.kinetic.polynomialC") / 1000000;
|
||||
// "Friction" of the scroll pane. The lower, the less friction and the further distance traveled.
|
||||
this._decelerationRate = Services.prefs.getIntPref("browser.ui.kinetic.decelerationRate") / 10000;
|
||||
// A multiplier for the initial velocity of the movement.
|
||||
this._speedSensitivity = Services.prefs.getIntPref("browser.ui.kinetic.speedSensitivity") / 100;
|
||||
// Number of milliseconds that can contain a swipe. Movements earlier than this are disregarded.
|
||||
this._swipeLength = Services.prefs.getIntPref("browser.ui.kinetic.swipeLength");
|
||||
|
||||
|
@ -846,7 +829,6 @@ function KineticController(aPanBy, aEndCallback) {
|
|||
KineticController.prototype = {
|
||||
_reset: function _reset() {
|
||||
this._active = false;
|
||||
this._paused = false;
|
||||
this.momentumBuffer = [];
|
||||
this._velocity.set(0, 0);
|
||||
},
|
||||
|
@ -856,84 +838,82 @@ KineticController.prototype = {
|
|||
},
|
||||
|
||||
_startTimer: function _startTimer() {
|
||||
let self = this;
|
||||
// Use closed form of a parabola to calculate each position for panning.
|
||||
// x(t) = v0*t + .5*t^2*a
|
||||
// where: v0 is initial velocity
|
||||
// a is acceleration
|
||||
// t is time elapsed
|
||||
//
|
||||
// x(t)
|
||||
// ^
|
||||
// | |
|
||||
// |
|
||||
// | |
|
||||
// | ....^^^^....
|
||||
// | ...^^ | ^^...
|
||||
// | ...^ ^...
|
||||
// |.. | ..
|
||||
// -----------------------------------> t
|
||||
// t0 tf=-v0/a
|
||||
//
|
||||
// Using this formula, distance moved is independent of the time between each frame, unlike time
|
||||
// step approaches. Once the time is up, set the position to x(tf) and stop the timer.
|
||||
|
||||
let lastp = this._position; // track last position vector because pan takes deltas
|
||||
let lastx = this._position; // track last position vector because pan takes differences
|
||||
let v0 = this._velocity; // initial velocity
|
||||
let a = this._acceleration; // acceleration
|
||||
let c = this._exponentialC;
|
||||
let p = new Point(0, 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;
|
||||
}
|
||||
|
||||
this._calcV = function(v0, a, t) {
|
||||
return v0 * Math.exp(-t / c) + 2 * a * t;
|
||||
}
|
||||
// Temporary "bins" so that we don't create new objects during pan.
|
||||
let aBin = new Point(0, 0);
|
||||
let v0Bin = new Point(0, 0);
|
||||
let self = this;
|
||||
|
||||
let callback = {
|
||||
onBeforePaint: function kineticHandleEvent(timeStamp) {
|
||||
// Someone called end() on us between timer intervals
|
||||
// or we are paused.
|
||||
if (!self.isActive() || self._paused)
|
||||
if (!self.isActive()) // someone called end() on us between timer intervals
|
||||
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;
|
||||
let realt = timeStamp - self._initialTime;
|
||||
self._time += self._updateInterval;
|
||||
t = (self._time + realt) / 2;
|
||||
let 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);
|
||||
// Calculate new position using x(t) formula.
|
||||
let x = v0Bin.set(v0).scale(t).add(aBin.set(a).scale(0.5 * t * t));
|
||||
let dx = x.x - lastx.x;
|
||||
let dy = x.y - lastx.y;
|
||||
lastx.set(x);
|
||||
|
||||
// Test to see if movement is finished for each component.
|
||||
if (dx * a.x > 0) {
|
||||
dx = 0;
|
||||
lastp.x = 0;
|
||||
// Test to see if movement is finished for each component. As seen in graph, we want the
|
||||
// final position to be at tf.
|
||||
if (t >= -v0.x / a.x) {
|
||||
// Plug in t=-v0/a into x(t) to get final position.
|
||||
dx = -v0.x * v0.x / 2 / a.x - lastx.x;
|
||||
// Reset components. Next frame: a's component will be 0 and t >= NaN will be false.
|
||||
lastx.x = 0;
|
||||
v0.x = 0;
|
||||
a.x = 0;
|
||||
}
|
||||
// Symmetric to above case.
|
||||
if (dy * a.y > 0) {
|
||||
dy = 0;
|
||||
lastp.y = 0;
|
||||
if (t >= -v0.y / a.y) {
|
||||
dy = -v0.y * v0.y / 2 / a.y - lastx.y;
|
||||
lastx.y = 0;
|
||||
v0.y = 0;
|
||||
a.y = 0;
|
||||
}
|
||||
|
||||
if (v0.x == 0 && v0.y == 0) {
|
||||
let panned = false;
|
||||
try { panned = self._panBy(Math.round(-dx), Math.round(-dy), true); } catch (e) {}
|
||||
if (!panned)
|
||||
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);
|
||||
}
|
||||
else
|
||||
mozRequestAnimationFrame(this);
|
||||
}
|
||||
};
|
||||
|
||||
this._active = true;
|
||||
this._paused = false;
|
||||
mozRequestAnimationFrame(callback);
|
||||
},
|
||||
|
||||
|
@ -942,12 +922,6 @@ KineticController.prototype = {
|
|||
return x ? ((x > 0) ? 1 : -1) : 0;
|
||||
}
|
||||
|
||||
function clampFromZero(x, closerToZero, furtherFromZero) {
|
||||
if (x >= 0)
|
||||
return Math.max(closerToZero, Math.min(furtherFromZero, x));
|
||||
return Math.min(-closerToZero, Math.max(-furtherFromZero, x));
|
||||
}
|
||||
|
||||
let mb = this.momentumBuffer;
|
||||
let mblen = this.momentumBuffer.length;
|
||||
|
||||
|
@ -966,43 +940,24 @@ KineticController.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
let currentVelocityX = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
if (currentVelocityX * this._velocity.x <= 0)
|
||||
currentVelocityX = 0;
|
||||
if (currentVelocityY * this._velocity.y <= 0)
|
||||
currentVelocityY = 0;
|
||||
|
||||
let swipeTime = Math.min(swipeLength, lastTime - mb[0].t);
|
||||
this._velocity.x = clampFromZero((distanceX / swipeTime) + currentVelocityX, Math.abs(currentVelocityX), 6);
|
||||
this._velocity.y = clampFromZero((distanceY / swipeTime) + currentVelocityY, Math.abs(currentVelocityY), 6);
|
||||
// Only allow kinetic scrolling to speed up if kinetic scrolling is active.
|
||||
this._velocity.x = (distanceX < 0 ? Math.min : Math.max)((distanceX / swipeLength) * this._speedSensitivity, this._velocity.x);
|
||||
this._velocity.y = (distanceY < 0 ? Math.min : Math.max)((distanceY / swipeLength) * this._speedSensitivity, this._velocity.y);
|
||||
|
||||
// Set acceleration vector to opposite signs of velocity
|
||||
this._acceleration.set(this._velocity.clone().map(sign).scale(-this._polynomialC));
|
||||
this._acceleration.set(this._velocity.clone().map(sign).scale(-this._decelerationRate));
|
||||
|
||||
this._position.set(0, 0);
|
||||
this._initialTime = mozAnimationStartTime;
|
||||
this._time = 0;
|
||||
this.momentumBuffer = [];
|
||||
|
||||
if (!this.isActive() || this._paused)
|
||||
if (!this.isActive())
|
||||
this._startTimer();
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
pause: function pause() {
|
||||
this._paused = true;
|
||||
},
|
||||
|
||||
end: function end() {
|
||||
if (this.isActive()) {
|
||||
if (this._beforeEnd)
|
||||
|
|
Загрузка…
Ссылка в новой задаче