Skip to main content

Grid Overlay

Ydesign ships smart guidelines and snapping that auto-align elements to each other. But sometimes you want an always-visible grid as a layout reference (pro typography, print grids, etc.).

This demo renders a grid overlay on the canvas.

The approach: an SVG grid as an unselectable image

Generate an SVG that covers the canvas and add it as the bottom-most, unselectable element:

function generateGridSvg(width: number, height: number, gridSize = 40) {
const lines: string[] = [];
for (let x = 0; x <= width; x += gridSize) {
lines.push(`<line x1="${x}" y1="0" x2="${x}" y2="${height}" stroke="#e0e0e0" stroke-width="1"/>`);
}
for (let y = 0; y <= height; y += gridSize) {
lines.push(`<line x1="0" y1="${y}" x2="${width}" y2="${y}" stroke="#e0e0e0" stroke-width="1"/>`);
}
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
${lines.join('\n')}
</svg>`;
}

Convert to dataURL and insert as an Image:

import { svgToURL } from '@ydesign/react-editor/utils/svg';

const gridSvg = generateGridSvg(store.width, store.height, 40);

store.addElement({
type: 'Image',
id: 'grid-overlay',
src: svgToURL(gridSvg),
left: 0,
top: 0,
width: store.width,
height: store.height,
selectable: false,
evented: false,
lockMovementX: true,
lockMovementY: true,
});

store.moveElementsBottom(['grid-overlay']);

Toggle

function toggleGrid() {
const grid = store.getElementById('grid-overlay');
if (grid) {
store.editor?.objectsHandler.removeById('grid-overlay');
} else {
// ... re-add as above
}
}

Next steps

  • Snap to grid: on object:moving, round left / top to the nearest grid step
  • Dynamic grid size: a <Slider /> to control gridSize, regenerate SVG on change
  • Exclude from export:
await store.toDataURL({
multiplier: 2,
filter: (obj: any) => obj.id !== 'grid-overlay',
});

See also