@@ -7,6 +7,7 @@ import { transferExif } from '@/lib/utils/exif'
77import {
88 drawRuleOfThirds , drawGoldenRatio , drawGoldenSpiral , drawGoldenDiagonal ,
99 drawDiagonalLines , drawCenterCross , drawSquareGrid , drawTriangles ,
10+ GOLDEN_RATIO ,
1011} from '@/lib/math/grid'
1112import type { FrameConfig , CropState , GridType , GridOptions } from './types'
1213import { thicknessToPx } from './types'
@@ -38,8 +39,30 @@ const GRID_DRAW_MAP: Record<GridType, DrawFn> = {
3839 'triangles' : ( ctx , w , h ) => drawTriangles ( ctx , w , h ) ,
3940}
4041
41- function drawGridTiled (
42- ctx : CanvasRenderingContext2D , drawFn : DrawFn ,
42+ function getLinePositions (
43+ gridType : GridType , w : number , h : number , opts : GridOptions ,
44+ ) : { v : number [ ] ; h : number [ ] } | null {
45+ switch ( gridType ) {
46+ case 'rule-of-thirds' :
47+ return { v : [ 0 , w / 3 , 2 * w / 3 ] , h : [ 0 , h / 3 , 2 * h / 3 ] }
48+ case 'golden-ratio' : {
49+ const pw = w / GOLDEN_RATIO , ph = h / GOLDEN_RATIO
50+ return { v : [ 0 , w - pw , pw ] , h : [ 0 , h - ph , ph ] }
51+ }
52+ case 'center-cross' :
53+ return { v : [ 0 , w / 2 ] , h : [ 0 , h / 2 ] }
54+ case 'square-grid' :
55+ return {
56+ v : Array . from ( { length : opts . gridDensity } , ( _ , i ) => ( i * w ) / opts . gridDensity ) ,
57+ h : Array . from ( { length : opts . gridDensity } , ( _ , i ) => ( i * h ) / opts . gridDensity ) ,
58+ }
59+ default :
60+ return null
61+ }
62+ }
63+
64+ function drawExportGrid (
65+ ctx : CanvasRenderingContext2D , gridType : GridType , drawFn : DrawFn ,
4366 originX : number , originY : number , gw : number , gh : number ,
4467 ox : number , oy : number , opts : GridOptions ,
4568) {
@@ -51,15 +74,30 @@ function drawGridTiled(
5174 ctx . restore ( )
5275 return
5376 }
54- const px = ( ( ox % gw ) + gw ) % gw
55- const py = ( ( oy % gh ) + gh ) % gh
56- for ( let dx = - 1 ; dx <= 0 ; dx ++ ) {
57- for ( let dy = - 1 ; dy <= 0 ; dy ++ ) {
58- ctx . save ( )
59- ctx . translate ( originX + px + dx * gw , originY + py + dy * gh )
60- ctx . beginPath ( )
61- drawFn ( ctx , gw , gh , opts )
62- ctx . restore ( )
77+
78+ const positions = getLinePositions ( gridType , gw , gh , opts )
79+ if ( positions ) {
80+ ctx . beginPath ( )
81+ for ( const base of positions . v ) {
82+ const x = ( ( base + ox ) % gw + gw ) % gw
83+ if ( x > 0.5 ) { ctx . moveTo ( originX + x , originY ) ; ctx . lineTo ( originX + x , originY + gh ) }
84+ }
85+ for ( const base of positions . h ) {
86+ const y = ( ( base + oy ) % gh + gh ) % gh
87+ if ( y > 0.5 ) { ctx . moveTo ( originX , originY + y ) ; ctx . lineTo ( originX + gw , originY + y ) }
88+ }
89+ ctx . stroke ( )
90+ } else {
91+ const px = ( ( ox % gw ) + gw ) % gw
92+ const py = ( ( oy % gh ) + gh ) % gh
93+ for ( let dx = - 1 ; dx <= 0 ; dx ++ ) {
94+ for ( let dy = - 1 ; dy <= 0 ; dy ++ ) {
95+ ctx . save ( )
96+ ctx . translate ( originX + px + dx * gw , originY + py + dy * gh )
97+ ctx . beginPath ( )
98+ drawFn ( ctx , gw , gh , opts )
99+ ctx . restore ( )
100+ }
63101 }
64102 }
65103}
@@ -137,7 +175,7 @@ export function ExportDialog({
137175 ctx . lineWidth = thicknessToPx ( gridOptions . thickness )
138176 for ( const gridType of activeGrids ) {
139177 const drawFn = GRID_DRAW_MAP [ gridType ]
140- if ( drawFn ) drawGridTiled ( ctx , drawFn , imgX , imgY , sw , sh , ox , oy , gridOptions )
178+ if ( drawFn ) drawExportGrid ( ctx , gridType , drawFn , imgX , imgY , sw , sh , ox , oy , gridOptions )
141179 }
142180 ctx . restore ( )
143181 }
0 commit comments