File size: 1,829 Bytes
f56a29b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { useMemo } from 'react';
import { useCanvasStore, useSceneSelector } from '@/lib/store';
import type { SlideContent } from '@/lib/types/stage';
import type { SlideBackground } from '@/lib/types/slides';

export function GridLines() {
  const gridLineSize = useCanvasStore.use.gridLineSize();
  const viewportRatio = useCanvasStore.use.viewportRatio();
  const viewportSize = useCanvasStore.use.viewportSize();

  const background = useSceneSelector<SlideContent, SlideBackground | undefined>(
    (content) => content.canvas.background,
  );

  // Calculate grid line color to avoid blending with background
  const gridColor = useMemo(() => {
    const bgColor = background?.color || '#fff';
    // Simplified version: choose black or white based on background brightness
    const isLight = bgColor === '#fff' || bgColor.startsWith('#f') || bgColor.startsWith('#e');
    const baseColor = isLight ? '0, 0, 0' : '255, 255, 255';
    return `rgba(${baseColor}, 0.5)`;
  }, [background]);

  // Grid path
  const path = useMemo(() => {
    const maxX = viewportSize;
    const maxY = viewportSize * viewportRatio;

    let p = '';
    for (let i = 0; i <= Math.floor(maxY / gridLineSize); i++) {
      p += `M0 ${i * gridLineSize} L${maxX} ${i * gridLineSize} `;
    }
    for (let i = 0; i <= Math.floor(maxX / gridLineSize); i++) {
      p += `M${i * gridLineSize} 0 L${i * gridLineSize} ${maxY} `;
    }
    return p;
  }, [viewportSize, viewportRatio, gridLineSize]);

  return (
    <svg
      className="grid-lines absolute inset-0 pointer-events-none z-40"
      width={viewportSize}
      height={viewportSize * viewportRatio}
      viewBox={`0 0 ${viewportSize} ${viewportSize * viewportRatio}`}
    >
      <path d={path} fill="none" stroke={gridColor} strokeWidth="1" strokeDasharray="5 5" />
    </svg>
  );
}