Merge pull request #1950 from Caden-Hornyak/fix/corner-radius-negative-dimensions

Fixed corner radius for Konva.Rect negative width/height
This commit is contained in:
Anton Lavrenov 2025-08-11 06:38:15 -05:00 committed by GitHub
commit 553245c074
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 12 deletions

View File

@ -1017,6 +1017,11 @@ export const Util = {
height: number,
cornerRadius: number | number[]
) {
// if negative dimensions, abs width/height and move rectangle
let xOrigin = width < 0 ? width : 0;
let yOrigin = height < 0 ? height : 0;
width = Math.abs(width);
height = Math.abs(height);
let topLeft = 0;
let topRight = 0;
let bottomLeft = 0;
@ -1033,35 +1038,42 @@ export const Util = {
bottomRight = Math.min(cornerRadius[2] || 0, width / 2, height / 2);
bottomLeft = Math.min(cornerRadius[3] || 0, width / 2, height / 2);
}
context.moveTo(topLeft, 0);
context.lineTo(width - topRight, 0);
context.moveTo(xOrigin + topLeft, yOrigin);
context.lineTo(xOrigin + width - topRight, yOrigin);
context.arc(
width - topRight,
topRight,
xOrigin + width - topRight,
yOrigin + topRight,
topRight,
(Math.PI * 3) / 2,
0,
false
);
context.lineTo(width, height - bottomRight);
context.lineTo(xOrigin + width, yOrigin + height - bottomRight);
context.arc(
width - bottomRight,
height - bottomRight,
xOrigin + width - bottomRight,
yOrigin + height - bottomRight,
bottomRight,
0,
Math.PI / 2,
false
);
context.lineTo(bottomLeft, height);
context.lineTo(xOrigin + bottomLeft, yOrigin + height);
context.arc(
bottomLeft,
height - bottomLeft,
xOrigin + bottomLeft,
yOrigin + height - bottomLeft,
bottomLeft,
Math.PI / 2,
Math.PI,
false
);
context.lineTo(0, topLeft);
context.arc(topLeft, topLeft, topLeft, Math.PI, (Math.PI * 3) / 2, false);
context.lineTo(xOrigin, yOrigin + topLeft);
context.arc(
xOrigin + topLeft,
yOrigin + topLeft,
topLeft,
Math.PI,
(Math.PI * 3) / 2,
false
);
},
};

View File

@ -234,4 +234,28 @@ describe('Rect', function () {
'clearRect(0,0,578,200);save();transform(1,0,0,1,50,50);beginPath();moveTo(0,0);lineTo(90,0);arc(90,10,10,4.712,0,false);lineTo(100,80);arc(80,80,20,0,1.571,false);lineTo(30,100);arc(30,70,30,1.571,3.142,false);lineTo(0,0);arc(0,0,0,3.142,4.712,false);closePath();fillStyle=black;fill();restore();clearRect(0,0,578,200);save();transform(1,0,0,1,50,50);beginPath();moveTo(0,0);lineTo(90,0);arc(90,10,10,4.712,0,false);lineTo(100,80);arc(80,80,20,0,1.571,false);lineTo(30,100);arc(30,70,30,1.571,3.142,false);lineTo(0,0);arc(0,0,0,3.142,4.712,false);closePath();fillStyle=black;fill();restore();'
);
});
// ======================================================
it('corner radius with negative width and height', function () {
var stage = addStage();
var layer = new Konva.Layer();
var rect = new Konva.Rect({
x: 100,
y: 100,
width: -100,
height: -100,
fill: 'black',
cornerRadius: [0, 10, 20, 30],
});
layer.add(rect);
stage.add(layer);
layer.draw();
var trace = layer.getContext().getTrace();
assert.equal(
trace,
'clearRect(0,0,578,200);save();transform(1,0,0,1,100,100);beginPath();moveTo(-100,-100);lineTo(-10,-100);arc(-10,-90,10,4.712,0,false);lineTo(0,-20);arc(-20,-20,20,0,1.571,false);lineTo(-70,0);arc(-70,-30,30,1.571,3.142,false);lineTo(-100,-100);arc(-100,-100,0,3.142,4.712,false);closePath();fillStyle=black;fill();restore();clearRect(0,0,578,200);save();transform(1,0,0,1,100,100);beginPath();moveTo(-100,-100);lineTo(-10,-100);arc(-10,-90,10,4.712,0,false);lineTo(0,-20);arc(-20,-20,20,0,1.571,false);lineTo(-70,0);arc(-70,-30,30,1.571,3.142,false);lineTo(-100,-100);arc(-100,-100,0,3.142,4.712,false);closePath();fillStyle=black;fill();restore();'
);
});
});