@@ -56,7 +56,7 @@ interface AnimatedBounds {
5656 id : string ;
5757 current : { x : number ; y : number ; width : number ; height : number } ;
5858 target : { x : number ; y : number ; width : number ; height : number } ;
59- borderRadius : number ;
59+ borderRadii : number [ ] ;
6060 opacity : number ;
6161 targetOpacity : number ;
6262 createdAt ?: number ;
@@ -143,10 +143,12 @@ export const OverlayCanvas: Component<OverlayCanvasProps> = (props) => {
143143 }
144144 } ;
145145
146- const parseBorderRadiusValue = ( borderRadius : string ) : number => {
147- if ( ! borderRadius ) return 0 ;
148- const match = borderRadius . match ( / ^ ( \d + (?: \. \d + ) ? ) / ) ;
149- return match ? parseFloat ( match [ 1 ] ) : 0 ;
146+ const parseBorderRadii = ( borderRadius : string ) : number [ ] => {
147+ if ( ! borderRadius ) return [ 0 , 0 , 0 , 0 ] ;
148+ const radiusString = borderRadius . split ( "/" ) [ 0 ] . trim ( ) ;
149+ const values = radiusString . split ( / \s + / ) . map ( ( value ) => parseFloat ( value ) || 0 ) ;
150+ const [ topLeft = 0 , topRight = topLeft , bottomRight = topLeft , bottomLeft = topRight ] = values ;
151+ return [ topLeft , topRight , bottomRight , bottomLeft ] ;
150152 } ;
151153
152154 const createAnimatedBounds = (
@@ -167,7 +169,7 @@ export const OverlayCanvas: Component<OverlayCanvasProps> = (props) => {
167169 width : bounds . width ,
168170 height : bounds . height ,
169171 } ,
170- borderRadius : parseBorderRadiusValue ( bounds . borderRadius ) ,
172+ borderRadii : parseBorderRadii ( bounds . borderRadius ) ,
171173 opacity : options ?. opacity ?? 1 ,
172174 targetOpacity : options ?. targetOpacity ?? options ?. opacity ?? 1 ,
173175 createdAt : options ?. createdAt ,
@@ -185,7 +187,7 @@ export const OverlayCanvas: Component<OverlayCanvasProps> = (props) => {
185187 width : bounds . width ,
186188 height : bounds . height ,
187189 } ;
188- animation . borderRadius = parseBorderRadiusValue ( bounds . borderRadius ) ;
190+ animation . borderRadii = parseBorderRadii ( bounds . borderRadius ) ;
189191 if ( targetOpacity !== undefined ) {
190192 animation . targetOpacity = targetOpacity ;
191193 }
@@ -194,26 +196,28 @@ export const OverlayCanvas: Component<OverlayCanvasProps> = (props) => {
194196 const resolveBoundsArray = ( instance : SelectionLabelInstance ) : OverlayBounds [ ] =>
195197 instance . boundsMultiple ?? [ instance . bounds ] ;
196198
199+ const clampRadii = ( radii : number [ ] , halfWidth : number , halfHeight : number ) : number [ ] =>
200+ radii . map ( ( radius ) => Math . min ( radius , halfWidth , halfHeight ) ) ;
201+
197202 const drawRoundedRectangle = (
198203 context : OffscreenCanvasRenderingContext2D ,
199204 rectX : number ,
200205 rectY : number ,
201206 rectWidth : number ,
202207 rectHeight : number ,
203- cornerRadius : number ,
208+ cornerRadii : number [ ] ,
204209 fillColor : string ,
205210 strokeColor : string ,
206211 opacity : number = 1 ,
207212 ) => {
208213 if ( rectWidth <= 0 || rectHeight <= 0 ) return ;
209214
210- const maxCornerRadius = Math . min ( rectWidth / 2 , rectHeight / 2 ) ;
211- const clampedCornerRadius = Math . min ( cornerRadius , maxCornerRadius ) ;
215+ const clamped = clampRadii ( cornerRadii , rectWidth / 2 , rectHeight / 2 ) ;
212216
213217 context . globalAlpha = opacity ;
214218 context . beginPath ( ) ;
215- if ( clampedCornerRadius > 0 ) {
216- context . roundRect ( rectX , rectY , rectWidth , rectHeight , clampedCornerRadius ) ;
219+ if ( clamped . some ( ( radius ) => radius > 0 ) ) {
220+ context . roundRect ( rectX , rectY , rectWidth , rectHeight , clamped ) ;
217221 } else {
218222 context . rect ( rectX , rectY , rectWidth , rectHeight ) ;
219223 }
@@ -241,7 +245,7 @@ export const OverlayCanvas: Component<OverlayCanvasProps> = (props) => {
241245 dragAnimation . current . y ,
242246 dragAnimation . current . width ,
243247 dragAnimation . current . height ,
244- dragAnimation . borderRadius ,
248+ dragAnimation . borderRadii ,
245249 style . fillColor ,
246250 style . borderColor ,
247251 ) ;
@@ -266,7 +270,7 @@ export const OverlayCanvas: Component<OverlayCanvasProps> = (props) => {
266270 animation . current . y ,
267271 animation . current . width ,
268272 animation . current . height ,
269- animation . borderRadius ,
273+ animation . borderRadii ,
270274 style . fillColor ,
271275 style . borderColor ,
272276 effectiveOpacity ,
@@ -293,7 +297,7 @@ export const OverlayCanvas: Component<OverlayCanvasProps> = (props) => {
293297 animation . current . y ,
294298 animation . current . width ,
295299 animation . current . height ,
296- animation . borderRadius ,
300+ animation . borderRadii ,
297301 style . fillColor ,
298302 style . borderColor ,
299303 animation . opacity ,
@@ -335,9 +339,9 @@ export const OverlayCanvas: Component<OverlayCanvasProps> = (props) => {
335339 const appendBoundsToPath = ( path : Path2D , animation : AnimatedBounds ) => {
336340 const { x, y, width, height } = animation . current ;
337341 if ( width <= 0 || height <= 0 ) return ;
338- const clampedRadius = Math . min ( animation . borderRadius , width / 2 , height / 2 ) ;
339- if ( clampedRadius > 0 ) {
340- path . roundRect ( x , y , width , height , clampedRadius ) ;
342+ const clamped = clampRadii ( animation . borderRadii , width / 2 , height / 2 ) ;
343+ if ( clamped . some ( ( radius ) => radius > 0 ) ) {
344+ path . roundRect ( x , y , width , height , clamped ) ;
341345 } else {
342346 path . rect ( x , y , width , height ) ;
343347 }
0 commit comments