New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

createjs.Touch.enable(stage, false, true); does not work in 0.8.0 #586

Open
ylazy opened this Issue Mar 19, 2015 · 7 comments

Comments

Projects
None yet
9 participants
@ylazy

ylazy commented Mar 19, 2015

Hello!

createjs.Touch.enable(stage, false, true); work as expected in 0.7.1. I can press-move canvas on html page. But it does not work on 0.8.0 anymore.

Thanks!
Ylazy

@derz

This comment has been minimized.

derz commented Mar 19, 2015

Duplicate of #585. But good that others can confirm the bug. :-)

@ylazy

This comment has been minimized.

ylazy commented May 29, 2015

this bug still found at the new build 0.8.1

@tylerault

This comment has been minimized.

tylerault commented Jun 8, 2015

Confirmed on 0.8.1. Single touch has no impact, so Touch.enable(stage,true,true) fails as well.

@Patrick-Seymour

This comment has been minimized.

Patrick-Seymour commented Jul 16, 2015

Had to deal with this issue today. Getting touch support working correctly is currently a two or three step process, depending on how you want ButtonHelpers to react to touch input.

First, you need to enable touch support on your stage, which everyone seems to be getting so far.

// 1
createjs.Touch.enable(stage, false, true);

At this point, all touch events that occur on the canvas HTML element, are effectively translated into mouse events for the createjs library, eg "mousedown" instead of "touchstart" or any such things. And this part works as expected.

Now, the way browser touch events work is that by default, user interactions with the page will result in zooming or swiping unless you call evt.preventDefault() on the browser event. This tells the browser that you are handling the event, and to not use the event for zooming or swiping.

However, you will notice that in actuality no events that occur on the canvas are used by the browser for its default actions. Eg, no swiping or zooming if you touch the canvas at all. Something is calling evt.preventDefault() on all events, even unhandled ones.

And, lo and behold, in the EaselJS Stage class is the following code snippet:

p._handlePointerDown = function(id, e, pageX, pageY, owner) {
  if (this.preventSelection) { e.preventDefault(); }
  ...
};

The e parameter is a browser event. So, this code is causing all browser events to disengage their default actions. Not what we want. So what does this preventSelection property do? The documentation says:

Prevents selection of other elements in the html page if the user clicks and drags, or double clicks on the canvas. This works by calling preventDefault() on any mousedown events (or touch equivalent) originating on the canvas.

Ah. Well, luckily the fix is simple:

// 2
stage.preventSelection = false;

I haven't really noticed any negative behaviors in my project by setting this property. And, it works! Much better interactions with the canvas, yet the user can still swipe and zoom using the canvas as an anchor point for the touch events.

Now, one last thing to consider, is that if the user is directly interacting with the canvas at all, you may want to disable the swipe or zoom functionality of the browser, on an event-by-event basis. For example, if you have users tap-and-drag in your application (such as to draw a line), you will want to disable any default browser actions when you handle the "click" event. Doing so is simple:

evt.nativeEvent.preventDefault();

Keep in mind, that if you are within createjs, you have to deal with createjs events and not browser events. evt.nativeEvent will have a reference to the browser event that originated the createjs event instance, and that is the object you want to prevent the default action on.

Finally, you may want to have the ButtonHelper class prevent the default browser action, when a user clicks on a button. You can do that with the following code snippet addition in the ButtonHelper.handleEvent function definition:

// 3
p.handleEvent = function(evt) {
  ...
  if (type == "mousedown") {
    evt && evt.nativeEvent && evt.nativeEvent.preventDefault && evt.nativeEvent.preventDefault();
    ...
};

The line of code needs to check for property existence as it goes because sometimes empty events are sent to the handler (at least when I tested it). But, other than that it seems to work decently enough.

@jaejeongkim

This comment has been minimized.

jaejeongkim commented Sep 16, 2015

Dear pittins.
I've test "stage.preventSelection = false;" method.
It really works for native touch event.
But, it cause also event called twice.
Do you have any solution?

I've tested on iOS8, Android Lollipop

@lakemalcom

This comment has been minimized.

lakemalcom commented Aug 5, 2016

@jaejeongkim I've found that the two events are different -- one is a TouchEvent and one is a MouseEvent. The touch event seems to fire inconsistently so I check in my handler for the evt.nativeEvent instanceof MouseEvent. At least this seems to be a good work around for now.

@DevelopSmith

This comment has been minimized.

DevelopSmith commented Oct 29, 2018

@Patrick-Seymour
Sir, you made my day. Thank you very much

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment