@@ -88,32 +88,34 @@ function approximateArc(
8888 const phiRad = ( phi * Math . PI ) / 180 ;
8989 const dx = ( p0 . x - p2 . x ) / 2 ;
9090 const dy = ( p0 . y - p2 . y ) / 2 ;
91+ let rxInternal = rx ;
92+ let ryInternal = ry ;
9193
9294 // Step 1: Compute the transformed start point.
9395 const x1p = Math . cos ( phiRad ) * dx + Math . sin ( phiRad ) * dy ;
9496 const y1p = - Math . sin ( phiRad ) * dx + Math . cos ( phiRad ) * dy ;
9597
9698 // Ensure the radii are large enough.
97- let rxSq = rx * rx ;
98- let rySq = ry * ry ;
99+ let rxSq = rxInternal * rxInternal ;
100+ let rySq = ryInternal * ryInternal ;
99101 const x1pSq = x1p * x1p ;
100102 const y1pSq = y1p * y1p ;
101103 const lambda = x1pSq / rxSq + y1pSq / rySq ;
102104 if ( lambda > 1 ) {
103105 const factor = Math . sqrt ( lambda ) ;
104- rx *= factor ;
105- ry *= factor ;
106- rxSq = rx * rx ;
107- rySq = ry * ry ;
106+ rxInternal *= factor ;
107+ ryInternal *= factor ;
108+ rxSq = rxInternal * rxInternal ;
109+ rySq = ryInternal * ryInternal ;
108110 }
109111
110112 // Step 2: Compute the center.
111113 const sign = largeArcFlag === sweepFlag ? - 1 : 1 ;
112114 const numerator = rxSq * rySq - rxSq * y1pSq - rySq * x1pSq ;
113- const denom = rxSq * y1pSq + rySq * x1pSq ;
114- const coeff = sign * Math . sqrt ( Math . max ( 0 , numerator / denom ) ) ;
115- const cxp = ( coeff * ( rx * y1p ) ) / ry ;
116- const cyp = ( coeff * ( - ry * x1p ) ) / rx ;
115+ const denominator = rxSq * y1pSq + rySq * x1pSq ;
116+ const coefficient = sign * Math . sqrt ( Math . max ( 0 , numerator / denominator ) ) ;
117+ const cxp = ( coefficient * ( rxInternal * y1p ) ) / ryInternal ;
118+ const cyp = ( coefficient * ( - ryInternal * x1p ) ) / rxInternal ;
117119
118120 // Step 3: Transform back to original coordinates.
119121 const cx = Math . cos ( phiRad ) * cxp - Math . sin ( phiRad ) * cyp + ( p0 . x + p2 . x ) / 2 ;
@@ -170,20 +172,22 @@ interface SvgCommand {
170172function parseSvgPath ( path : string ) : SvgCommand [ ] {
171173 const commands : SvgCommand [ ] = [ ] ;
172174 const re = / ( [ M m L l H h V v C c Q q A a Z z ] ) ( [ ^ M m L l H h V v C c Q q A a Z z ] * ) / g;
173- let match : RegExpExecArray | null ;
174- while ( ( match = re . exec ( path ) ) !== null ) {
175+ let match : RegExpExecArray | null = re . exec ( path ) ;
176+ while ( match !== null ) {
175177 const type = match [ 1 ] ;
176178 const argsStr = match [ 2 ] . trim ( ) ;
177179 const args : number [ ] = [ ] ;
178180 if ( argsStr . length > 0 ) {
179181 // Match numbers (including decimals, negatives, exponents)
180182 const numberRe = / - ? \d * \. ? \d + (?: e [ - + ] ? \d + ) ? / gi;
181- let numberMatch : RegExpExecArray | null ;
182- while ( ( numberMatch = numberRe . exec ( argsStr ) ) !== null ) {
183+ let numberMatch : RegExpExecArray | null = numberRe . exec ( argsStr ) ;
184+ while ( numberMatch !== null ) {
183185 args . push ( Number . parseFloat ( numberMatch [ 0 ] ) ) ;
186+ numberMatch = numberRe . exec ( argsStr ) ;
184187 }
185188 }
186189 commands . push ( { type, args } ) ;
190+ match = re . exec ( path ) ;
187191 }
188192 return commands ;
189193}
@@ -451,7 +455,7 @@ export function svgPathToSegments(
451455 break ;
452456 }
453457 default : {
454- console . error ( ' unsupported SVG command type: ' + type + ' ' + args . join ( ' ' ) ) ;
458+ console . error ( ` unsupported SVG command type: ${ type } ${ args . join ( ' ' ) } ` ) ;
455459 // Unsupported commands can be skipped.
456460 idx = args . length ;
457461 break ;
0 commit comments