UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

183 lines (173 loc) 5.67 kB
import {Number3, StringOrNumber3} from '../../types/GlobalTypes'; import {TypedMultipleParam} from './_Multiple'; import {Color} from 'three'; import {ParamType} from '../poly/ParamType'; import {FloatParam} from './Float'; import {ParamValuesTypeMap} from './types/ParamValuesTypeMap'; import {ParamInitValuesTypeMap} from './types/ParamInitValuesTypeMap'; import {ColorConversion} from '../../core/Color'; import {TypeAssert} from '../poly/Assert'; import {isArray} from '../../core/Type'; const COMPONENT_NAMES_COLOR: Readonly<string[]> = ['r', 'g', 'b']; const tmp: Number3 = [0, 0, 0]; function colorEqualsStringNumber3(c: Color, array: StringOrNumber3): boolean { return c.r == array[0] && c.g == array[1] && c.b == array[2]; } function stringNumber3Equals(array1: StringOrNumber3, array2: StringOrNumber3): boolean { return array1[0] == array2[0] && array1[1] == array2[1] && array1[2] == array2[2]; } export class ColorParam extends TypedMultipleParam<ParamType.COLOR> { protected override _value = new Color(); private _valuePreConversion = new Color(); private _valueSerializedDirty: boolean = false; private _valueSerialized: Number3 = [0, 0, 0]; private _valuePreConversionSerialized: Number3 = [0, 0, 0]; r!: FloatParam; g!: FloatParam; b!: FloatParam; static override type() { return ParamType.COLOR; } override componentNames(): Readonly<string[]> { return COMPONENT_NAMES_COLOR; } override defaultValueSerialized() { if (isArray(this._default_value)) { return this._default_value; } else { return this._default_value.toArray() as Number3; } } override _prefilterInvalidRawInput(rawInput: any) { if (rawInput instanceof Color) { rawInput.toArray(tmp); return tmp; } return super._prefilterInvalidRawInput(rawInput); } // rawInputSerialized() { // if (this._raw_input instanceof Color) { // return this._raw_input.toArray() as Number3; // } else { // const new_array: StringOrNumber3 = [this._raw_input[0], this._raw_input[1], this._raw_input[2]]; // return new_array; // } // } override valueSerialized() { this._updateValueSerializedIfRequired(); return this._valueSerialized; } override valuePreConversionSerialized() { this._updateValueSerializedIfRequired(); return this._valuePreConversionSerialized; } private _copiedValue: Number3 = [0, 0, 0]; protected override _copyValue(param: ColorParam) { param.value.toArray(this._copiedValue); this.set(this._copiedValue); } // protected _prefilterInvalidRawInput( // raw_input: ParamInitValuesTypeMap[ParamType.COLOR] // ): ParamInitValuesTypeMap[ParamType.COLOR] { // return raw_input; // } protected override _cloneRawInput(raw_input: ParamInitValuesTypeMap[ParamType.COLOR]) { if (raw_input instanceof Color) { return raw_input.clone(); } else { const new_array: StringOrNumber3 = [raw_input[0], raw_input[1], raw_input[2]]; // in case array elements are undefined if (new_array[0] == null) { new_array[0] = new_array[0] || 0; } if (new_array[1] == null) { new_array[1] = new_array[1] || new_array[0]; } if (new_array[2] == null) { new_array[2] = new_array[2] || new_array[1]; } return new_array; } } static override areRawInputEqual( raw_input1: ParamInitValuesTypeMap[ParamType.COLOR], raw_input2: ParamInitValuesTypeMap[ParamType.COLOR] ) { if (raw_input1 instanceof Color) { if (raw_input2 instanceof Color) { return raw_input1.equals(raw_input2); } else { return colorEqualsStringNumber3(raw_input1, raw_input2); } } else { if (raw_input2 instanceof Color) { return colorEqualsStringNumber3(raw_input2, raw_input1); } else { return stringNumber3Equals(raw_input1, raw_input2); } } } static override areValuesEqual( val1: ParamValuesTypeMap[ParamType.COLOR], val2: ParamValuesTypeMap[ParamType.COLOR] ) { return val1.equals(val2); } override initComponents() { super.initComponents(); this.r = this.components[0]; this.g = this.components[1]; this.b = this.components[2]; this._valueSerializedDirty = true; // this.options.onOptionChange('conversion', () => { // this.setValueFromComponents(); // }); } override postOptionsInitialize() { this.setValueFromComponents(); } private _updateValueSerializedIfRequired() { if (!this._valueSerializedDirty) { return; } this._valueSerialized[0] = this._value.r; this._valueSerialized[1] = this._value.g; this._valueSerialized[2] = this._value.b; this._valuePreConversionSerialized[0] = this._valuePreConversion.r; this._valuePreConversionSerialized[1] = this._valuePreConversion.g; this._valuePreConversionSerialized[2] = this._valuePreConversion.b; } valuePreConversion() { return this._valuePreConversion; } async setConversion(conversion: ColorConversion) { this.options.setOption('conversion', conversion); this.setDirty(); // to ensure value is recomputed await this.options.executeCallback(); } override setValueFromComponents() { this._valuePreConversion.r = this.r.value; this._valuePreConversion.g = this.g.value; this._valuePreConversion.b = this.b.value; this._value.copy(this._valuePreConversion); this._applyColorConversion(); this._valueSerializedDirty = true; } private _applyColorConversion() { const conversion = this.options.colorConversion(); switch (conversion) { case ColorConversion.NONE: { return; } case ColorConversion.SRGB_TO_LINEAR: { this._value.convertSRGBToLinear(); return; } case ColorConversion.LINEAR_TO_SRGB: { this._value.convertLinearToSRGB(); return; } } TypeAssert.unreachable(conversion); } }