My user should be able to move (or rotate) an object by mouse in a canvas. When mouse events occur the screen coordinates are used to calculate the delta (direction and length) to the last event. Nothing special...
- mousedown (get the first coordinate)
- mousemove (get nth coordinate, calculate deltaXY, move object by deltaXY)
- mouseup (same as step 2 and stop the mousemove and mouseup event handling)
After this chain of events it should be possible to repeat the same action.
This outdated example works as expected, after removing the toRx
calls. But here the delta to the first coordinate is determined: github.com:rx-draggable
Here is my effort to adapt the code from the 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 only for one cycle. After the mouseup
event i got this error:
Uncaught EXCEPTION: Error during evaluation of "mousemove"
ORIGINAL EXCEPTION: ObjectUnsubscribedError
ERROR CONTEXT: EventEvaluationErrorContext
The cancellation of the mousemove
subscription does not work. The error is repeating for all following mousemoves.
Do you have an idea what is wrong with my code? Is there a different elegant approach to solve this problem?