From 8a147535dea2a74322e2bd02eed7dfbf36c2333f Mon Sep 17 00:00:00 2001 From: jalf Date: Tue, 29 Jan 2013 17:06:03 +0100 Subject: [PATCH 1/3] Clamp mouseclick coordinates to target element bounds --- include/util.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/util.js b/include/util.js index 6f6c52a6..dd1f252f 100644 --- a/include/util.js +++ b/include/util.js @@ -298,7 +298,9 @@ Util.getEventPosition = function (e, obj, scale) { if (typeof scale === "undefined") { scale = 1; } - return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale}; + var x = Math.max(Math.min(docX - pos.x, obj.width-1), 0); + var y = Math.max(Math.min(docY - pos.y, obj.height-1), 0); + return {'x': x / scale, 'y': y / scale}; }; From 0d0f754aade74dbd74a1a9766b66f3d00c754b3c Mon Sep 17 00:00:00 2001 From: jalf Date: Tue, 22 Jan 2013 12:51:23 +0100 Subject: [PATCH 2/3] Listen for mouseup events from window as well as target element Pressing an holding a mouse button and then moving the mouse out of the canvas before releasing meant that onmouseup was never triggered. --- include/input.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/input.js b/include/input.js index fef21634..fa753d94 100644 --- a/include/input.js +++ b/include/input.js @@ -609,10 +609,12 @@ that.grab = function() { if ('ontouchstart' in document.documentElement) { Util.addEvent(c, 'touchstart', onMouseDown); + Util.addEvent(window, 'touchend', onMouseUp); Util.addEvent(c, 'touchend', onMouseUp); Util.addEvent(c, 'touchmove', onMouseMove); } else { Util.addEvent(c, 'mousedown', onMouseDown); + Util.addEvent(window, 'mouseup', onMouseUp); Util.addEvent(c, 'mouseup', onMouseUp); Util.addEvent(c, 'mousemove', onMouseMove); Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', @@ -632,10 +634,12 @@ that.ungrab = function() { if ('ontouchstart' in document.documentElement) { Util.removeEvent(c, 'touchstart', onMouseDown); + Util.removeEvent(window, 'touchend', onMouseUp); Util.removeEvent(c, 'touchend', onMouseUp); Util.removeEvent(c, 'touchmove', onMouseMove); } else { Util.removeEvent(c, 'mousedown', onMouseDown); + Util.removeEvent(window, 'mouseup', onMouseUp); Util.removeEvent(c, 'mouseup', onMouseUp); Util.removeEvent(c, 'mousemove', onMouseMove); Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', From b1b342a97e6ea31a6080e2bf5cdf94988563b03a Mon Sep 17 00:00:00 2001 From: jalf Date: Wed, 30 Jan 2013 11:48:33 +0100 Subject: [PATCH 3/3] Capture mouse events and filter irrelevant ones --- include/input.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/include/input.js b/include/input.js index fa753d94..b996c7d5 100644 --- a/include/input.js +++ b/include/input.js @@ -486,7 +486,8 @@ function Mouse(defaults) { "use strict"; var that = {}, // Public API methods - conf = {}; // Configuration attributes + conf = {}, // Configuration attributes + mouseCaptured = false; // Configuration attributes Util.conf_defaults(conf, that, defaults, [ @@ -499,7 +500,23 @@ Util.conf_defaults(conf, that, defaults, [ ['touchButton', 'rw', 'int', 1, 'Button mask (1, 2, 4) for touch devices (0 means ignore clicks)'] ]); +function captureMouse() { + // capturing the mouse ensures we get the mouseup event + if (conf.target.setCapture) { + conf.target.setCapture(); + } + // some browsers give us mouseup events regardless, + // so if we never captured the mouse, we can disregard the event + mouseCaptured = true; +} + +function releaseMouse() { + if (conf.target.releaseCapture) { + conf.target.releaseCapture(); + } + mouseCaptured = false; +} // // Private functions // @@ -536,11 +553,17 @@ function onMouseButton(e, down) { } function onMouseDown(e) { + captureMouse(); onMouseButton(e, 1); } function onMouseUp(e) { + if (!mouseCaptured) { + return; + } + onMouseButton(e, 0); + releaseMouse(); } function onMouseWheel(e) {