Merge pull request #742 from finn-no/scroll-touch-fix
Fixed problems with touch events on a scrollable page
This commit is contained in:
@@ -903,7 +903,7 @@ OpenLayers.Events = OpenLayers.Class({
|
||||
var num = touches.length;
|
||||
var touch;
|
||||
for (var i=0; i<num; ++i) {
|
||||
touch = touches[i];
|
||||
touch = this.getTouchClientXY(touches[i]);
|
||||
x += touch.clientX;
|
||||
y += touch.clientY;
|
||||
}
|
||||
@@ -915,7 +915,48 @@ OpenLayers.Events = OpenLayers.Class({
|
||||
}
|
||||
this.triggerEvent(type, evt);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Method: getTouchClientXY
|
||||
* WebKit has a few bugs for clientX/clientY. This method detects them
|
||||
* and calculate the correct values.
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {Touch} a Touch object from a TouchEvent
|
||||
*
|
||||
* Returns:
|
||||
* {Object} An object with only clientX and clientY properties with the
|
||||
* calculated values.
|
||||
*/
|
||||
getTouchClientXY: function (evt) {
|
||||
// olMochWin is to override window, used for testing
|
||||
var win = window.olMockWin || window,
|
||||
winPageX = win.pageXOffset,
|
||||
winPageY = win.pageYOffset,
|
||||
x = evt.clientX,
|
||||
y = evt.clientY;
|
||||
|
||||
if (evt.pageY === 0 && Math.floor(y) > Math.floor(evt.pageY) ||
|
||||
evt.pageX === 0 && Math.floor(x) > Math.floor(evt.pageX)) {
|
||||
// iOS4 include scroll offset in clientX/Y
|
||||
x = x - winPageX;
|
||||
y = y - winPageY;
|
||||
} else if (y < (evt.pageY - winPageY) || x < (evt.pageX - winPageX) ) {
|
||||
// Some Android browsers have totally bogus values for clientX/Y
|
||||
// when scrolling/zooming a page
|
||||
x = evt.pageX - winPageX;
|
||||
y = evt.pageY - winPageY;
|
||||
}
|
||||
|
||||
evt.olClientX = x;
|
||||
evt.olClientY = y;
|
||||
|
||||
return {
|
||||
clientX: x,
|
||||
clientY: y
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: clearMouseCache
|
||||
* Clear cached data about the mouse position. This should be called any
|
||||
@@ -925,17 +966,7 @@ OpenLayers.Events = OpenLayers.Class({
|
||||
clearMouseCache: function() {
|
||||
this.element.scrolls = null;
|
||||
this.element.lefttop = null;
|
||||
// OpenLayers.Util.pagePosition needs to use
|
||||
// element.getBoundingClientRect to correctly calculate the offsets
|
||||
// for the iPhone, but once the page is scrolled, getBoundingClientRect
|
||||
// returns incorrect offsets. So our best bet is to not invalidate the
|
||||
// offsets once we have them, and hope that the page was not scrolled
|
||||
// when we did the initial calculation.
|
||||
var body = document.body;
|
||||
if (body && !((body.scrollTop != 0 || body.scrollLeft != 0) &&
|
||||
navigator.userAgent.match(/iPhone/i))) {
|
||||
this.element.offsets = null;
|
||||
}
|
||||
this.element.offsets = null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -959,8 +990,8 @@ OpenLayers.Events = OpenLayers.Class({
|
||||
if (!this.element.scrolls) {
|
||||
var viewportElement = OpenLayers.Util.getViewportElement();
|
||||
this.element.scrolls = [
|
||||
viewportElement.scrollLeft,
|
||||
viewportElement.scrollTop
|
||||
window.pageXOffset || viewportElement.scrollLeft,
|
||||
window.pageYOffset || viewportElement.scrollTop
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -495,8 +495,8 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
||||
for (var i=0; i<len; i++) {
|
||||
touch = evt.touches[i];
|
||||
touches[i] = {
|
||||
clientX: touch.clientX,
|
||||
clientY: touch.clientY
|
||||
clientX: touch.olClientX,
|
||||
clientY: touch.olClientY
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,10 @@ OpenLayers.Handler.Pinch = OpenLayers.Class(OpenLayers.Handler, {
|
||||
};
|
||||
this.callback("start", [evt, this.start]);
|
||||
propagate = !this.stopDown;
|
||||
} else if (this.started) {
|
||||
// Some webkit versions send fake single-touch events during
|
||||
// multitouch, which cause the drag handler to trigger
|
||||
return false;
|
||||
} else {
|
||||
this.started = false;
|
||||
this.start = null;
|
||||
@@ -125,6 +129,11 @@ OpenLayers.Handler.Pinch = OpenLayers.Class(OpenLayers.Handler, {
|
||||
this.last = current;
|
||||
// prevent document dragging
|
||||
OpenLayers.Event.stop(evt);
|
||||
return false;
|
||||
} else if (this.started) {
|
||||
// Some webkit versions send fake single-touch events during
|
||||
// multitouch, which cause the drag handler to trigger
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -140,12 +149,13 @@ OpenLayers.Handler.Pinch = OpenLayers.Class(OpenLayers.Handler, {
|
||||
* {Boolean} Let the event propagate.
|
||||
*/
|
||||
touchend: function(evt) {
|
||||
if (this.started) {
|
||||
if (this.started && !OpenLayers.Event.isMultiTouch(evt)) {
|
||||
this.started = false;
|
||||
this.pinching = false;
|
||||
this.callback("done", [evt, this.start, this.last]);
|
||||
this.start = null;
|
||||
this.last = null;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -199,8 +209,8 @@ OpenLayers.Handler.Pinch = OpenLayers.Class(OpenLayers.Handler, {
|
||||
var t0 = touches[0];
|
||||
var t1 = touches[1];
|
||||
return Math.sqrt(
|
||||
Math.pow(t0.clientX - t1.clientX, 2) +
|
||||
Math.pow(t0.clientY - t1.clientY, 2)
|
||||
Math.pow(t0.olClientX - t1.olClientX, 2) +
|
||||
Math.pow(t0.olClientY - t1.olClientY, 2)
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
@@ -1195,9 +1195,9 @@ OpenLayers.Util.pagePosition = function(forElement) {
|
||||
|
||||
if (forElement.getBoundingClientRect) { // IE
|
||||
box = forElement.getBoundingClientRect();
|
||||
var scrollTop = viewportElement.scrollTop;
|
||||
var scrollLeft = viewportElement.scrollLeft;
|
||||
|
||||
var scrollTop = window.pageYOffset || viewportElement.scrollTop;
|
||||
var scrollLeft = window.pageXOffset || viewportElement.scrollLeft;
|
||||
|
||||
pos[0] = box.left + scrollLeft;
|
||||
pos[1] = box.top + scrollTop;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user