Creating endless grid background pattern in Fabric.js canvas similar to Miro's design

Hey everyone!

I’m working on building a drawing application using Fabric.js and I need help creating a seamless grid background that behaves like the one in Miro. You know how Miro has that nice grid that moves and scales smoothly?

What I’m trying to build:
A drawing tool where users can sketch and the background has an endless grid pattern that responds to user interactions.

Key features I need to implement:

  1. Zoom functionality - When users zoom in or out, the grid should scale accordingly and maintain its proportions
  2. Pan support - Moving around the canvas should shift the grid background naturally
  3. Responsive sizing - When the browser window changes size, the grid should adapt to fill the entire canvas area

I’ve searched around and found some examples but they either don’t handle all the zoom and pan requirements or they have performance issues when dealing with large canvas areas.

Does anyone have experience implementing this type of infinite grid system? Any tips on the best approach or examples would be really helpful. I’m particularly interested in how to handle the grid rendering efficiently without impacting performance.

Thanks for any guidance you can share!

i did somethin like that too! use fabric.js’s background image option for a repeating pattern. keep it simple with a small grid image, and let it tile. it helps with zooming and panning smoothly too. good luck with your project!

honestly the easiest way ive found is just using css background on the canvas container itself with background-size and background-position. then you can update those values when fabric fires zoom/pan events. way less complicated than custom rendering and performs great too

Canvas rendering approach worked well for me when I built something similar. Rather than relying on background images or SVG patterns, I drew the grid lines directly on a separate canvas layer positioned behind the main fabric canvas. The performance is actually better since you have full control over when to redraw. I calculate the visible grid bounds based on the current viewport and only render lines that are actually visible on screen. When zoom changes, I adjust the grid spacing dynamically - for example, switching between major and minor grid lines at different zoom levels to keep things clean. The panning is handled by updating the grid offset calculations during fabric’s canvas move events. One gotcha I ran into was making sure the grid coordinates align properly with fabric’s coordinate system, especially when dealing with fractional zoom levels. You might want to consider caching the grid canvas and only updating it when necessary to avoid performance hits.

I tackled this exact problem last year when building a collaborative whiteboard app. The trick is using a custom pattern brush combined with viewport transformation tracking. Instead of rendering the entire grid, I created a repeating SVG pattern that gets applied as the canvas background. The key is listening to fabric’s viewport transform events and updating the pattern offset accordingly. For performance, I implemented a threshold system where the grid only redraws when zoom or pan changes exceed certain values. This prevents constant redrawing during smooth interactions. The math gets tricky with coordinate transformations, but once you nail the pattern positioning relative to the viewport matrix, it works beautifully. Make sure to debounce your grid updates during rapid zoom operations to avoid stuttering.