Angular2: mouse event handling (movement relative to current position)

前端 未结 2 1663
独厮守ぢ
独厮守ぢ 2021-02-04 03:21

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)

2条回答
  •  攒了一身酷
    2021-02-04 03:55

    The problem that you have is that the code is not reactive. In reactive programming all behaviors should be defined at decoration time and only one subscription is required.

    Here is an example: Angular2/rxjs mouse translation/rotation

    import {Component, NgModule, OnInit, ViewChild} from '@angular/core'
    import {BrowserModule, ElementRef, MouseEvent} from '@angular/platform-browser'
    import {Observable} from 'rxjs/Observable';
    import 'rxjs/add/observable/fromEvent';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/switchMapTo';
    import 'rxjs/add/operator/takeUntil';
    import 'rxjs/add/operator/combineLatest';
    import 'rxjs/add/operator/startWith';
    
    @Component({
      selector: 'my-app',
      styles: [`
      canvas{
        border: 1px solid red;
      }`],
      template: `
        

    translate/Rotate by mouse

    Translate by delta: {{relativeTo$|async|json}}

    Rotate by angle: {{rotateToAngle$|async|json}}

    ` }) export class App extends OnInit { @ViewChild('canvas') canvas: ElementRef; relativeTo$: Observable<{dx:number, dy:number, start: MouseEvent}>; rotateToAngle$: Observable<{angle:number, start: MouseEvent}>; ngOnInit() { const canvasNE = this.canvas.nativeElement; const mouseDown$ = Observable.fromEvent(canvasNE, 'mousedown'); const mouseMove$ = Observable.fromEvent(canvasNE, 'mousemove'); const mouseUp$ = Observable.fromEvent(canvasNE, 'mouseup'); const moveUntilMouseUp$= mouseMove$.takeUntil(mouseUp$); const startRotate$ = mouseDown$.switchMapTo(moveUntilMouseUp$.startWith(null)); const relativePoint = (start: MouseEvent, end: MouseEvent): {x:number, y:number} => (start && end && { dx: start.clientX - end.clientX, dy: start.clientY - end.clientY, start: start } || {}); this.relativeTo$ = startRotate$ .combineLatest(mouseDown$) .map(arr => relativePoint(arr[0],arr[1])); this.rotateToAngle$ = this.relativeTo$ .map((tr) => ({angle: Math.atan2(tr.dy, tr.dx), start: tr.start})); // this.relativeTo$.subscribe(console.log.bind(console,'rotate:')); // this.rotateToAngle$.subscribe(console.log.bind(console,'rotate 0:')); } } @NgModule({ imports: [ BrowserModule ], declarations: [ App ], bootstrap: [ App ] }) export class AppModule {}

提交回复
热议问题