@pilotlab/lux-tools
Version:
A luxurious user experience framework, developed by your friends at Pilot.
162 lines (122 loc) • 5.91 kB
text/typescript
import is from '@pilotlab/is';
import { IAnimationEaseFunction } from '@pilotlab/animation';
import RangeScaleBase from './rangeScaleBase';
export class RangeScale extends RangeScaleBase {
constructor(
inputMin:number = 0, inputMax:number = 1,
outputMin:number = 0, outputMax:number = 1,
ease?:IAnimationEaseFunction
) {
super(inputMin, inputMax, ease);
let isInvert:boolean = outputMin > outputMax;
let outputMinFinal:number = isInvert ? outputMax : outputMin;
let outputMaxFinal:number = isInvert ? outputMin : outputMax;
if (is.notEmpty(outputMinFinal)) this._outputMin = outputMinFinal;
if (is.notEmpty(outputMaxFinal)) this._outputMax = outputMaxFinal;
this._isInvert = isInvert;
}
/*--------------------------------------------------------------------*
START: Static Methods
*--------------------------------------------------------------------*/
/**
* Returns the relative position of the input value
* within the min/max range as a value between 0.0 and 1.0.
*/
static normalize(value:number, min:number, max:number, isConstrain:boolean = true, isInvert:boolean = false):number {
let p:number = (value - min) / (max - min);
if (isConstrain) {
if (p < 0) p = 0;
if (p > 1) p = 1;
}
if (isInvert) p = 1.0 - p;
return p;
}
/**
* Accepts a value between 0.0 and 1.0 and returns the input value at the corresponding
* progress point within the min/max input range.
*/
static unnormalize(valueNormalized:number, min:number, max:number, isConstrain:boolean = true, isInvert:boolean = false):number {
let p:number = valueNormalized;
if (isConstrain) {
if (p < 0) p = 0;
if (p > 1) p = 1;
}
if (isInvert) p = 1.0 - p;
return (min + (p * (max - min)));
}
static outputEase(value:number, min:number, max:number, ease:IAnimationEaseFunction):number {
if (min > max) return ease(value - min, max, min - max, max - min);
else return ease(value - min, min, max - min, max - min);
}
static easeNormalized(value:number, ease:IAnimationEaseFunction, isInvert:boolean = false):number {
if (isInvert) value = 1.0 - value;
return ease(value, 0, 1, 1);
}
/*--------------------------------------------------------------------*
START: Properties
*--------------------------------------------------------------------*/
get outputMin():number { return this._outputMin; }
set outputMin(value:number) { this._outputMin = value; }
private _outputMin:number = 0.0;
get outputMax():number { return this._outputMax; }
set outputMax(value:number) { this._outputMax = value; }
private _outputMax:number = 0.0;
get isInvert():boolean { return this._isInvert; }
set isInvert(value:boolean) { this._isInvert = value; }
private _isInvert:boolean = false;
get value():number { return this._value; }
private _value:number;
/*--------------------------------------------------------------------*
START: Public Methods
*--------------------------------------------------------------------*/
output(
inputValue:number,
isValueNormalized:boolean = false,
isConstrain:boolean = true,
isNormalizeReturnValue:boolean = false,
isInvertReturnValue:boolean = false
):number {
//----- 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._value;
this.p_lastInputRaw = inputValue;
this.p_checkInputPreviousRaw(inputValue);
//----- Now get the raw, unconstrained output value.
let p:number = this.normalizeInput(inputValue, false);
let value:number = this._outputFromNormalized(p);
//----- Find the return value.
value = this.normalizeOutput(value, isConstrain, isInvertReturnValue);
if (is.notEmpty(this.p_ease)) value = RangeScale.easeNormalized(value, this.p_ease);
if (this._isInvert) value = 1.0 - value;
this.p_lastInputNormalized = value;
if (!isNormalizeReturnValue) value = this.unnormalizeOutput(value);
//----- Store the value for possible later retrieval.
this._value = value;
return value
}
/*--------------------------------------------------------------------*
START: Public Methods
*--------------------------------------------------------------------*/
/**
* Returns the relative position of the output value
* within the min/max range as a value between 0.0 and 1.0.
*/
normalizeOutput(outputUnnormalized:number, isConstrain:boolean = true, isInvert:boolean = false):number {
return RangeScale.normalize(outputUnnormalized, this._outputMin, this._outputMax, isConstrain, isInvert);
}
/**
* Accepts a value between 0.0 and 1.0 and returns the output value
* at the corresponding progress point within the min/max input range.
*/
unnormalizeOutput(outputNormalized:number, isConstrain:boolean = true, isInvert:boolean = false):number {
return RangeScale.unnormalize(outputNormalized, this._outputMin, this._outputMax, isConstrain, isInvert);
}
/*--------------------------------------------------------------------*
START: Private Methods
*--------------------------------------------------------------------*/
private _outputFromNormalized(inputNormalized:number):number {
let p:number = inputNormalized;
return (this._outputMin + (p * (this._outputMax - this._outputMin)));
}
} // End class
export default RangeScale;