mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-06-24 20:01:42 +02:00
decent drawing tools
This commit is contained in:
parent
8b48ad77e8
commit
346d1dddba
@ -2,19 +2,16 @@ import { style, globalStyle } from "@vanilla-extract/css";
|
|||||||
|
|
||||||
export const DrawImageMain = style({
|
export const DrawImageMain = style({
|
||||||
position: "relative",
|
position: "relative",
|
||||||
width: "512px",
|
|
||||||
height: "512px",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
globalStyle(`${DrawImageMain} > canvas`, {
|
globalStyle(`${DrawImageMain} > canvas`, {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "0",
|
top: "0",
|
||||||
left: "0",
|
left: "0",
|
||||||
opacity: "0.5",
|
opacity: ".5",
|
||||||
});
|
});
|
||||||
|
|
||||||
globalStyle(`${DrawImageMain} > img`, {
|
globalStyle(`${DrawImageMain} > img`, {
|
||||||
position: "absolute",
|
|
||||||
top: "0",
|
top: "0",
|
||||||
left: "0",
|
left: "0",
|
||||||
});
|
});
|
||||||
|
@ -1,22 +1,27 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React, { useRef, useState } from "react";
|
import React, { useRef, useState, useCallback, useEffect } from "react";
|
||||||
|
|
||||||
// https://github.com/embiem/react-canvas-draw
|
// https://github.com/embiem/react-canvas-draw
|
||||||
|
|
||||||
type DrawImageProps = {
|
type DrawImageProps = {
|
||||||
imageData: string;
|
imageData: string;
|
||||||
|
brushSize: string;
|
||||||
|
|
||||||
|
brushShape: string;
|
||||||
|
brushColor: string;
|
||||||
|
isErasing: boolean;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DrawImageMain, //@ts-ignore
|
DrawImageMain, //@ts-ignore
|
||||||
} from "./drawImage.css.ts";
|
} from "./drawImage.css.ts";
|
||||||
|
|
||||||
export default function DrawImage({ imageData }: DrawImageProps) {
|
export default function DrawImage({ imageData, brushSize, brushShape, brushColor, isErasing }: DrawImageProps) {
|
||||||
|
|
||||||
const drawingRef = useRef<HTMLCanvasElement>(null);
|
const drawingRef = useRef<HTMLCanvasElement>(null);
|
||||||
const cursorRef = useRef<HTMLCanvasElement>(null);
|
const cursorRef = useRef<HTMLCanvasElement>(null);
|
||||||
|
const [isUpdating, setIsUpdating] = useState(false);
|
||||||
const [isDrawing, setIsDrawing] = useState(false);
|
|
||||||
|
|
||||||
const _handleMouseDown = (
|
const _handleMouseDown = (
|
||||||
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
||||||
@ -27,95 +32,100 @@ export default function DrawImage({ imageData }: DrawImageProps) {
|
|||||||
nativeEvent: { offsetX, offsetY },
|
nativeEvent: { offsetX, offsetY },
|
||||||
} = e;
|
} = e;
|
||||||
|
|
||||||
setIsDrawing(true);
|
setIsUpdating(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const _handleMouseUp = (
|
const _handleMouseUp = (
|
||||||
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
||||||
) => {
|
) => {
|
||||||
setIsDrawing(false);
|
setIsUpdating(false);
|
||||||
|
|
||||||
const canvas = drawingRef.current;
|
const canvas = drawingRef.current;
|
||||||
if (canvas) {
|
if (canvas) {
|
||||||
const data = canvas.toDataURL();
|
const data = canvas.toDataURL();
|
||||||
console.log("data", data);
|
// TODO: SEND THIS TO THE STATE
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const _handleMouseMove = (
|
const _drawCanvas = (x, y, brushSize, brushShape, brushColor) => {
|
||||||
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
const canvas = drawingRef.current;
|
||||||
) => {
|
if (canvas) {
|
||||||
if (isDrawing) {
|
const ctx = canvas.getContext("2d");
|
||||||
const canvas = drawingRef.current;
|
if (isErasing) {
|
||||||
if (canvas) {
|
|
||||||
const ctx = canvas.getContext("2d");
|
|
||||||
ctx.strokeStyle = "red";
|
|
||||||
const {
|
|
||||||
nativeEvent: { offsetX, offsetY },
|
|
||||||
} = e;
|
|
||||||
|
|
||||||
|
// stack overflow https://stackoverflow.com/questions/10396991/clearing-circular-regions-from-html5-canvas
|
||||||
|
|
||||||
|
const offset = brushSize / 2;
|
||||||
|
ctx.clearRect(x - offset, y - offset, brushSize, brushSize);
|
||||||
|
|
||||||
|
} else {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
|
ctx.lineWidth = brushSize;
|
||||||
ctx.lineWidth = 20;
|
ctx.lineCap = brushShape;
|
||||||
|
ctx.strokeStyle = brushColor;
|
||||||
// Sets the end of the lines drawn
|
ctx.moveTo(x, y);
|
||||||
// to a round shape.
|
ctx.lineTo(x, y);
|
||||||
ctx.lineCap = "round";
|
|
||||||
|
|
||||||
ctx.strokeStyle = "white";
|
|
||||||
// The cursor to start drawing
|
|
||||||
// moves to this coordinate
|
|
||||||
ctx.moveTo(offsetX, offsetY);
|
|
||||||
|
|
||||||
// A line is traced from start
|
|
||||||
// coordinate to this coordinate
|
|
||||||
ctx.lineTo(offsetX, offsetY);
|
|
||||||
|
|
||||||
// Draws the line.
|
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const _handleCursorMove = (
|
const _drawCursor = (x, y, brushSize, brushShape, brushColor) => {
|
||||||
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
|
||||||
) => {
|
|
||||||
console.log("cursor move");
|
|
||||||
|
|
||||||
|
|
||||||
const canvas = cursorRef.current;
|
const canvas = cursorRef.current;
|
||||||
if (canvas) {
|
if (canvas) {
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
ctx.strokeStyle = "red";
|
|
||||||
const {
|
|
||||||
nativeEvent: { offsetX, offsetY },
|
|
||||||
} = e;
|
|
||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
|
|
||||||
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
ctx.lineWidth = 20;
|
if (isErasing) {
|
||||||
|
const offset = brushSize / 2;
|
||||||
|
// draw a quare outline
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.lineCap = 'butt';
|
||||||
|
ctx.strokeStyle = brushColor;
|
||||||
|
ctx.moveTo(x - offset, y - offset);
|
||||||
|
ctx.lineTo(x + offset, y - offset);
|
||||||
|
ctx.lineTo(x + offset, y + offset);
|
||||||
|
ctx.lineTo(x - offset, y + offset);
|
||||||
|
ctx.lineTo(x - offset, y - offset);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
// Sets the end of the lines drawn
|
} else {
|
||||||
// to a round shape.
|
|
||||||
ctx.lineCap = "round";
|
|
||||||
|
|
||||||
ctx.strokeStyle = "white";
|
ctx.lineWidth = brushSize;
|
||||||
// The cursor to start drawing
|
ctx.lineCap = brushShape;
|
||||||
// moves to this coordinate
|
ctx.strokeStyle = brushColor;
|
||||||
ctx.moveTo(offsetX, offsetY);
|
ctx.moveTo(x, y);
|
||||||
|
ctx.lineTo(x, y);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// A line is traced from start
|
};
|
||||||
// coordinate to this coordinate
|
|
||||||
ctx.lineTo(offsetX, offsetY);
|
|
||||||
|
|
||||||
// Draws the line.
|
const _handleMouseMove = (
|
||||||
ctx.stroke();
|
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
||||||
|
) => {
|
||||||
|
|
||||||
|
const {
|
||||||
|
nativeEvent: { offsetX: x, offsetY: y },
|
||||||
|
} = e;
|
||||||
|
|
||||||
|
_drawCursor(x, y, brushSize, brushShape, brushColor);
|
||||||
|
|
||||||
|
if (isUpdating) {
|
||||||
|
_drawCanvas(x, y, brushSize, brushShape, brushColor);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// function for external use
|
||||||
|
const fillCanvas = () => {
|
||||||
|
const canvas = drawingRef.current;
|
||||||
|
if (canvas) {
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
ctx.fillStyle = brushColor;
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={DrawImageMain}>
|
<div className={DrawImageMain}>
|
||||||
@ -124,17 +134,15 @@ export default function DrawImage({ imageData }: DrawImageProps) {
|
|||||||
ref={drawingRef}
|
ref={drawingRef}
|
||||||
width={512}
|
width={512}
|
||||||
height={512}
|
height={512}
|
||||||
onMouseDown={_handleMouseDown}
|
|
||||||
onMouseMove={_handleMouseMove}
|
|
||||||
onMouseUp={_handleMouseUp}
|
|
||||||
></canvas>
|
></canvas>
|
||||||
<canvas
|
<canvas
|
||||||
ref={cursorRef}
|
ref={cursorRef}
|
||||||
width={512}
|
width={512}
|
||||||
height={512}
|
height={512}
|
||||||
onMouseMove={_handleCursorMove}
|
onMouseDown={_handleMouseDown}
|
||||||
|
onMouseUp={_handleMouseUp}
|
||||||
|
onMouseMove={_handleMouseMove}
|
||||||
></canvas>
|
></canvas>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,6 @@ export const InpaintingSlider = style({
|
|||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "10px",
|
top: "10px",
|
||||||
left: "400px",
|
left: "400px",
|
||||||
width: "200px",
|
|
||||||
height: "20px",
|
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
||||||
});
|
});
|
||||||
|
@ -1,19 +1,148 @@
|
|||||||
import React from "react";
|
import React, { useRef, useState, ChangeEvent } from "react";
|
||||||
import DrawImage from "../../../molecules/drawImage";
|
import DrawImage from "../../../molecules/drawImage";
|
||||||
|
|
||||||
import { useImageCreate } from "../../../../stores/imageCreateStore";
|
import { useImageCreate } from "../../../../stores/imageCreateStore";
|
||||||
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
InpaintingPanelMain,
|
||||||
|
InpaintingControls,
|
||||||
|
InpaintingControlRow,
|
||||||
|
} from // @ts-ignore
|
||||||
|
"./inpaintingPanel.css.ts";
|
||||||
|
|
||||||
export default function InpaintingPanel() {
|
export default function InpaintingPanel() {
|
||||||
|
|
||||||
|
// no idea if this is the right typing
|
||||||
|
const drawingRef = useRef(null);
|
||||||
|
|
||||||
|
const [brushSize, setBrushSize] = useState('20');
|
||||||
|
const [brushShape, setBrushShape] = useState("round");
|
||||||
|
const [brushColor, setBrushColor] = useState("#fff");
|
||||||
|
const [isErasing, setIsErasing] = useState(false);
|
||||||
|
|
||||||
const init_image = useImageCreate((state) =>
|
const init_image = useImageCreate((state) =>
|
||||||
state.getValueForRequestKey("init_image")
|
state.getValueForRequestKey("init_image")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const _handleBrushMask = () => {
|
||||||
|
setIsErasing(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _handleBrushErase = () => {
|
||||||
|
setIsErasing(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _handleFillMask = () => {
|
||||||
|
console.log("fill mask!!", drawingRef);
|
||||||
|
|
||||||
|
// drawingRef.current?.fillCanvas();
|
||||||
|
};
|
||||||
|
|
||||||
|
const _handleClearAll = () => {
|
||||||
|
console.log("clear all");
|
||||||
|
};
|
||||||
|
|
||||||
|
const _handleBrushSize = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setBrushSize(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// const _handleBrushShape = (e: ) => {
|
||||||
|
// console.log("brush shape", e.target.value);
|
||||||
|
// setBrushShape(e.target.value);
|
||||||
|
// };
|
||||||
|
|
||||||
|
const _handleBrushShape = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
console.log("brush shape", e.target.value);
|
||||||
|
setBrushShape(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _handleBrushColor = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
console.log("brush color", e.target.value);
|
||||||
|
setBrushColor(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={InpaintingPanelMain}>
|
||||||
<DrawImage imageData={init_image} />
|
<DrawImage
|
||||||
|
// ref={drawingRef}
|
||||||
|
imageData={init_image}
|
||||||
|
brushSize={brushSize}
|
||||||
|
brushShape={brushShape}
|
||||||
|
brushColor={brushColor}
|
||||||
|
isErasing={isErasing}
|
||||||
|
/>
|
||||||
|
<div className={InpaintingControls}>
|
||||||
|
<div className={InpaintingControlRow}>
|
||||||
|
<button
|
||||||
|
onClick={_handleBrushMask}
|
||||||
|
>
|
||||||
|
Mask
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={_handleBrushErase}
|
||||||
|
>
|
||||||
|
Erase
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
disabled
|
||||||
|
onClick={_handleFillMask}
|
||||||
|
>
|
||||||
|
Fill
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
disabled
|
||||||
|
onClick={_handleClearAll}
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<label
|
||||||
|
>
|
||||||
|
Brush Size
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min="1"
|
||||||
|
max="100"
|
||||||
|
value={brushSize}
|
||||||
|
onChange={_handleBrushSize}
|
||||||
|
>
|
||||||
|
</input>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={InpaintingControlRow}>
|
||||||
|
<button
|
||||||
|
value={"round"}
|
||||||
|
onClick={_handleBrushShape}
|
||||||
|
>
|
||||||
|
Cirle Brush
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
value={"square"}
|
||||||
|
onClick={_handleBrushShape}
|
||||||
|
>
|
||||||
|
Square Brush
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
value={"#000"}
|
||||||
|
onClick={_handleBrushColor}
|
||||||
|
>
|
||||||
|
Dark Brush
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
value={"#fff"}
|
||||||
|
onClick={_handleBrushColor}
|
||||||
|
>
|
||||||
|
Light Brush
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
import { style } from '@vanilla-extract/css'
|
||||||
|
|
||||||
|
export const InpaintingPanelMain = style({
|
||||||
|
position: 'relative',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
padding: '10px 10px',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const InpaintingControls = style({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
width: '100%',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const InpaintingControlRow = style({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-evenly',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '100%',
|
||||||
|
|
||||||
|
':first-of-type': {
|
||||||
|
margin: '10px 0',
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user