fix(ui): fix color input field alpha

Closes #5647

The alpha values in the UI are `0-1` but the backend wants `0-255`.

Previously, this was handled in `parseFIeldValue` when building the graph. In a recent release, field types were refactored and broke the alpha handling.

The logic for handling alpha values is moved into `ColorFieldInputComponent`, and `parseFieldValue` now just does no value transformations.

Though it would be a minor change, I'm leaving this function in because I don't want to change the rest of the logic except when necessary.
This commit is contained in:
psychedelicious 2024-02-04 17:51:08 +11:00
parent 52e07db06b
commit fb50a221f8
2 changed files with 21 additions and 20 deletions

View File

@ -1,31 +1,47 @@
import { useAppDispatch } from 'app/store/storeHooks';
import { fieldColorValueChanged } from 'features/nodes/store/nodesSlice';
import type { ColorFieldInputInstance, ColorFieldInputTemplate } from 'features/nodes/types/field';
import { memo, useCallback } from 'react';
import { memo, useCallback, useMemo } from 'react';
import type { RgbaColor } from 'react-colorful';
import { RgbaColorPicker } from 'react-colorful';
import type { FieldComponentProps } from './types';
const FALLBACK_COLOR: RgbaColor = { r: 0, g: 0, b: 0, a: 255 };
const ColorFieldInputComponent = (props: FieldComponentProps<ColorFieldInputInstance, ColorFieldInputTemplate>) => {
const { nodeId, field } = props;
const dispatch = useAppDispatch();
const color = useMemo(() => {
// For better or worse, zColorFieldValue is typed as optional. This means that `field.value` and `fieldTemplate.default`
// can be undefined. Rather than changing the schema (which could have other consequences), we can just provide a fallback.
if (!field.value) {
return FALLBACK_COLOR;
}
const { r, g, b, a } = field.value;
// We need to divide by 255 to convert from 0-255 to 0-1, which is what the UI component needs
return { r, g, b, a: a / 255 };
}, [field.value]);
const handleValueChanged = useCallback(
(value: RgbaColor) => {
// We need to multiply by 255 to convert from 0-1 to 0-255, which is what the backend needs
const { r, g, b, a: _a } = value;
const a = Math.round(_a * 255);
dispatch(
fieldColorValueChanged({
nodeId,
fieldName: field.name,
value,
value: { r, g, b, a },
})
);
},
[dispatch, field.name, nodeId]
);
return <RgbaColorPicker className="nodrag" color={field.value} onChange={handleValueChanged} />;
return <RgbaColorPicker className="nodrag" color={color} onChange={handleValueChanged} />;
};
export default memo(ColorFieldInputComponent);

View File

@ -1,8 +1,7 @@
import type { NodesState } from 'features/nodes/store/types';
import type { FieldInputInstance } from 'features/nodes/types/field';
import { isColorFieldInputInstance } from 'features/nodes/types/field';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { cloneDeep, omit, reduce } from 'lodash-es';
import { omit, reduce } from 'lodash-es';
import type { Graph } from 'services/api/types';
import type { AnyInvocation } from 'services/events/types';
import { v4 as uuidv4 } from 'uuid';
@ -11,21 +10,7 @@ import { v4 as uuidv4 } from 'uuid';
* We need to do special handling for some fields
*/
export const parseFieldValue = (field: FieldInputInstance) => {
if (isColorFieldInputInstance(field)) {
if (field.value) {
const clonedValue = cloneDeep(field.value);
const { r, g, b, a } = field.value;
// scale alpha value to PIL's desired range 0-255
const scaledAlpha = Math.max(0, Math.min(a * 255, 255));
const transformedColor = { r, g, b, a: scaledAlpha };
Object.assign(clonedValue, transformedColor);
return clonedValue;
}
}
// Currently, no special handling is needed.
return field.value;
};