typescript - Angular2: mouse event handling (movement relative to current position) -
my user should able move (or rotate) object mouse in canvas. when mouse events occur screen coordinates used calculate delta (direction , length) last event. nothing special...
- mousedown (get first coordinate)
- mousemove (get nth coordinate, calculate deltaxy, move object deltaxy)
- mouseup (same step 2 , stop mousemove , mouseup event handling)
after chain of events should possible repeat same action.
this outdated example works expected, after removing torx
calls. here delta first coordinate determined: github.com:rx-draggable
here effort adapt code example:
@component({ selector: 'home', providers: [scene], template: '<canvas #canvas id="3dview"></canvas>' }) export class home { @viewchild('canvas') canvas: elementref; private scene: scene; private mousedrag = new eventemitter(); private mouseup = new eventemitter<mouseevent>(); private mousedown = new eventemitter<mouseevent>(); private mousemove = new eventemitter<mouseevent>(); private last: mouseevent; private el: htmlelement; @hostlistener('mouseup', ['$event']) onmouseup(event: mouseevent) { this.mouseup.emit(event); } @hostlistener('mousemove', ['$event']) onmousemove(event: mouseevent) { this.mousemove.emit(event); } constructor(@inject(elementref) elementref: elementref, scene: scene) { this.el = elementref.nativeelement; this.scene = scene; } @hostlistener('mousedown', ['$event']) mousehandling(event) { event.preventdefault(); console.log('mousedown', event); this.last = event; this.mousemove.subscribe({next: evt => { console.log('mousemove.subscribe', evt); this.mousedrag.emit(evt); }}); this.mouseup.subscribe({next: evt => { console.log('mousemove.subscribe', evt); this.mousedrag.emit(evt); this.mousemove.unsubscribe(); this.mouseup.unsubscribe(); }}); } ngoninit() { console.log('init'); this.mousedrag.subscribe({ next: evt => { console.log('mousedrag.subscribe', evt); this.scene.rotate( evt.clientx - this.last.clientx, evt.clienty - this.last.clienty); this.last = evt; } }); } ... }
it works 1 cycle. after mouseup
event got error:
uncaught exception: error during evaluation of "mousemove"
original exception: objectunsubscribederror
error context: eventevaluationerrorcontext
the cancellation of mousemove
subscription not work. error repeating following mousemoves.
do have idea wrong code? there different elegant approach solve problem?
i believe problem lays difference between unsubscribe()
, remove(sub : subscription)
on eventemitter
. possible without use of subscriptions (except ones created @hostlistener
) , make easy read. i've rewritten code little. might consider though placing mouseup
event
on document
or window
, otherwise weird behaviour if release mouse outside canvas.
warning: untested code ahead
@component({ selector: 'home', providers: [scene], template: '<canvas #canvas id="3dview"></canvas>' }) export class home { @viewchild('canvas') canvas: elementref; private scene: scene; private last: mouseevent; private el: htmlelement; private mousedown : boolean = false; @hostlistener('mouseup') onmouseup() { this.mousedown = false; } @hostlistener('mousemove', ['$event']) onmousemove(event: mouseevent) { if(this.mousedown) { this.scene.rotate( event.clientx - this.last.clientx, event.clienty - this.last.clienty ); this.last = event; } } @hostlistener('mousedown', ['$event']) onmousedown(event) { this.mousedown = true; this.last = event; } constructor(elementref: elementref, scene: scene) { this.el = elementref.nativeelement; this.scene = scene; } }
Comments
Post a Comment