From e6eeb88c14825295648e5e6af001155289c10351 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Sun, 10 Aug 2025 17:19:56 +0900 Subject: [PATCH] #3 --- .../src/components/threads/ThreadCanvas.tsx | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/frontend/src/components/threads/ThreadCanvas.tsx b/frontend/src/components/threads/ThreadCanvas.tsx index d86c69f..ff39086 100644 --- a/frontend/src/components/threads/ThreadCanvas.tsx +++ b/frontend/src/components/threads/ThreadCanvas.tsx @@ -116,6 +116,7 @@ const isLayer = (obj: unknown): obj is Layer => ( export default () => { const drawingRef = useRef (false) const fileInputRef = useRef (null) + const layersRef = useRef> ({ }) const stageRef = useRef (null) const [activeLayerId, setActiveLayerId] = useState (null) @@ -125,6 +126,7 @@ export default () => { const [layers, setLayers] = useState ([]) const [mode, setMode] = useState (Mode.Pen) const [pointSize, setPointSize] = useState (3) + const [singleLayer, setSingleLayer] = useState (false) const [stageHeight, setStageHeight] = useState (480) const [stageWidth, setStageWidth] = useState (480) @@ -210,37 +212,31 @@ export default () => { fileInputRef.current.value = '' } - const handlePaint = async () => { + const handlePaint = (ev: Konva.KonvaEventObject) => { const layer = activeLayer - if (!(layer) || !(stageRef.current)) + if (!(layer) || !(layersRef.current?.[layer.id])) return - const stage = stageRef.current - const pos = stage.getPointerPosition () + const pos = ev.target.getStage ()?.getPointerPosition () if (!(pos)) return - const dataURL = stage.toDataURL ({ mimeType: 'image/png', pixelRatio: 1 }) + const stage = layersRef.current[layer.id] + if (!(stage)) + return - const img = new window.Image - img.crossOrigin = 'anonymous' - await new Promise (res => { - img.onload = () => res () - img.src = dataURL - }) + if (drawingRef.current) + return + + drawingRef.current = true - const $off = document.createElement ('canvas') - $off.width = stageWidth - $off.height = stageHeight - const ctx = $off.getContext ('2d') - ctx!.drawImage (img, 0, 0, stageWidth, stageHeight) + const off = stage.toCanvas ({ pixelRatio: 1 }) + const ctx = off.getContext ('2d')! + const imgData = ctx.getImageData (0, 0, off.width, off.height) - const imgData = ctx!.getImageData (0, 0, stageWidth, stageHeight) const [r, g, b, a] = hexToRgba (colour, 255) floodFill (imgData, Math.floor (pos.x), Math.floor (pos.y), { r, g, b, a }) - ctx!.putImageData (imgData, 0, 0) - - const nextSrc = $off.toDataURL ('image/png') + ctx.putImageData (imgData, 0, 0) updateActiveLayerHistory ([...layer.history, layer.lines]) updateActiveLayerFuture ([]) @@ -251,7 +247,9 @@ export default () => { { mode: Mode.Paint, points: [pos.x, pos.y], stroke: colour, - imageSrc: nextSrc }] }) : l)) + imageSrc: off.toDataURL ('image/png') }] }) : l)) + + drawingRef.current = false } const updateActiveLayerLines = (lines: Line[]) => { @@ -537,11 +535,19 @@ export default () => { 追加 + +
- { + { stageRef.current = node }} width={stageWidth} @@ -561,8 +567,11 @@ export default () => { listening={false} /> - {layers.map (layer => ( - + {layers.map (layer => (!(singleLayer) || layer.id === activeLayerId) && ( + { + if (node) + layersRef.current = { ...layersRef.current, [layer.id]: node } + }}> {images[layer.id] && ( { : 'source-over'} />) case Mode.Paint: return ( -