import { Component , ElementRef , Renderer2 , Input , Output , EventEmitter , OnInit , OnChanges , AfterViewInit , HostBinding , } from '@angular/core' ; import { Store , IPoint , IOptions , ISize , IResizeState , IResizeEvent , IRectangle , defaultBound , } from './resizable.store' ; import { resizeReducer } from './resizable.reducer' ; import { MOUSE_DOWN , RESIZE_STOP , RESIZE } from './resizable.actions' ; import { ResizableState } from './resizable.state' ; @ Component ( { selector : '[resizable]' , providers : [ Store ] , template : `
    <ng-content></ng-content>
    <div
      *ngFor="let dir of directions"
      class="ngr-grabber"
      [ngClass]="'ngr-' + dir"
      (mousedown)="onMouseDown($event, dir)"
      (touchstart)="onMouseDown($event, dir)"
    ></div>
  ` , styleUrls : [ 'resizable.component.css' ] , host : { '(document: mouseup)' : 'onMouseUp($event)' , '(document: touchend)' : 'onMouseUp($event)' , '(document: mousemove)' : 'onMouseMove($event)' , '(document: touchmove)' : 'onMouseMove($event)' , } , } ) export class ResizableComponent implements OnInit , OnChanges { @ Output ( ) resizeStart = new EventEmitter < IResizeEvent > ( ) ; @ Output ( ) resizing = new EventEmitter < IResizeEvent > ( ) ; @ Output ( ) resizeEnd = new EventEmitter < IResizeEvent > ( ) ; @ Input ( ) x : number ; @ Input ( ) y : number ; @ Input ( ) width ? : number ; @ Input ( ) height ? : number ; @ Input ( ) minWidth = 350 ; @ Input ( ) minHeight = 400 ; @ Input ( ) maxWidth = Infinity ; @ Input ( ) maxHeight = Infinity ; @ Input ( ) disableResize = false ; @ Input ( ) directions : string [ ] = [ 'bottom' , 'right' ] ; @ Input ( ) grid : ISize = { width : 1 , height : 1 } ; @ Input ( ) bound : IRectangle = null ; @ Input ( ) ratio : number = null ; constructor ( private el , private store , private renderer , private rState ) { } ngOnInit ( ) { this . renderer . addClass ( this . el . nativeElement , 'ngresizable' ) ; const css = getComputedStyle ( this . el . nativeElement ) ; this . width = css . width ? parseInt ( css . width , 10 ) : this . width ; this . height = css . height ? parseInt ( css . height , 10 ) : this . height ; this . minWidth = css . minWidth ? parseInt ( css . minWidth , 10 ) : this . minWidth ; this . minHeight = css . minHeight ? parseInt ( css . minHeight , 10 ) : this . minHeight ; this . maxWidth = css . maxWidth ? parseInt ( css . maxWidth , 10 ) : this . maxWidth ; this . maxHeight = css . maxHeight ? parseInt ( css . maxHeight , 10 ) : this . maxHeight ; this . store . addReducer ( resizeReducer ) ; this . setSize ( { width : this . width , height : this . height } , { x : this . x , y : this . y } ) ; } ngOnChanges ( c ) { this . setSize ( { width : this . width , height : this . height } , { x : this . x , y : this . y } ) ; } onMouseMove ( e ) { if ( e . touches ) { e = e . touches [ 0 ] ; } if ( this . _state . isResizing ) { this . emitAction ( RESIZE , { x : e . clientX , y : e . clientY , } ) ; const csize = this . _state . currentSize ; const cpos = this . _state . currentPosition ; this . setSize ( csize , cpos ) ; this . emitEvent ( this . resizing ) ; } } onMouseDown ( e , dir ) { if ( e . touches ) { e = e . touches [ 0 ] ; } this . emitAction ( MOUSE_DOWN , { x : e . clientX , y : e . clientY , } , { x : this . el . nativeElement . offsetLeft , y : this . el . nativeElement . offsetTop , } , { width : this . el . nativeElement . offsetWidth , height : this . el . nativeElement . offsetHeight , } , dir ) ; this . emitEvent ( this . resizeStart ) ; } onMouseUp ( e ) { this . emitAction ( RESIZE_STOP , { x : 0 , y : 0 } , { x : 0 , y : 0 } ) ; this . emitEvent ( this . resizeEnd ) ; } private emitAction ( action , mousePosition , startPosition ? , startSize ? , startDirection ? ) { const options = { minSize : { width : this . minWidth , height : this . minHeight } , maxSize : { width : this . maxWidth , height : this . maxHeight } , grid : this . grid , ratio : this . ratio , disabled : this . disableResize , directions : this . directions , bound : this . bound || defaultBound , } ; this . store . emitAction ( action , mousePosition , startPosition , options , startSize , startDirection ) ; } private emitEvent ( output ) { output . next ( { position : this . _state . currentPosition , size : this . _state . currentSize , direction : this . _state . direction , } ) ; } private get _state ( ) : IResizeState { return this . store . state ; } private setSize ( size , pos ) { this . width = size . width ; this . height = size . height ; this . x = pos . x ; this . y = pos . y ; this . renderer . setStyle ( this . el . nativeElement , 'width' , this . width + 'px' ) ; this . renderer . setStyle ( this . el . nativeElement , 'height' , this . height + 'px' ) ; this . renderer . setStyle ( this . el . nativeElement , 'left' , this . x + 'px' ) ; this . renderer . setStyle ( this . el . nativeElement , 'top' , this . y + 'px' ) ; } }