feat: Add IP Adapter Begin & End Percent to Linear UI

This commit is contained in:
blessedcoolant 2023-09-17 11:53:05 +12:00
parent c48e648cbb
commit 7be5743011
5 changed files with 165 additions and 25 deletions

View File

@ -1,5 +1,6 @@
import { Flex } from '@chakra-ui/react';
import { memo } from 'react';
import ParamIPAdapterBeginEnd from './ParamIPAdapterBeginEnd';
import ParamIPAdapterFeatureToggle from './ParamIPAdapterFeatureToggle';
import ParamIPAdapterImage from './ParamIPAdapterImage';
import ParamIPAdapterModelSelect from './ParamIPAdapterModelSelect';
@ -26,6 +27,7 @@ const IPAdapterPanel = () => {
<ParamIPAdapterImage />
<ParamIPAdapterModelSelect />
<ParamIPAdapterWeight />
<ParamIPAdapterBeginEnd />
</Flex>
);
};

View File

@ -0,0 +1,100 @@
import {
FormControl,
FormLabel,
HStack,
RangeSlider,
RangeSliderFilledTrack,
RangeSliderMark,
RangeSliderThumb,
RangeSliderTrack,
Tooltip,
} from '@chakra-ui/react';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import {
ipAdapterBeginStepPctChanged,
ipAdapterEndStepPctChanged,
} from 'features/controlNet/store/controlNetSlice';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const formatPct = (v: number) => `${Math.round(v * 100)}%`;
const ParamIPAdapterBeginEnd = () => {
const isEnabled = useAppSelector(
(state: RootState) => state.controlNet.isIPAdapterEnabled
);
const beginStepPct = useAppSelector(
(state: RootState) => state.controlNet.ipAdapterInfo.beginStepPct
);
const endStepPct = useAppSelector(
(state: RootState) => state.controlNet.ipAdapterInfo.endStepPct
);
const dispatch = useAppDispatch();
const { t } = useTranslation();
const handleStepPctChanged = useCallback(
(v: number[]) => {
dispatch(ipAdapterBeginStepPctChanged(v[0] as number));
dispatch(ipAdapterEndStepPctChanged(v[1] as number));
},
[dispatch]
);
return (
<FormControl isDisabled={!isEnabled}>
<FormLabel>{t('controlnet.beginEndStepPercent')}</FormLabel>
<HStack w="100%" gap={2} alignItems="center">
<RangeSlider
aria-label={['Begin Step %', 'End Step %!']}
value={[beginStepPct, endStepPct]}
onChange={handleStepPctChanged}
min={0}
max={1}
step={0.01}
minStepsBetweenThumbs={5}
isDisabled={!isEnabled}
>
<RangeSliderTrack>
<RangeSliderFilledTrack />
</RangeSliderTrack>
<Tooltip label={formatPct(beginStepPct)} placement="top" hasArrow>
<RangeSliderThumb index={0} />
</Tooltip>
<Tooltip label={formatPct(endStepPct)} placement="top" hasArrow>
<RangeSliderThumb index={1} />
</Tooltip>
<RangeSliderMark
value={0}
sx={{
insetInlineStart: '0 !important',
insetInlineEnd: 'unset !important',
}}
>
0%
</RangeSliderMark>
<RangeSliderMark
value={0.5}
sx={{
insetInlineStart: '50% !important',
transform: 'translateX(-50%)',
}}
>
50%
</RangeSliderMark>
<RangeSliderMark
value={1}
sx={{
insetInlineStart: 'unset !important',
insetInlineEnd: '0 !important',
}}
>
100%
</RangeSliderMark>
</RangeSlider>
</HStack>
</FormControl>
);
};
export default memo(ParamIPAdapterBeginEnd);

View File

