mirror of
				https://github.com/bspeice/speice.io
				synced 2025-11-03 10:00:37 -05:00 
			
		
		
		
	Split paint/render image to handle callback depth
Iterator state still uses the same pattern, not sure how problematic that is.
This commit is contained in:
		@ -55,29 +55,28 @@ export default function Canvas({width, height, children}: CanvasProps) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }, []);
 | 
					    }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const {colorMode} = useColorMode();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Holder objects are used to force re-painting even if the iterator
 | 
					    // Holder objects are used to force re-painting even if the iterator
 | 
				
			||||||
    // returns a modified image with the same reference
 | 
					    // returns a modified image with the same reference
 | 
				
			||||||
    type ImageHolder = { image?: ImageData };
 | 
					    type ImageHolder = { image?: ImageData };
 | 
				
			||||||
    const [imageHolder, setImageHolder] = useState<ImageHolder>({ image: null });
 | 
					 | 
				
			||||||
    useEffect(() => {
 | 
					 | 
				
			||||||
        const image = imageHolder.image;
 | 
					 | 
				
			||||||
        if (!image) {
 | 
					 | 
				
			||||||
            // No image is available, leave the canvas as-is
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!canvasCtx) {
 | 
					    const [paintImage, setPaintImage] = useState<ImageHolder>({ image: null });
 | 
				
			||||||
            // Canvas is not ready for the image we have,
 | 
					    useEffect(() => {
 | 
				
			||||||
            // re-submit the image and wait for the ref to populate
 | 
					        if (paintImage.image && canvasCtx) {
 | 
				
			||||||
            setImageHolder({ image });
 | 
					            canvasCtx.putImageData(paintImage.image, 0, 0);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }, [paintImage, canvasCtx]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const {colorMode} = useColorMode();
 | 
				
			||||||
 | 
					    const [renderImage, setRenderImage] = useState<ImageHolder>({ image: null });
 | 
				
			||||||
 | 
					    useEffect(() => {
 | 
				
			||||||
 | 
					        const image = renderImage.image;
 | 
				
			||||||
 | 
					        if (!image) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If light mode is active, paint the image as-is
 | 
					        // If light mode is active, paint the image as-is
 | 
				
			||||||
        if (colorMode === 'light') {
 | 
					        if (colorMode === 'light') {
 | 
				
			||||||
            canvasCtx.putImageData(image, 0, 0);
 | 
					            setPaintImage({ image });
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,8 +88,8 @@ export default function Canvas({width, height, children}: CanvasProps) {
 | 
				
			|||||||
            const isAlpha = index % 4 === 3;
 | 
					            const isAlpha = index % 4 === 3;
 | 
				
			||||||
            paintImage.data[index] = isAlpha ? value : 255 - value;
 | 
					            paintImage.data[index] = isAlpha ? value : 255 - value;
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        canvasCtx.putImageData(paintImage, 0, 0);
 | 
					        setPaintImage({ image: paintImage });
 | 
				
			||||||
    }, [colorMode, imageHolder]);
 | 
					    }, [colorMode, renderImage]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Image iterators (painters) are also in a holder; this allows
 | 
					    // Image iterators (painters) are also in a holder; this allows
 | 
				
			||||||
    // re-submitting the existing iterator to draw the next frame,
 | 
					    // re-submitting the existing iterator to draw the next frame,
 | 
				
			||||||
@ -115,7 +114,7 @@ export default function Canvas({width, height, children}: CanvasProps) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        const image = painter.next().value;
 | 
					        const image = painter.next().value;
 | 
				
			||||||
        if (image) {
 | 
					        if (image) {
 | 
				
			||||||
            setImageHolder({ image });
 | 
					            setRenderImage({ image });
 | 
				
			||||||
            setAnimHolder({ painter });
 | 
					            setAnimHolder({ painter });
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            setAnimHolder({ painter: null });
 | 
					            setAnimHolder({ painter: null });
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user