takopus Posted March 19, 2019 Share Posted March 19, 2019 I've found some strange behavior in interactivity events of display object inside a masked container. Not sure if this is a bug or just a questionable decision; anyway, it poses some problems. Generally interactive display objects receives events such as "pointermove" or "pointerupoutside" at any time, whether pointer is over them or not. Same applies to masked display objects, by the way. But if you place an interactive display object inside a masked container, events fire only when pointer is over masked area. All events, including "pointerupoutside", so there's no way to keep track of pointer position and button state. Look at this codepen. Have anyone faced this problem? I guess I can assign event listeners to the stage container or nearest parent without mask, and it will probably work, but seems a little bit dirty to me. Is there a better solution? Quote Link to comment Share on other sites More sharing options...
takopus Posted March 19, 2019 Author Share Posted March 19, 2019 Ok, gonna share my own solution. Kinda dirty, but working. Hope this will help someone. First, add this little helper to DisplayObject. It will return nearest parent which is not inside a masked container (but can have mask, which is irrelevant): PIXI.DisplayObject.prototype.getNearestUnmaskedParent = function(){ var parents = []; var dobj = this; while (dobj.parent){ dobj = dobj.parent; parents.unshift(dobj); } for (var i=0, l=parents.length; i<l; i++){ if (parents[i].mask) return parents[i]; } return this; }; And now if you need to add event listeners to a display object inside a masked container, do it like this: this.onPointerDown = function(){ // get unmasked parent: this.unmaskedParent = this.myInteractiveObject.getNearestUnmaskedParent(); // store it's interactivity state and set it to true: this.unmaskedParentInteractivity = this.unmaskedParent.interactivity; this.unmaskedParent.interactivity = true; // set your event listeners: this.unmaskedParent.on("pointerupoutside", this.onPointerUp, this); } this.onPointerUp = function(){ this.unmaskedParent.removeListener("pointerupoutside", this.onPointerUp, this); // restore parent interactivity and forget it: this.unmaskedParent.interactivity = this.unmaskedParentInteractivity; delete this.unmaskedParent; delete this.unmaskedParentInteractivity; } this.myInteractiveObject.on("pointerdown", this.onPointerDown, this); Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 19, 2019 Share Posted March 19, 2019 I think that's the cause: https://github.com/pixijs/pixi.js/blob/v4.x/src/interaction/InteractionManager.js#L1045 I added that `else` and i certainly didnt think about pointer events and stuff like `trackedPointers`. Unfortunately, I already have too many issues on me, I can only recommend to look at my old try at fixing interaction: https://github.com/pixijs/pixi-display/blob/layers/src/InteractionManagerMixin.ts#L19 Maybe if you add pixi-layers plugin in the project it'll help (that's the repo i mentioned) If you have an idea on how to fix that easily in vanilla pixijs you can submit PR for pixi version v4 (v4.x branch) or for v5 (dev branch, default). Quote Link to comment Share on other sites More sharing options...
takopus Posted March 19, 2019 Author Share Posted March 19, 2019 I fear I have no required knowledge in PIXI or actually JS to dig into all of this. And, sadly, my solution above helps with only a half of the problem. Now I can watch pointer movement, but I can't get "pointerupoutside" event. I catch "pointerdown" on some DisplayObject (scrollbar, actually) and add "pointerupoutside" on any of it's parents. But since said parent had not received "pointerdown" before, "pointerupoutside" won't fire. It seems to me that right solution may be simple: any listener, subscribed to "*move" and "*upoutiside" events must get them, regardless of hit test. If you have a minute to spare, could you please stick my nose to place in sources where I can try to make an override for this? Thanks for your help anyway! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 19, 2019 Share Posted March 19, 2019 all InteractionManager file I really dont know how to do what you want, it seems like invariant that has to be enforced in multiple methods and added in commentary, and maybe with tests, so no one violates it. We can ask @themoonrat Quote Link to comment Share on other sites More sharing options...
takopus Posted March 19, 2019 Author Share Posted March 19, 2019 Ah, I see. Don't think it's necessary at this point. Thank you for your time! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.