mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): rough out regional prompts components
This commit is contained in:
parent
1d1e4d02dc
commit
f87eee810b
@ -0,0 +1,23 @@
|
||||
import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
||||
import { useTransform } from 'features/regionalPrompts/hooks/useTransform';
|
||||
import type { LineObject } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
import { Line } from 'react-konva';
|
||||
|
||||
type Props = {
|
||||
line: LineObject;
|
||||
};
|
||||
|
||||
export const LineComponent = ({ line }: Props) => {
|
||||
const { shapeRef } = useTransform(line);
|
||||
|
||||
return (
|
||||
<Line
|
||||
ref={shapeRef}
|
||||
key={line.id}
|
||||
points={line.points}
|
||||
stroke={rgbaColorToString(line.color)}
|
||||
strokeWidth={line.strokeWidth}
|
||||
draggable
|
||||
/>
|
||||
);
|
||||
};
|
@ -0,0 +1,25 @@
|
||||
import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
||||
import { useTransform } from 'features/regionalPrompts/hooks/useTransform';
|
||||
import type { FillRectObject } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
import { Rect } from 'react-konva';
|
||||
|
||||
type Props = {
|
||||
rect: FillRectObject;
|
||||
};
|
||||
|
||||
export const RectComponent = ({ rect }: Props) => {
|
||||
const { shapeRef } = useTransform(rect);
|
||||
|
||||
return (
|
||||
<Rect
|
||||
ref={shapeRef}
|
||||
key={rect.id}
|
||||
x={rect.x}
|
||||
y={rect.y}
|
||||
width={rect.width}
|
||||
height={rect.height}
|
||||
fill={rgbaColorToString(rect.color)}
|
||||
draggable
|
||||
/>
|
||||
);
|
||||
};
|
@ -0,0 +1,19 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { RegionalPromptsEditor } from 'features/regionalPrompts/components/RegionalPromptsEditor';
|
||||
|
||||
const meta: Meta<typeof RegionalPromptsEditor> = {
|
||||
title: 'Feature/RegionalPrompts',
|
||||
tags: ['autodocs'],
|
||||
component: RegionalPromptsEditor,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof RegionalPromptsEditor>;
|
||||
|
||||
const Component = () => {
|
||||
return <RegionalPromptsEditor />;
|
||||
};
|
||||
|
||||
export const Default: Story = {
|
||||
render: Component,
|
||||
};
|
@ -0,0 +1,25 @@
|
||||
import { Flex } from '@invoke-ai/ui-library';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { RegionalPromptsStage } from 'features/regionalPrompts/components/RegionalPromptsStage';
|
||||
import { layersSelectors, selectRegionalPromptsSlice } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
|
||||
const selectLayers = createSelector(selectRegionalPromptsSlice, (regionalPrompts) =>
|
||||
layersSelectors.selectAll(regionalPrompts)
|
||||
);
|
||||
|
||||
export const RegionalPromptsEditor = () => {
|
||||
const layers = useAppSelector(selectLayers);
|
||||
return (
|
||||
<Flex>
|
||||
<Flex flexBasis={1}>
|
||||
{layers.map((layer) => (
|
||||
<Flex key={layer.id}>{layer.prompt}</Flex>
|
||||
))}
|
||||
</Flex>
|
||||
<Flex flexBasis={1}>
|
||||
<RegionalPromptsStage />
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
@ -0,0 +1,39 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { LineComponent } from 'features/regionalPrompts/components/LineComponent';
|
||||
import { RectComponent } from 'features/regionalPrompts/components/RectComponent';
|
||||
import {
|
||||
layerObjectsSelectors,
|
||||
layersSelectors,
|
||||
selectRegionalPromptsSlice,
|
||||
} from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
import { memo } from 'react';
|
||||
import { Group, Layer, Stage } from 'react-konva';
|
||||
|
||||
const selectLayers = createSelector(selectRegionalPromptsSlice, (regionalPrompts) =>
|
||||
layersSelectors.selectAll(regionalPrompts)
|
||||
);
|
||||
|
||||
export const RegionalPromptsStage: React.FC = memo(() => {
|
||||
const layers = useAppSelector(selectLayers);
|
||||
return (
|
||||
<Stage width={window.innerWidth} height={window.innerHeight}>
|
||||
<Layer>
|
||||
{layers.map((layer) => (
|
||||
<Group key={layer.id}>
|
||||
{layerObjectsSelectors.selectAll(layer.objects).map((obj) => {
|
||||
if (obj.kind === 'line') {
|
||||
return <LineComponent key={obj.id} line={obj} />;
|
||||
}
|
||||
if (obj.kind === 'fillRect') {
|
||||
return <RectComponent key={obj.id} rect={obj} />;
|
||||
}
|
||||
})}
|
||||
</Group>
|
||||
))}
|
||||
</Layer>
|
||||
</Stage>
|
||||
);
|
||||
});
|
||||
|
||||
RegionalPromptsStage.displayName = 'RegionalPromptingEditor';
|
@ -0,0 +1,30 @@
|
||||
import type { FillRectObject, LayerObject, LineObject } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
import type { Image } from 'konva/lib/shapes/Image';
|
||||
import type { Line } from 'konva/lib/shapes/Line';
|
||||
import type { Rect } from 'konva/lib/shapes/Rect';
|
||||
import type { Transformer } from 'konva/lib/shapes/Transformer';
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
type ShapeType<T> = T extends LineObject ? Line : T extends FillRectObject ? Rect : Image;
|
||||
|
||||
export const useTransform = <TObject extends LayerObject>(object: TObject) => {
|
||||
const shapeRef = useRef<ShapeType<TObject>>(null);
|
||||
const transformerRef = useRef<Transformer>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!object.isSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!transformerRef.current || !shapeRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (object.isSelected) {
|
||||
transformerRef.current.nodes([shapeRef.current]);
|
||||
transformerRef.current.getLayer()?.batchDraw();
|
||||
}
|
||||
}, [object.isSelected]);
|
||||
|
||||
return { shapeRef, transformerRef };
|
||||
};
|
Loading…
Reference in New Issue
Block a user