❌

Reading view

I built a coloring site with React + Konva. Here's how I kept the canvas out of React's render cycle

I've been building tintly.art, a free coloring site people mostly use on their phones (Next.js 16 + Konva). A few things I learned along the way:

1. Konva lives outside React. The canvas is plain Konva classes (fill layer, stroke layer, outline layer), not react-konva. React only renders the toolbar, palette and sheets. They talk through tiny stores with subscribe(), read with useSyncExternalStore. Drawing a stroke never re-renders a single component.

2. One stroke = one Konva.Line. While you drag, only a preview line updates. On release it's committed as one command, so undo/redo is just a stack of commands.

3. Raster cache for cheap phones. After ~24 strokes the committed group gets cached into one bitmap, so the frame cost stays flat no matter how much someone draws. When you zoom past the cache resolution it switches back to vector so nothing blurs.

4. The eraser uses destination-out on the stroke layer only, so it can never erase the fills or the outlines underneath.

5. Tap-to-fill works on SVG regions turned into Konva.Paths, and glitter fills are just a generated pattern tile as fillPatternImage.

Huge thanks to Anton Lavrenov and everyone behind Konva. It's honestly giving colors to my vision. People color on it every day, and it brings them a bit of joy and a calm little break.

Happy to answer questions about any of this. 🎨

submitted by /u/Dootutu to r/reactjs
[link] [comments]
  •  
❌