Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Component, Input, forwardRef, OnInit, OnDestroy, AfterViewInit, HostListener, Renderer2, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';
- import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "@angular/forms";
- @Component({
- selector: 'value-selector',
- templateUrl: '../../templates/elements/value-selector.html',
- styleUrls:
- [
- '../../styles/elements/value-selector.scss'
- ],
- providers:
- [
- {
- provide: NG_VALUE_ACCESSOR,
- useExisting: forwardRef(() => ValueSelectorComponent),
- multi: true
- }
- ]
- })
- export class ValueSelectorComponent implements ControlValueAccessor, OnInit, AfterViewInit, OnDestroy
- {
- private value: Value;
- private disabled: boolean = false;
- @Input() min: number;
- @Input() max: number;
- @Input() selectors: number = 1;
- @Input() step: number = 1;
- @Input() unit: string;
- @ViewChild('Bar') Bar: ElementRef;
- @ViewChild('Sel1') Sel1: ElementRef;
- @ViewChild('Sel2') Sel2: ElementRef;
- private Selector1: Selector = new Selector();
- private Selector2: Selector = new Selector();
- private MDL1: () => void;
- private MDL2: () => void;
- private TS1: () => void;
- private TS2: () => void;
- constructor(private CD: ChangeDetectorRef, private renderer: Renderer2)
- {
- }
- ngOnInit(): void
- {
- // Initializam datele
- if (this.selectors < 1 && this.selectors > 2)
- {
- throw new Error('Invalid selectors number!');
- }
- this.min = Number(this.min);
- this.max = Number(this.max);
- this.selectors = Number(this.selectors);
- this.step = Number(this.step);
- if (this.selectors == 1)
- {
- this.Selector1.PercentageValue = 1;
- }
- else if (this.selectors == 2)
- {
- this.Selector2.PercentageValue = 1;
- }
- this.value = {
- min: this.min,
- max: this.max
- };
- }
- ngAfterViewInit(): void
- {
- this.MDL1 = this.renderer.listen(this.Sel1.nativeElement, 'mousedown', (event) =>
- {
- this.StartDrag(this.Selector1, event.clientX, event);
- });
- this.TS1 = this.renderer.listen(this.Sel1.nativeElement, 'touchstart', (event) =>
- {
- this.StartDrag(this.Selector1, event.touches[0].clientX, event);
- });
- if (this.selectors == 2)
- {
- this.TS2 = this.renderer.listen(this.Sel2.nativeElement, 'touchstart', (event) =>
- {
- this.StartDrag(this.Selector2, event.touches[0].clientX, event);
- });
- this.MDL2 = this.renderer.listen(this.Sel2.nativeElement, 'mousedown', (event) =>
- {
- this.StartDrag(this.Selector2, event.clientX, event);
- });
- }
- // Dezactivam verificarile de schimbari
- // In mod normal ChangeDetectionStrategy nu ar permite event-urilor sa functioneze
- // Insa avem atasate niste evente, insa ele trebuie sa functioneze doar cand se trage, nu mereu.
- //this.CD.detach();
- }
- ngOnDestroy()
- {
- if (this.MDL1) this.MDL1();
- if (this.TS1) this.TS1();
- if (this.selectors == 2)
- {
- if (this.MDL2) this.MDL2();
- if (this.TS2) this.TS2();
- }
- }
- // ControlValueAccessor
- private onTouchedCallback: () => void = () => {};
- private onChangeCallback: (_: any) => void = () => {};
- writeValue(value: Value)
- {
- this.value = value;
- this.onChangeCallback(value);
- //this.CD.detectChanges();
- }
- registerOnChange(fn: any)
- {
- this.onChangeCallback = fn;
- }
- registerOnTouched(fn: any)
- {
- this.onTouchedCallback = fn;
- }
- setDisabledState(isDisabled: boolean)
- {
- this.disabled = isDisabled;
- //this.CD.detectChanges();
- }
- // ControlValueAccessor END
- @HostListener('window:mouseup')
- Mouseup()
- {
- this.StopDrag(this.Selector1);
- if (this.selectors == 2)
- {
- this.StopDrag(this.Selector2);
- }
- }
- @HostListener('window:touchend')
- Touchend()
- {
- this.StopDrag(this.Selector1);
- if (this.selectors == 2)
- {
- this.StopDrag(this.Selector2);
- }
- }
- @HostListener('window:touchcancel')
- Touchcancel()
- {
- this.StopDrag(this.Selector1);
- if (this.selectors == 2)
- {
- this.StopDrag(this.Selector2);
- }
- }
- @HostListener('document:mousemove', ['$event'])
- Mousemove(e: any)
- {
- if (this.Selector1.Drag === true)
- {
- this.OnMove(this.Selector1, e.clientX);
- }
- else if (this.Selector2.Drag === true)
- {
- this.OnMove(this.Selector2, e.clientX);
- }
- }
- @HostListener('document:touchmove', ['$event'])
- Touchmove(e: any)
- {
- if (this.Selector1.Drag === true)
- {
- this.OnMove(this.Selector1, e.touches[0].clientX);
- }
- else if (this.Selector2.Drag === true)
- {
- this.OnMove(this.Selector2, e.touches[0].clientX);
- }
- }
- private StartDrag(selector: Selector, x: number, event: any): void
- {
- selector.Drag = true;
- selector.OldX = x;
- event.stopPropagation();
- event.preventDefault();
- }
- private StopDrag(selector: Selector): void
- {
- selector.Drag = false;
- }
- private OnMove(selector: Selector, x: number): void
- {
- const distance: number = x - selector.OldX;
- const bar_width: number = this.Bar.nativeElement.getBoundingClientRect().width;
- const new_x: number = (bar_width * selector.PercentageValue) + distance;
- let new_pval: number = new_x / bar_width;
- if (new_pval > 1)
- {
- new_pval = 1;
- }
- else if (new_pval < 0)
- {
- new_pval = 0;
- }
- if (this.SelectorValue(new_pval) % this.step === 0)
- {
- selector.OldX = x;
- selector.PercentageValue = new_pval;
- this.writeValue
- (
- {
- min: this.SelectorValue(this.Minimum),
- max: this.SelectorValue(this.Maximum)
- }
- );
- }
- }
- private SelectorValue(value: number): number
- {
- return Math.floor(this.min + (Math.abs(this.min - this.max) * value));
- }
- private get Minimum(): number
- {
- if (this.Selector1.PercentageValue < this.Selector2.PercentageValue)
- {
- return this.Selector1.PercentageValue;
- }
- else
- {
- return this.Selector2.PercentageValue;
- }
- }
- private get Maximum(): number
- {
- if (this.Selector1.PercentageValue > this.Selector2.PercentageValue)
- {
- return this.Selector1.PercentageValue;
- }
- else
- {
- return this.Selector2.PercentageValue;
- }
- }
- private get BarRangeStyle(): any
- {
- return {
- 'left': (this.Minimum * 100) + '%',
- 'width': ((Math.abs(this.Selector1.PercentageValue - this.Selector2.PercentageValue)) * 100) + '%'
- };
- }
- }
- class Selector
- {
- PercentageValue: number = 0;
- Drag: boolean = false;
- OldX: number = 0;
- }
- interface Value
- {
- min: number;
- max: number;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement