@@ -92,18 +92,61 @@ export function Arrows() {
9292 // This gives us the length of the arrow if it went from center to center
9393 const r = Math . hypot ( dy , dx ) ;
9494
95- // Calculate the new end point for the arrow
96- // We subtract ARROW_LENGTH_REDUCER from the total distance to make the arrow
97- // stop before reaching the center of the target square
98- const end = {
99- // Calculate new end x coordinate by:
100- // 1. Taking the original x direction (dx)
101- // 2. Scaling it by (r - ARROW_LENGTH_REDUCER) / r to shorten it
102- // 3. Adding to the starting x coordinate
103- x : from . x + ( dx * ( r - ARROW_LENGTH_REDUCER ) ) / r ,
104- // Same calculation for y coordinate
105- y : from . y + ( dy * ( r - ARROW_LENGTH_REDUCER ) ) / r ,
106- } ;
95+ let pathD : string ;
96+
97+ // Is Knight move
98+ if ( r === Math . hypot ( 1 , 2 ) * squareWidth ) {
99+ // The mid point is only used in Knight move drawing
100+ // and here we prioritise drawing along the long edge
101+ // by defining the midpoint depending on which is bigger X or Y
102+ const mid =
103+ Math . abs ( dx ) < Math . abs ( dy )
104+ ? {
105+ x : from . x ,
106+ y : to . y ,
107+ }
108+ : {
109+ x : to . x ,
110+ y : from . y ,
111+ } ;
112+
113+ // Calculate the difference in x and y coordinates between mid and end points
114+ const dxEnd = to . x - mid . x ;
115+ const dyEnd = to . y - mid . y ;
116+
117+ // End arrow distance is always one squareWidth for Knight moves
118+ const rEnd = squareWidth ;
119+
120+ // Calculate the new end point for the arrow
121+ // We subtract ARROW_LENGTH_REDUCER from the end line distance to make the arrow
122+ // stop before reaching the center of the target square
123+ const end = {
124+ // Calculate new end x coordinate by:
125+ // 1. Taking the mid->end x direction (dxEnd)
126+ // 2. Scaling it by (rEnd - ARROW_LENGTH_REDUCER) / rEnd to shorten it
127+ // 3. Adding to the mid x coordinate
128+ x : mid . x + ( dxEnd * ( rEnd - ARROW_LENGTH_REDUCER ) ) / rEnd ,
129+ // Same calculation for y coordinate
130+ y : mid . y + ( dyEnd * ( rEnd - ARROW_LENGTH_REDUCER ) ) / rEnd ,
131+ } ;
132+
133+ pathD = `M${ from . x } ,${ from . y } L${ mid . x } ,${ mid . y } L${ end . x } ,${ end . y } ` ;
134+ } else {
135+ // Calculate the new end point for the arrow
136+ // We subtract ARROW_LENGTH_REDUCER from the total distance to make the arrow
137+ // stop before reaching the center of the target square
138+ const end = {
139+ // Calculate new end x coordinate by:
140+ // 1. Taking the original x direction (dx)
141+ // 2. Scaling it by (r - ARROW_LENGTH_REDUCER) / r to shorten it
142+ // 3. Adding to the starting x coordinate
143+ x : from . x + ( dx * ( r - ARROW_LENGTH_REDUCER ) ) / r ,
144+ // Same calculation for y coordinate
145+ y : from . y + ( dy * ( r - ARROW_LENGTH_REDUCER ) ) / r ,
146+ } ;
147+
148+ pathD = `M${ from . x } ,${ from . y } L${ end . x } ,${ end . y } ` ;
149+ }
107150
108151 return (
109152 < Fragment
@@ -121,11 +164,9 @@ export function Arrows() {
121164 >
122165 < polygon points = "0.3 0, 2 1.25, 0.3 2.5" fill = { arrow . color } />
123166 </ marker >
124- < line
125- x1 = { from . x }
126- y1 = { from . y }
127- x2 = { end . x }
128- y2 = { end . y }
167+ < path
168+ d = { pathD }
169+ fill = "none"
129170 opacity = {
130171 isArrowActive
131172 ? arrowOptions . activeOpacity
0 commit comments