// Grid drawing adapted from https://longviewcoder.com/2021/12/08/konva-a-better-grid/ import { useColorMode } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; import { useAppSelector } from 'app/store'; import _ from 'lodash'; import { ReactNode, useCallback, useLayoutEffect, useState } from 'react'; import { Group, Line as KonvaLine } from 'react-konva'; import { canvasSelector } from 'features/canvas/store/canvasSelectors'; const selector = createSelector( [canvasSelector], (canvas) => { const { stageScale, stageCoordinates, stageDimensions } = canvas; return { stageScale, stageCoordinates, stageDimensions }; }, { memoizeOptions: { resultEqualityCheck: _.isEqual, }, } ); const gridLinesColor = { dark: 'rgba(255, 255, 255, 0.2)', green: 'rgba(255, 255, 255, 0.2)', light: 'rgba(0, 0, 0, 0.2)', }; const IAICanvasGrid = () => { const { colorMode } = useColorMode(); const { stageScale, stageCoordinates, stageDimensions } = useAppSelector(selector); const [gridLines, setGridLines] = useState([]); const unscale = useCallback( (value: number) => { return value / stageScale; }, [stageScale] ); useLayoutEffect(() => { const gridLineColor = gridLinesColor[colorMode]; const { width, height } = stageDimensions; const { x, y } = stageCoordinates; const stageRect = { x1: 0, y1: 0, x2: width, y2: height, offset: { x: unscale(x), y: unscale(y), }, }; const gridOffset = { x: Math.ceil(unscale(x) / 64) * 64, y: Math.ceil(unscale(y) / 64) * 64, }; const gridRect = { x1: -gridOffset.x, y1: -gridOffset.y, x2: unscale(width) - gridOffset.x + 64, y2: unscale(height) - gridOffset.y + 64, }; const gridFullRect = { x1: Math.min(stageRect.x1, gridRect.x1), y1: Math.min(stageRect.y1, gridRect.y1), x2: Math.max(stageRect.x2, gridRect.x2), y2: Math.max(stageRect.y2, gridRect.y2), }; const fullRect = gridFullRect; const // find the x & y size of the grid xSize = fullRect.x2 - fullRect.x1, ySize = fullRect.y2 - fullRect.y1, // compute the number of steps required on each axis. xSteps = Math.round(xSize / 64) + 1, ySteps = Math.round(ySize / 64) + 1; const xLines = _.range(0, xSteps).map((i) => ( )); const yLines = _.range(0, ySteps).map((i) => ( )); setGridLines(xLines.concat(yLines)); }, [stageScale, stageCoordinates, stageDimensions, colorMode, unscale]); return {gridLines}; }; export default IAICanvasGrid;