Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

better HostListener support as observable #4511

Closed
PatrickJS opened this issue Oct 4, 2015 · 2 comments
Closed

better HostListener support as observable #4511

PatrickJS opened this issue Oct 4, 2015 · 2 comments
Labels
effort2: days feature Issue that requests a new feature

Comments

@PatrickJS
Copy link
Member

PatrickJS commented Oct 4, 2015

Is there any way we can get more sugar for events as observables e.g.

import {Component, View, Directive, Output, EventEmitter, HostListener} from 'angular2/angular2';
import {DOM} from 'angular2/src/core/dom/dom_adapter';
import {ElementRef} from 'angular2/core';


@Directive({
  selector: '[draggable]'
})
export class Draggable {
  mouseup   = new EventEmitter();
  mousemove = new EventEmitter();
  mousedown = new EventEmitter();
  mousedrag;

  @HostListener('mouseup', ['$event'])
  onMouseup(event) {
    this.mouseup.next(event);
  }

  @HostListener('mousedown', ['$event'])
  onMousedown(event) {
    this.mousedown.next(event);
  }

  @HostListener('mousemove', ['$event'])
  onMousemove(event) {
    this.mousemove.next(event);
  }

  constructor(public element: ElementRef) {

    this.element.nativeElement.style.position = 'relative';
    this.element.nativeElement.style.cursor   = 'pointer';

    this.mousedrag = this.mousedown._subject
      .map(event => {
        event.preventDefault();
        // calculate offsets when mouse down
        return {
          left: event.clientX - this.element.nativeElement.getBoundingClientRect().left,
          top:  event.clientY - this.element.nativeElement.getBoundingClientRect().top
        };
      })
      .flatMap(imageOffset => {
        return this.mousemove._subject
          .map(pos => {
            // calculate offsets from mouse down to mouse moves
            return {
              top:  pos.clientY - imageOffset.top,
              left: pos.clientX - imageOffset.left
            };
          })
          .takeUntil(this.mouseup._subject);
      });

  }

  onInit() {
    this.mousedrag.subscribe({
      next: pos => {
        // Update position
        this.element.nativeElement.style.top  = pos.top  + 'px';
        this.element.nativeElement.style.left = pos.left + 'px';
      }
    });
  }

}

@Component({
  selector: 'app'
})
@View({
  // needed in order to tell Angular's compiler what's in the template
  directives: [ Draggable ],
  styles: [`
    [draggable] {
      -webkit-transform: translate3d(0, 0, 0);
      -moz-transform: translate3d(0, 0, 0);
      -ms-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0);
      background-image: url(https://cdn.rawgit.com/Reactive-Extensions/rx.angular.js/master/examples/draganddrop/logo.png);
      background-repeat: no-repeat;
      background-position: center;
      background-size: contain;
      height: 200px;
      width: 200px;
      color: #000000;
      border: 1px solid #666666;
      padding: 10px;
    }
  `],
  template: `

  <div draggable>
    Draggable Div
  </div>

  `
})
export class App {
  constructor() {

  }
}

[sidenote] bonus points if you can understand this madness

this.mousedrag = this.mousedown._subject.map(event => (event.preventDefault(), {
    left: event.clientX - this.element.nativeElement.getBoundingClientRect().left,
    top:  event.clientY - this.element.nativeElement.getBoundingClientRect().top
  })).flatMap(imageOffset => this.mousemove._subject.map(pos => ({
    top:  pos.clientY - imageOffset.top,
    left: pos.clientX - imageOffset.left
  })).takeUntil(this.mouseup._subject));

github-tipe-logo

@naomiblack naomiblack added comp: core effort2: days feature Issue that requests a new feature labels Oct 5, 2015
@jeffbcross
Copy link
Contributor

Closing as duplicate of #4062

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
effort2: days feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests

3 participants