mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat: Add IP Adapter Begin & End Percent to Linear UI
This commit is contained in:
parent
c48e648cbb
commit
7be5743011
@ -1,5 +1,6 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
import ParamIPAdapterBeginEnd from './ParamIPAdapterBeginEnd';
|
||||||
import ParamIPAdapterFeatureToggle from './ParamIPAdapterFeatureToggle';
|
import ParamIPAdapterFeatureToggle from './ParamIPAdapterFeatureToggle';
|
||||||
import ParamIPAdapterImage from './ParamIPAdapterImage';
|
import ParamIPAdapterImage from './ParamIPAdapterImage';
|
||||||
import ParamIPAdapterModelSelect from './ParamIPAdapterModelSelect';
|
import ParamIPAdapterModelSelect from './ParamIPAdapterModelSelect';
|
||||||
@ -26,6 +27,7 @@ const IPAdapterPanel = () => {
|
|||||||
<ParamIPAdapterImage />
|
<ParamIPAdapterImage />
|
||||||
<ParamIPAdapterModelSelect />
|
<ParamIPAdapterModelSelect />
|
||||||
<ParamIPAdapterWeight />
|
<ParamIPAdapterWeight />
|
||||||
|
<ParamIPAdapterBeginEnd />
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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);
|
@ -64,6 +64,8 @@ export type IPAdapterConfig = {
|
|||||||
adapterImage: ImageDTO | null;
|
adapterImage: ImageDTO | null;
|
||||||
model: IPAdapterModelParam | null;
|
model: IPAdapterModelParam | null;
|
||||||
weight: number;
|
weight: number;
|
||||||
|
beginStepPct: number;
|
||||||
|
endStepPct: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ControlNetState = {
|
export type ControlNetState = {
|
||||||
@ -78,6 +80,8 @@ export const initialIPAdapterState: IPAdapterConfig = {
|
|||||||
adapterImage: null,
|
adapterImage: null,
|
||||||
model: null,
|
model: null,
|
||||||
weight: 1,
|
weight: 1,
|
||||||
|
beginStepPct: 0,
|
||||||
|
endStepPct: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initialControlNetState: ControlNetState = {
|
export const initialControlNetState: ControlNetState = {
|
||||||
@ -388,6 +392,12 @@ export const controlNetSlice = createSlice({
|
|||||||
) => {
|
) => {
|
||||||
state.ipAdapterInfo.model = action.payload;
|
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) => {
|
ipAdapterStateReset: (state) => {
|
||||||
state.isIPAdapterEnabled = false;
|
state.isIPAdapterEnabled = false;
|
||||||
state.ipAdapterInfo = { ...initialIPAdapterState };
|
state.ipAdapterInfo = { ...initialIPAdapterState };
|
||||||
@ -455,6 +465,8 @@ export const {
|
|||||||
ipAdapterImageChanged,
|
ipAdapterImageChanged,
|
||||||
ipAdapterWeightChanged,
|
ipAdapterWeightChanged,
|
||||||
ipAdapterModelChanged,
|
ipAdapterModelChanged,
|
||||||
|
ipAdapterBeginStepPctChanged,
|
||||||
|
ipAdapterEndStepPctChanged,
|
||||||
ipAdapterStateReset,
|
ipAdapterStateReset,
|
||||||
} = controlNetSlice.actions;
|
} = controlNetSlice.actions;
|
||||||
|
|
||||||
|
@ -14,16 +14,18 @@ export const addIPAdapterToLinearGraph = (
|
|||||||
// | MetadataAccumulatorInvocation
|
// | MetadataAccumulatorInvocation
|
||||||
// | undefined;
|
// | undefined;
|
||||||
|
|
||||||
if (isIPAdapterEnabled) {
|
if (isIPAdapterEnabled && ipAdapterInfo.model) {
|
||||||
const ipAdapterNode: IPAdapterInvocation = {
|
const ipAdapterNode: IPAdapterInvocation = {
|
||||||
id: IP_ADAPTER,
|
id: IP_ADAPTER,
|
||||||
type: 'ip_adapter',
|
type: 'ip_adapter',
|
||||||
is_intermediate: true,
|
is_intermediate: true,
|
||||||
weight: ipAdapterInfo.weight,
|
weight: ipAdapterInfo.weight,
|
||||||
ip_adapter_model: {
|
ip_adapter_model: {
|
||||||
base_model: 'sd-1',
|
base_model: ipAdapterInfo.model?.base_model,
|
||||||
model_name: 'ip_adapter_plus_sd15',
|
model_name: ipAdapterInfo.model?.model_name,
|
||||||
},
|
},
|
||||||
|
begin_step_percent: ipAdapterInfo.beginStepPct,
|
||||||
|
end_step_percent: ipAdapterInfo.endStepPct,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ipAdapterInfo.adapterImage) {
|
if (ipAdapterInfo.adapterImage) {
|
||||||
|
@ -2564,10 +2564,22 @@ export type components = {
|
|||||||
image_encoder_model: components["schemas"]["CLIPVisionModelField"];
|
image_encoder_model: components["schemas"]["CLIPVisionModelField"];
|
||||||
/**
|
/**
|
||||||
* Weight
|
* Weight
|
||||||
* @description The weight of the IP-Adapter.
|
* @description The weight given to the ControlNet
|
||||||
* @default 1
|
* @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
|
* IP-Adapter
|
||||||
@ -2602,10 +2614,22 @@ export type components = {
|
|||||||
ip_adapter_model: components["schemas"]["IPAdapterModelField"];
|
ip_adapter_model: components["schemas"]["IPAdapterModelField"];
|
||||||
/**
|
/**
|
||||||
* Weight
|
* Weight
|
||||||
* @description The weight of the IP-Adapter.
|
* @description The weight given to the IP-Adapter
|
||||||
* @default 1
|
* @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
|
* Type
|
||||||
* @default ip_adapter
|
* @default ip_adapter
|
||||||
@ -7706,18 +7730,6 @@ export type components = {
|
|||||||
/** Ui Order */
|
/** Ui Order */
|
||||||
ui_order?: number;
|
ui_order?: number;
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* CLIPVisionModelFormat
|
|
||||||
* @description An enumeration.
|
|
||||||
* @enum {string}
|
|
||||||
*/
|
|
||||||
CLIPVisionModelFormat: "diffusers";
|
|
||||||
/**
|
|
||||||
* StableDiffusion2ModelFormat
|
|
||||||
* @description An enumeration.
|
|
||||||
* @enum {string}
|
|
||||||
*/
|
|
||||||
StableDiffusion2ModelFormat: "checkpoint" | "diffusers";
|
|
||||||
/**
|
/**
|
||||||
* StableDiffusionXLModelFormat
|
* StableDiffusionXLModelFormat
|
||||||
* @description An enumeration.
|
* @description An enumeration.
|
||||||
@ -7725,17 +7737,17 @@ export type components = {
|
|||||||
*/
|
*/
|
||||||
StableDiffusionXLModelFormat: "checkpoint" | "diffusers";
|
StableDiffusionXLModelFormat: "checkpoint" | "diffusers";
|
||||||
/**
|
/**
|
||||||
* ControlNetModelFormat
|
* StableDiffusionOnnxModelFormat
|
||||||
* @description An enumeration.
|
* @description An enumeration.
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
ControlNetModelFormat: "checkpoint" | "diffusers";
|
StableDiffusionOnnxModelFormat: "olive" | "onnx";
|
||||||
/**
|
/**
|
||||||
* IPAdapterModelFormat
|
* CLIPVisionModelFormat
|
||||||
* @description An enumeration.
|
* @description An enumeration.
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
IPAdapterModelFormat: "invokeai";
|
CLIPVisionModelFormat: "diffusers";
|
||||||
/**
|
/**
|
||||||
* StableDiffusion1ModelFormat
|
* StableDiffusion1ModelFormat
|
||||||
* @description An enumeration.
|
* @description An enumeration.
|
||||||
@ -7743,11 +7755,23 @@ export type components = {
|
|||||||
*/
|
*/
|
||||||
StableDiffusion1ModelFormat: "checkpoint" | "diffusers";
|
StableDiffusion1ModelFormat: "checkpoint" | "diffusers";
|
||||||
/**
|
/**
|
||||||
* StableDiffusionOnnxModelFormat
|
* IPAdapterModelFormat
|
||||||
* @description An enumeration.
|
* @description An enumeration.
|
||||||
* @enum {string}
|
* @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;
|
responses: never;
|
||||||
parameters: never;
|
parameters: never;
|
||||||
|
Loading…
Reference in New Issue
Block a user