Open seanbeauchamp opened 8 years ago
The underlying issue seems clear upon a quick code review. Touch/mouse events are relying on pageX
and pageY
which need to be translated to match the stage element's positioning. The Core
object defines and initially sets the values _pageX
and _pageY
to the upper-left bounds of the stage element, however they are never updated beyond first initialization. I suspect the original authors reasoned that, in most cases, the absolute position of the stage element would not change.
I am no expert in web development, so my knowledge is definitely lacking in areas; however, I have to wonder: why are absolute coordinates being used in the first place? If it is possible to obtain coordinates relative to the stage element from the original touch/mouse events, then no coordinate conversion would be needed. This would probably be a good line of investigation, unfortunately I do not have any more time to devote beyond this post.
Provided page-centric coordinates must be used, one possible fix involves monitoring the stage element for changes in positioning, to allow the Core
object to maintain those two member variables. Alternatively, the Event._initPosition
function could query the current location of the stage element dynamically, making the cached values unnecessary. Profiling would be required to determine if this on-demand approach is acceptable from a performance standpoint.
Until the best course of action is determined and implemented, it should be easy enough to work around the issue. When you detect the position of the stage element has changed, manually recompute the values within the Core
object using something like the following:
if (enchant.Core.instance) {
var core = enchant.Core.instance;
var bounding = core._element.getBoundingClientRect();
core._pageX = Math.round(window.scrollX || window.pageXOffset + bounding.left);
core._pageY = Math.round(window.scrollY || window.pageYOffset + bounding.top);
}
If it is not practical to monitor the stage element, you instead could replace the Event._initPosition
function with one that dynamically queries the placement of the stage element, similar to the following:
if (enchant.Core.instance) {
console.log("enchant.js detected. Patching Event._initPosition to workaround issue #324.");
enchant.Event.prototype._initPosition = function(pageX, pageY) {
var core = enchant.Core.instance;
var bounding = core._element.getBoundingClientRect();
var stageX = Math.round(window.scrollX || window.pageXOffset + bounding.left);
var stageY = Math.round(window.scrollY || window.pageYOffset + bounding.top);
this.x = this.localX = (pageX - stageX) / core.scale;
this.y = this.localY = (pageY - stageY) / core.scale;
};
}
NOTE: I have done only minimal testing of these snippets, so do take care to test them carefully to ensure they function well in your environment.
Thank you for your work @seraku24
If there's an obvious fix I'm missing then feel free to disregard, but it appears items designed to be clicked on in an Enchant game no longer respond when a window is resized. Returning the window back to the original size returns functionality, but there doesn't seem to be a way to reposition the touch-area for objects with a command like window.onresize.