@ -64,6 +64,8 @@ export type IPAdapterConfig = {
adapterImage: ImageDTO | null;
model: IPAdapterModelParam | null;
weight: number;
beginStepPct: number;
endStepPct: number;
};
export type ControlNetState = {
@ -78,6 +80,8 @@ export const initialIPAdapterState: IPAdapterConfig = {
adapterImage: null,
model: null,
weight: 1,
beginStepPct: 0,
endStepPct: 1,
};
export const initialControlNetState: ControlNetState = {
@ -388,6 +392,12 @@ export const controlNetSlice = createSlice({
) => {
state.ipAdapterInfo.model = action.payload;
},
ipAdapterBeginStepPctChanged: (state, action: PayloadAction<number>) => {
state.ipAdapterInfo.beginStepPct = action.payload;
},
ipAdapterEndStepPctChanged: (state, action: PayloadAction<number>) => {
state.ipAdapterInfo.endStepPct = action.payload;
},
ipAdapterStateReset: (state) => {
state.isIPAdapterEnabled = false;
state.ipAdapterInfo = { ...initialIPAdapterState };
@ -455,6 +465,8 @@ export const {
ipAdapterImageChanged,
ipAdapterWeightChanged,
ipAdapterModelChanged,
ipAdapterBeginStepPctChanged,
ipAdapterEndStepPctChanged,
ipAdapterStateReset,
} = controlNetSlice.actions;

View File

@ -14,16 +14,18 @@ export const addIPAdapterToLinearGraph = (
// | MetadataAccumulatorInvocation
// | undefined;
if (isIPAdapterEnabled) {
if (isIPAdapterEnabled && ipAdapterInfo.model) {
const ipAdapterNode: IPAdapterInvocation = {
id: IP_ADAPTER,
type: 'ip_adapter',
is_intermediate: true,
weight: ipAdapterInfo.weight,
ip_adapter_model: {
base_model: 'sd-1',
model_name: 'ip_adapter_plus_sd15',
base_model: ipAdapterInfo.model?.base_model,
model_name: ipAdapterInfo.model?.model_name,
},
begin_step_percent: ipAdapterInfo.beginStepPct,
end_step_percent: ipAdapterInfo.endStepPct,
};
if (ipAdapterInfo.adapterImage) {

View File

@ -2564,10 +2564,22 @@ export type components = {
image_encoder_model: components["schemas"]["CLIPVisionModelField"];
/**
* Weight
* @description The weight of the IP-Adapter.
* @description The weight given to the ControlNet
* @default 1
*/
weight?: number;
weight?: number | number[];
/**
* Begin Step Percent
* @description When the IP-Adapter is first applied (% of total steps)
* @default 0
*/
begin_step_percent?: number;
/**
* End Step Percent
* @description When the IP-Adapter is last applied (% of total steps)
* @default 1
*/
end_step_percent?: number;
};
/**
* IP-Adapter
@ -2602,10 +2614,22 @@ export type components = {
ip_adapter_model: components["schemas"]["IPAdapterModelField"];
/**
* Weight
* @description The weight of the IP-Adapter.
* @description The weight given to the IP-Adapter
* @default 1
*/
weight?: number;
weight?: number | number[];
/**
* Begin Step Percent
* @description When the IP-Adapter is first applied (% of total steps)
* @default 0
*/
begin_step_percent?: number;
/**
* End Step Percent
* @description When the IP-Adapter is last applied (% of total steps)
* @default 1
*/
end_step_percent?: number;
/**
* Type
* @default ip_adapter
@ -7706,18 +7730,6 @@ export type components = {
/** Ui Order */
ui_order?: number;
};
/**
* CLIPVisionModelFormat
* @description An enumeration.
* @enum {string}
*/
CLIPVisionModelFormat: "diffusers";
/**
* StableDiffusion2ModelFormat
* @description An enumeration.
* @enum {string}
*/
StableDiffusion2ModelFormat: "checkpoint" | "diffusers";
/**
* StableDiffusionXLModelFormat
* @description An enumeration.
@ -7725,17 +7737,17 @@ export type components = {
*/
StableDiffusionXLModelFormat: "checkpoint" | "diffusers";
/**
* ControlNetModelFormat
* StableDiffusionOnnxModelFormat
* @description An enumeration.
* @enum {string}
*/
ControlNetModelFormat: "checkpoint" | "diffusers";
StableDiffusionOnnxModelFormat: "olive" | "onnx";
/**
* IPAdapterModelFormat
* CLIPVisionModelFormat
* @description An enumeration.
* @enum {string}
*/
IPAdapterModelFormat: "invokeai";
CLIPVisionModelFormat: "diffusers";
/**
* StableDiffusion1ModelFormat
* @description An enumeration.
@ -7743,11 +7755,23 @@ export type components = {
*/
StableDiffusion1ModelFormat: "checkpoint" | "diffusers";
/**
* StableDiffusionOnnxModelFormat
* IPAdapterModelFormat
* @description An enumeration.
* @enum {string}
*/
StableDiffusionOnnxModelFormat: "olive" | "onnx";
IPAdapterModelFormat: "invokeai";
/**
* StableDiffusion2ModelFormat
* @description An enumeration.
* @enum {string}
*/
StableDiffusion2ModelFormat: "checkpoint" | "diffusers";
/**
* ControlNetModelFormat
* @description An enumeration.
* @enum {string}
*/
ControlNetModelFormat: "checkpoint" | "diffusers";
};
responses: never;
parameters: never;