import is from '@pilotlab/is'; import { IAnimationEaseFunction } from '@pilotlab/animation'; import { Signal } from '@pilotlab/signals'; import RangeScale from './rangeScale'; import RangeScaleBase from './rangeScaleBase'; export class RangeScaleManager extends RangeScaleBase { /** * Provides methods to scale between an input range and an output range. * Multiple output ranges can be added and scaled to a single input range. * @param inputMin * @param inputMax * @param ease - An easing function can be provided to allow smooth modulated scaling from one range to the other. */ constructor(inputMin:number = 0, inputMax:number = 1, ease?:IAnimationEaseFunction) { super(inputMin, inputMax, ease); } /*--------------------------------------------------------------------* START: Properties *--------------------------------------------------------------------*/ get outputRanges():Map { return this._outputRanges; } private _outputRanges:Map = new Map(); /*--------------------------------------------------------------------* START: Signals *--------------------------------------------------------------------*/ updated:Signal = new Signal(); /*--------------------------------------------------------------------* START: Public Methods *--------------------------------------------------------------------*/ addOutputRange(name:string, outputMin:number, outputMax:number):RangeScale { let interpolatorValue:RangeScale = new RangeScale( this.p_inputMin, this.p_inputMax, outputMin, outputMax, this.p_ease ); this._outputRanges.set(name, interpolatorValue); return interpolatorValue; } update(inputValue:number, isValueNormalized:boolean = false):void { //----- Make sure we have a raw (not normalized or constrained) input value to work with. if (isValueNormalized) inputValue = this.unnormalizeInput(inputValue, false); if (inputValue === this.p_lastInputRaw) return; this.p_lastInputRaw = inputValue; this.p_lastInputNormalized = this.normalizeInput(inputValue); this.p_checkInputPreviousRaw(inputValue); //----- Update all the managed range scalers. this._outputRanges.forEach((scalerValues:RangeScale, name:string):boolean => { scalerValues.output(inputValue, false, false, false, false); return true; }); this.updated.dispatch(this.progress); } output( name:string, isConstrain:boolean = true, isNormalizeReturnValue:boolean = false, isInvertReturnValue:boolean = false ):number { let scaler:RangeScale = this._outputRanges.get(name); if (is.empty(scaler)) return null; let returnValue:number = scaler.normalizeOutput(scaler.value, isConstrain, isInvertReturnValue); if (isNormalizeReturnValue) return returnValue; else return scaler.unnormalizeOutput(returnValue, false, false); } } // End of class export default RangeScaleManager;