dmko Posted May 22, 2017 Share Posted May 22, 2017 Originally, I had a Sprite which I managed to drag around by something like the following: 1. Attaching pointerdown, pointermove, pointerup, pointeroutside 2. For movement- events pass InteractionData, which allows calling getLocalPosition(parent, pointHolder, interactionData.global); 3. Simply update the position to pointHolder (there's a slight difference to my actual code where pointerdown also logs an offset which is added to the movements, and helpers/cleanup/etc. but we can ignore that for now) This worked fine - but then I noticed that really fast movements all around tended to "lose" the object and it would stop tracking briefly. I could then duplicate it without crazy motions but the sort of use case that kids would definitely do. So my new code took a different approach, which works perfectly on desktop but fails on the iPad: 1. only attach pointerdown to the sprite 2. when the sprite is touched: start a ticker add pointerup and pointerupoutside to renderer.plugins.interaction (this will kill the ticker and remove themselves) 3. while the ticker is ticking: get the main InteractionManager from renderer.plugins.interaction get the updated point via interactionManager.mouse.getLocalPosition(parent, pointHolder, interactionManager.mouse.global); set the position to this Clearly the reason this fails is because InteractionManager.mouse != touch. Is there a workaround for that? Alternatively, is there a way to get a single global touch event, regardless of which object is active or even if no interactive objects were touched? (i.e. I could start the listener with the sprite pointerdown, but then track pointermove via a stage-wide listener to avoid the tracking problem above, even if there's no stage-sized interactive listener below it) Quote Link to comment Share on other sites More sharing options...
dmko Posted May 22, 2017 Author Share Posted May 22, 2017 (edited) n/m... seems InteractionManager itself will dispatch the events more reliably for some reason... I dunno why, but this approach seems to work better than just listening on the sprite itself - and it's cross-platform Maybe this base class will help others too: export class DragContainer extends PIXI.Container { private touchPoint: PIXI.Point = new PIXI.Point(); private dragOffset:PIXI.Point = new PIXI.Point(); //if listenerTarget is provided, then dragging only starts when that is touched (though this container itself is what moves) //screenLimit sets the boundries for draggable area constructor(private renderer: (PIXI.WebGLRenderer | PIXI.CanvasRenderer), listenerTarget?:PIXI.DisplayObject, public screenLimit?: PIXI.Rectangle) { super(); if(listenerTarget === undefined) { listenerTarget = this; } listenerTarget.on('pointerdown', (iEvent:PIXI.interaction.InteractionEvent) => { this.clearListeners(); this.updateTouchPoint(iEvent.data); this.dragOffset.x = this.x - this.touchPoint.x; this.dragOffset.y = this.y - this.touchPoint.y; renderer.plugins.interaction.on('pointermove', this.onDragMove, this); renderer.plugins.interaction.on('pointerup', this.onDragEnd, this); renderer.plugins.interaction.on('pointeroutside', this.onDragEnd, this); this.emit('dragStart'); }); } onDragMove(iEvent:PIXI.interaction.InteractionEvent) { this.updateTouchPoint(iEvent.data); let targetX:number = this.touchPoint.x + this.dragOffset.x; let targetY:number = this.touchPoint.y + this.dragOffset.y; let allowMove:boolean = (this.screenLimit === undefined) ? true : this.screenLimit.contains(targetX, targetY); if(allowMove) { this.position.set(targetX, targetY); this.emit('dragMove'); } } onDragEnd(iEvent:PIXI.interaction.InteractionEvent) { this.clearListeners(); this.emit('dragEnd'); } clearListeners() { this.renderer.plugins.interaction.off('pointermove', this.onDragMove, this); this.renderer.plugins.interaction.off('pointerup', this.onDragEnd, this); this.renderer.plugins.interaction.off('pointeroutside', this.onDragEnd, this); } updateTouchPoint(iData:PIXI.interaction.InteractionData) { iData.getLocalPosition(this.parent, this.touchPoint, iData.global); } } Edited May 22, 2017 by dmko added screenLimit code 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.