Angular2:鼠标事件处理(相对于当前位置的移动)

2024-05-14

我的用户应该能够通过鼠标在画布中移动(或旋转)对象。当鼠标事件发生时,屏幕坐标用于计算与最后一个事件的增量(方向和长度)。没什么特别的...

  1. mousedown(获取第一个坐标)
  2. mousemove(获取第n个坐标,计算deltaXY,按deltaXY移动对象)
  3. mouseup(与步骤2相同并停止mousemove和mouseup事件处理)

在这一系列事件之后,应该可以重复相同的操作。

删除后,这个过时的示例按预期工作toRx来电。但这里确定了第一个坐标的增量:github.com:rx-draggable https://github.com/Reactive-Extensions/RxJS

这是我对示例中的代码进行的修改:

@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;
      }
    });
  }
  ...
}

它仅适用于一个周期。之后mouseup事件我收到此错误:

未捕获的异常:评估“mousemove”时出错

原始异常:ObjectUnsubscribedError

错误上下文:EventEvaluationErrorContext

的取消mousemove订阅不起作用。所有后续鼠标移动都会重复该错误。

你知道我的代码有什么问题吗?是否有不同的优雅方法来解决这个问题?


我相信你的问题在于之间的区别unsubscribe() and remove(sub : Subscription) on an EventEmitter。但是可以在不使用订阅的情况下完成此操作(除了由@HostListener)并使其易于阅读。我稍微重写了你的代码。您可能会考虑将您的mouseup event on the document or window,否则如果在画布外释放鼠标,则会出现奇怪的行为。

警告:前面有未经测试的代码

@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;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular2:鼠标事件处理(相对于当前位置的移动) 的相关文章