@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
183 lines (173 loc) • 5.67 kB
text/typescript
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);
}
}