I’m working on building a drawing application using Fabric.js and I need help creating a background grid that behaves like the ones you see in online whiteboard apps.
What I’m trying to build:
A canvas with an endless grid pattern that responds to user interactions just like professional drawing tools.
Key features I need:
Grid should scale properly when users zoom in or zoom out
Moving around the canvas should shift the grid accordingly
When browser window gets resized, the grid should adjust to fill the new canvas dimensions
I’ve been searching around but most examples I found either don’t handle all the interactive features or have performance issues. Does anyone know the best approach for this kind of functionality?
Had this exact problem last year building a collaborative whiteboard. Here’s what worked: create a separate canvas for your grid pattern, then use createPattern() to apply it as the background. Listen for ‘after:render’ events and recalculate the pattern offset using current viewportTransform values. For scaling, adjust your grid spacing with the zoom factor from the transform matrix. Handle window resizes by regenerating pattern dimensions and refreshing the background property. Performance stayed smooth even with heavy usage since the browser handles pattern repetition natively.
Hook into Fabric’s transform events with a custom background rendering function. Override the canvas background with a pattern that recalculates based on the viewport matrix. I create a function that draws grid lines using the canvas 2D context directly, then call it on zoom and pan events. Debounce the redraw calls or you’ll get performance hits during smooth zooming. The math’s tricky when calculating which grid lines are visible in the current viewport, but once you get that right, performance stays solid even with complex canvases.
i’ve tried this b4! fabric’s viewportTransform is super helpful. just calculate the grid offset based on your zoom and pan, then redraw the bg pattern. performance is good if u stick to drawing what’s visible.
canvas.on(‘viewport:changed’) is perfect for this! Use the transform matrix to offset your grid pattern and cache those visible area calculations - otherwise it’ll lag like crazy.