mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
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:
parent
52e07db06b
commit
fb50a221f8
@ -1,31 +1,47 @@
|
|||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import { fieldColorValueChanged } from 'features/nodes/store/nodesSlice';
|
import { fieldColorValueChanged } from 'features/nodes/store/nodesSlice';
|
||||||
import type { ColorFieldInputInstance, ColorFieldInputTemplate } from 'features/nodes/types/field';
|
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 type { RgbaColor } from 'react-colorful';
|
||||||
import { RgbaColorPicker } from 'react-colorful';
|
import { RgbaColorPicker } from 'react-colorful';
|
||||||
|
|
||||||
import type { FieldComponentProps } from './types';
|
import type { FieldComponentProps } from './types';
|
||||||
|
|
||||||
|
const FALLBACK_COLOR: RgbaColor = { r: 0, g: 0, b: 0, a: 255 };
|
||||||
|
|
||||||
const ColorFieldInputComponent = (props: FieldComponentProps<ColorFieldInputInstance, ColorFieldInputTemplate>) => {
|
const ColorFieldInputComponent = (props: FieldComponentProps<ColorFieldInputInstance, ColorFieldInputTemplate>) => {
|
||||||
const { nodeId, field } = props;
|
const { nodeId, field } = props;
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
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(
|
const handleValueChanged = useCallback(
|
||||||
(value: RgbaColor) => {
|
(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(
|
dispatch(
|
||||||
fieldColorValueChanged({
|
fieldColorValueChanged({
|
||||||
nodeId,
|
nodeId,
|
||||||
fieldName: field.name,
|
fieldName: field.name,
|
||||||
value,
|
value: { r, g, b, a },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[dispatch, field.name, nodeId]
|
[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);
|
export default memo(ColorFieldInputComponent);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import type { NodesState } from 'features/nodes/store/types';
|
import type { NodesState } from 'features/nodes/store/types';
|
||||||
import type { FieldInputInstance } from 'features/nodes/types/field';
|
import type { FieldInputInstance } from 'features/nodes/types/field';
|
||||||
import { isColorFieldInputInstance } from 'features/nodes/types/field';
|
|
||||||
import { isInvocationNode } from 'features/nodes/types/invocation';
|
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 { Graph } from 'services/api/types';
|
||||||
import type { AnyInvocation } from 'services/events/types';
|
import type { AnyInvocation } from 'services/events/types';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
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
|
* We need to do special handling for some fields
|
||||||
*/
|
*/
|
||||||
export const parseFieldValue = (field: FieldInputInstance) => {
|
export const parseFieldValue = (field: FieldInputInstance) => {
|
||||||
if (isColorFieldInputInstance(field)) {
|
// Currently, no special handling is needed.
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return field.value;
|
return field.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user