fix(editor): recalculate roundness type when switching shape types (#11473)

When converting between generic shapes, the roundness type was only
recalculated when the target type was a diamond. Converting a diamond
(which uses the proportional radius algorithm) back to a rectangle kept
the proportional radius, so rectangles ended up rendering with overly
round corners.

---------

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Co-authored-by: Maruthan G <maruthang4@gmail.com>
Co-authored-by: Sivram <withsivram@gmail.com>
Co-authored-by: Jai Kumar Dewani <jai.dewani.99@gmail.com>
Co-authored-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Augusto Xavier
2026-06-11 14:17:15 -03:00
committed by GitHub
parent 0cf56b19c7
commit a83ac48853
4 changed files with 59 additions and 15 deletions
@@ -831,14 +831,13 @@ const convertElementType = <
newElement({
...element,
type: targetType,
roundness:
targetType === "diamond" && element.roundness
? {
type: isUsingAdaptiveRadius(targetType)
? ROUNDNESS.ADAPTIVE_RADIUS
: ROUNDNESS.PROPORTIONAL_RADIUS,
}
: element.roundness,
roundness: element.roundness
? {
type: isUsingAdaptiveRadius(targetType)
? ROUNDNESS.ADAPTIVE_RADIUS
: ROUNDNESS.PROPORTIONAL_RADIUS,
}
: element.roundness,
}),
) as typeof element;
@@ -0,0 +1,46 @@
import { ROUNDNESS } from "@excalidraw/common";
import { convertElementTypes } from "../components/ConvertElementTypePopup";
import { Excalidraw } from "../index";
import { API } from "./helpers/api";
import { act, render } from "./test-utils";
const { h } = window;
describe("convert element type", () => {
beforeEach(async () => {
await render(<Excalidraw handleKeyboardGlobally={true} />);
});
// #9662
it("recalculates roundness type when switching between generic shapes", () => {
const rectangle = API.createElement({
type: "rectangle",
roundness: { type: ROUNDNESS.ADAPTIVE_RADIUS }, // Dooesn't matter as long as it is set
});
API.setElements([rectangle]);
API.setSelectedElements([rectangle]);
act(() => {
convertElementTypes(h.app, {
conversionType: "generic",
nextType: "diamond",
});
});
expect(h.elements[0].type).toBe("diamond");
expect(h.elements[0].roundness?.type).toBe(ROUNDNESS.PROPORTIONAL_RADIUS);
act(() => {
convertElementTypes(h.app, {
conversionType: "generic",
nextType: "rectangle",
});
});
expect(h.elements[0].type).toBe("rectangle");
expect(h.elements[0].roundness?.type).toBe(ROUNDNESS.ADAPTIVE_RADIUS);
});
});
@@ -154,7 +154,7 @@ exports[`restoreElements > should restore correctly with rectangle, ellipse and
"opacity": 10,
"roughness": 2,
"roundness": {
"type": 3,
"type": 2,
},
"seed": Any<Number>,
"strokeColor": "red",
@@ -192,7 +192,7 @@ exports[`restoreElements > should restore correctly with rectangle, ellipse and
"opacity": 10,
"roughness": 2,
"roundness": {
"type": 3,
"type": 2,
},
"seed": Any<Number>,
"strokeColor": "red",
+4 -5
View File
@@ -19,8 +19,7 @@ import {
newTextElement,
} from "@excalidraw/element";
import { isLinearElementType } from "@excalidraw/element";
import { getSelectedElements } from "@excalidraw/element";
import { isUsingAdaptiveRadius, getSelectedElements } from "@excalidraw/element";
import { selectGroupsForSelectedElements } from "@excalidraw/element";
import { FONT_SIZES } from "@excalidraw/common";
@@ -267,9 +266,9 @@ export class API {
: rest.roundness
)
? {
type: isLinearElementType(type)
? ROUNDNESS.PROPORTIONAL_RADIUS
: ROUNDNESS.ADAPTIVE_RADIUS,
type: isUsingAdaptiveRadius(type)
? ROUNDNESS.ADAPTIVE_RADIUS
: ROUNDNESS.PROPORTIONAL_RADIUS,
}
: null,
roughness: rest.roughness ?? appState.currentItemRoughness,