Advertisement
Guest User

Untitled

a guest
Jul 15th, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { Component, Input, forwardRef, OnInit, OnDestroy, AfterViewInit, HostListener, Renderer2, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';
  2. import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "@angular/forms";
  3.  
  4. @Component({
  5.     selector: 'value-selector',
  6.     templateUrl: '../../templates/elements/value-selector.html',
  7.     styleUrls:
  8.     [
  9.         '../../styles/elements/value-selector.scss'
  10.     ],
  11.     providers:
  12.     [
  13.         {
  14.             provide: NG_VALUE_ACCESSOR,
  15.             useExisting: forwardRef(() => ValueSelectorComponent),
  16.             multi: true
  17.         }
  18.     ]
  19. })
  20. export class ValueSelectorComponent implements ControlValueAccessor, OnInit, AfterViewInit, OnDestroy
  21. {
  22.     private value: Value;
  23.     private disabled: boolean = false;
  24.  
  25.     @Input() min: number;
  26.     @Input() max: number;
  27.     @Input() selectors: number = 1;
  28.     @Input() step: number = 1;
  29.     @Input() unit: string;
  30.  
  31.     @ViewChild('Bar') Bar: ElementRef;
  32.     @ViewChild('Sel1') Sel1: ElementRef;
  33.     @ViewChild('Sel2') Sel2: ElementRef;
  34.    
  35.     private Selector1: Selector = new Selector();
  36.     private Selector2: Selector = new Selector();
  37.  
  38.     private MDL1: () => void;
  39.     private MDL2: () => void;
  40.     private TS1: () => void;
  41.     private TS2: () => void;
  42.  
  43.     constructor(private CD: ChangeDetectorRef, private renderer: Renderer2)
  44.     {
  45.  
  46.     }
  47.  
  48.     ngOnInit(): void
  49.     {
  50.         // Initializam datele
  51.         if (this.selectors < 1 && this.selectors > 2)
  52.         {
  53.             throw new Error('Invalid selectors number!');
  54.         }  
  55.  
  56.         this.min = Number(this.min);
  57.         this.max = Number(this.max);
  58.         this.selectors = Number(this.selectors);
  59.         this.step = Number(this.step);
  60.  
  61.         if (this.selectors == 1)
  62.         {
  63.             this.Selector1.PercentageValue = 1;
  64.         }
  65.         else if (this.selectors == 2)
  66.         {
  67.             this.Selector2.PercentageValue = 1;
  68.         }
  69.  
  70.         this.value = {
  71.             min: this.min,
  72.             max: this.max
  73.         };
  74.     }
  75.  
  76.     ngAfterViewInit(): void
  77.     {
  78.         this.MDL1 = this.renderer.listen(this.Sel1.nativeElement, 'mousedown', (event) =>
  79.         {
  80.             this.StartDrag(this.Selector1, event.clientX, event);
  81.         });
  82.  
  83.         this.TS1 = this.renderer.listen(this.Sel1.nativeElement, 'touchstart', (event) =>
  84.         {
  85.             this.StartDrag(this.Selector1, event.touches[0].clientX, event);
  86.         });
  87.  
  88.         if (this.selectors == 2)
  89.         {
  90.             this.TS2 = this.renderer.listen(this.Sel2.nativeElement, 'touchstart', (event) =>
  91.             {
  92.                 this.StartDrag(this.Selector2, event.touches[0].clientX, event);
  93.             });
  94.    
  95.             this.MDL2 = this.renderer.listen(this.Sel2.nativeElement, 'mousedown', (event) =>
  96.             {
  97.                 this.StartDrag(this.Selector2, event.clientX, event);
  98.             });
  99.         }
  100.  
  101.         // Dezactivam verificarile de schimbari
  102.         // In mod normal ChangeDetectionStrategy nu ar permite event-urilor sa functioneze
  103.         // Insa avem atasate niste evente, insa ele trebuie sa functioneze doar cand se trage, nu mereu.
  104.         //this.CD.detach();
  105.     }
  106.  
  107.     ngOnDestroy()
  108.     {
  109.         if (this.MDL1) this.MDL1();
  110.         if (this.TS1) this.TS1();
  111.         if (this.selectors == 2)
  112.         {
  113.             if (this.MDL2) this.MDL2();
  114.             if (this.TS2) this.TS2();
  115.         }
  116.     }
  117.  
  118.    
  119.     // ControlValueAccessor
  120.     private onTouchedCallback: () => void = () => {};
  121.     private onChangeCallback: (_: any) => void = () => {};
  122.  
  123.     writeValue(value: Value)
  124.     {
  125.         this.value = value;
  126.         this.onChangeCallback(value);
  127.         //this.CD.detectChanges();    
  128.     }
  129.  
  130.     registerOnChange(fn: any)
  131.     {
  132.         this.onChangeCallback = fn;
  133.     }
  134.  
  135.     registerOnTouched(fn: any)
  136.     {
  137.         this.onTouchedCallback = fn;
  138.     }
  139.  
  140.     setDisabledState(isDisabled: boolean)
  141.     {
  142.         this.disabled = isDisabled;
  143.         //this.CD.detectChanges();
  144.     }
  145.     // ControlValueAccessor END
  146.  
  147.     @HostListener('window:mouseup')
  148.     Mouseup()
  149.     {
  150.         this.StopDrag(this.Selector1);
  151.         if (this.selectors == 2)
  152.         {
  153.             this.StopDrag(this.Selector2);
  154.         }
  155.     }
  156.  
  157.     @HostListener('window:touchend')
  158.     Touchend()
  159.     {
  160.         this.StopDrag(this.Selector1);
  161.         if (this.selectors == 2)
  162.         {
  163.             this.StopDrag(this.Selector2);
  164.         }
  165.     }  
  166.  
  167.     @HostListener('window:touchcancel')
  168.     Touchcancel()
  169.     {
  170.         this.StopDrag(this.Selector1);
  171.         if (this.selectors == 2)
  172.         {
  173.             this.StopDrag(this.Selector2);
  174.         }
  175.     }  
  176.  
  177.     @HostListener('document:mousemove', ['$event'])
  178.     Mousemove(e: any)
  179.     {
  180.         if (this.Selector1.Drag === true)
  181.         {
  182.             this.OnMove(this.Selector1, e.clientX);
  183.         }
  184.         else if (this.Selector2.Drag === true)
  185.         {
  186.             this.OnMove(this.Selector2, e.clientX);
  187.         }
  188.     }
  189.  
  190.     @HostListener('document:touchmove', ['$event'])
  191.     Touchmove(e: any)
  192.     {
  193.         if (this.Selector1.Drag === true)
  194.         {
  195.             this.OnMove(this.Selector1, e.touches[0].clientX);
  196.         }
  197.         else if (this.Selector2.Drag === true)
  198.         {
  199.             this.OnMove(this.Selector2, e.touches[0].clientX);
  200.         }
  201.     }    
  202.  
  203.     private StartDrag(selector: Selector, x: number, event: any): void
  204.     {
  205.         selector.Drag = true;
  206.         selector.OldX = x;
  207.         event.stopPropagation();
  208.         event.preventDefault();
  209.     }
  210.  
  211.     private StopDrag(selector: Selector): void
  212.     {
  213.         selector.Drag = false;
  214.     }
  215.  
  216.     private OnMove(selector: Selector, x: number): void
  217.     {
  218.         const distance: number = x - selector.OldX;
  219.         const bar_width: number = this.Bar.nativeElement.getBoundingClientRect().width;
  220.         const new_x: number = (bar_width * selector.PercentageValue) + distance;
  221.         let new_pval: number = new_x / bar_width;
  222.         if (new_pval > 1)
  223.         {
  224.             new_pval = 1;
  225.         }
  226.         else if (new_pval < 0)
  227.         {
  228.             new_pval = 0;
  229.         }
  230.  
  231.         if (this.SelectorValue(new_pval) % this.step === 0)
  232.         {
  233.             selector.OldX = x;
  234.             selector.PercentageValue = new_pval;  
  235.  
  236.             this.writeValue
  237.             (
  238.                 {
  239.                     min: this.SelectorValue(this.Minimum),
  240.                     max: this.SelectorValue(this.Maximum)
  241.                 }
  242.             );
  243.         }
  244.     }
  245.  
  246.     private SelectorValue(value: number): number
  247.     {
  248.         return Math.floor(this.min + (Math.abs(this.min - this.max) * value));
  249.     }
  250.  
  251.     private get Minimum(): number
  252.     {
  253.         if (this.Selector1.PercentageValue < this.Selector2.PercentageValue)
  254.         {
  255.             return this.Selector1.PercentageValue;
  256.         }
  257.         else
  258.         {
  259.             return this.Selector2.PercentageValue;
  260.         }
  261.     }
  262.  
  263.     private get Maximum(): number
  264.     {
  265.         if (this.Selector1.PercentageValue > this.Selector2.PercentageValue)
  266.         {
  267.             return this.Selector1.PercentageValue;
  268.         }
  269.         else
  270.         {
  271.             return this.Selector2.PercentageValue;
  272.         }
  273.     }
  274.  
  275.     private get BarRangeStyle(): any
  276.     {
  277.         return {
  278.             'left': (this.Minimum * 100) + '%',
  279.             'width': ((Math.abs(this.Selector1.PercentageValue - this.Selector2.PercentageValue)) * 100) + '%'
  280.         };
  281.     }
  282. }
  283.  
  284. class Selector
  285. {
  286.     PercentageValue: number = 0;
  287.     Drag: boolean = false;
  288.     OldX: number = 0;
  289. }
  290.  
  291.  
  292. interface Value
  293. {
  294.     min: number;
  295.     max: number;
  296. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement