feat(ui): colored mask preview image

This commit is contained in:
psychedelicious 2024-08-24 08:54:20 +10:00
parent 56fd46a069
commit 9f29892c24

View File

@ -1,13 +1,36 @@
import { Box, chakra, Flex } from '@invoke-ai/ui-library';
import { useStore } from '@nanostores/react';
import { createSelector } from '@reduxjs/toolkit';
import { rgbColorToString } from 'common/util/colorCodeTransformers';
import { useEntityAdapter } from 'features/controlLayers/contexts/EntityAdapterContext';
import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
import { TRANSPARENCY_CHECKER_PATTERN } from 'features/controlLayers/konva/constants';
import { memo, useEffect, useRef } from 'react';
import { selectCanvasV2Slice, selectEntity } from 'features/controlLayers/store/canvasV2Slice';
import { memo, useEffect, useMemo, useRef } from 'react';
import { useSelector } from 'react-redux';
const ChakraCanvas = chakra.canvas;
const PADDING = 4;
export const CanvasEntityPreviewImage = memo(() => {
const entityIdentifier = useEntityIdentifierContext();
const adapter = useEntityAdapter();
const selectMaskColor = useMemo(
() =>
createSelector(selectCanvasV2Slice, (state) => {
const entity = selectEntity(state, entityIdentifier);
if (!entity) {
return null;
}
if (entity.type === 'inpaint_mask' || entity.type === 'regional_guidance') {
return rgbColorToString(entity.fill.color);
}
return null;
}),
[entityIdentifier]
);
const maskColor = useSelector(selectMaskColor);
const containerRef = useRef<HTMLDivElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
const cache = useStore(adapter.renderer.$canvasCache);
@ -26,8 +49,25 @@ export const CanvasEntityPreviewImage = memo(() => {
canvasRef.current.width = rect.width;
canvasRef.current.height = rect.height;
ctx.drawImage(canvas, rect.x, rect.y, rect.width, rect.height, 0, 0, rect.width, rect.height);
}, [adapter.transformer, adapter.transformer.nodeRect, adapter.transformer.pixelRect, cache]);
const scale = containerRef.current.offsetWidth / rect.width;
const sx = rect.x;
const sy = rect.y;
const sWidth = rect.width;
const sHeight = rect.height;
const dx = PADDING / scale;
const dy = PADDING / scale;
const dWidth = rect.width - (PADDING * 2) / scale;
const dHeight = rect.height - (PADDING * 2) / scale;
ctx.drawImage(canvas, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
if (maskColor) {
ctx.fillStyle = maskColor;
ctx.globalCompositeOperation = 'source-in';
ctx.fillRect(0, 0, rect.width, rect.height);
}
}, [adapter.transformer, adapter.transformer.nodeRect, adapter.transformer.pixelRect, cache, maskColor]);
return (
<Flex