diff --git a/packages/excalidraw/element/typeChecks.ts b/packages/excalidraw/element/typeChecks.ts index ef1bcd3dbc..7193e251b3 100644 --- a/packages/excalidraw/element/typeChecks.ts +++ b/packages/excalidraw/element/typeChecks.ts @@ -214,7 +214,10 @@ export const isBoundToContainer = ( }; export const isUsingAdaptiveRadius = (type: string) => - type === "rectangle" || type === "embeddable" || type === "iframe"; + type === "rectangle" || + type === "embeddable" || + type === "iframe" || + type === "image"; export const isUsingProportionalRadius = (type: string) => type === "line" || type === "arrow" || type === "diamond"; diff --git a/packages/excalidraw/renderer/renderElement.ts b/packages/excalidraw/renderer/renderElement.ts index 5ab3f3ca52..de4bcfe533 100644 --- a/packages/excalidraw/renderer/renderElement.ts +++ b/packages/excalidraw/renderer/renderElement.ts @@ -344,6 +344,17 @@ const drawElementOnCanvas = ( ? renderConfig.imageCache.get(element.fileId)?.image : undefined; if (img != null && !(img instanceof Promise)) { + if (element.roundness && context.roundRect) { + context.beginPath(); + context.roundRect( + 0, + 0, + element.width, + element.height, + getCornerRadius(Math.min(element.width, element.height), element), + ); + context.clip(); + } context.drawImage( img, 0 /* hardcoded for the selection box*/, @@ -1301,6 +1312,31 @@ export const renderElementToSvg = ( }) rotate(${degree} ${cx} ${cy})`, ); + if (element.roundness) { + const clipPath = svgRoot.ownerDocument!.createElementNS( + SVG_NS, + "clipPath", + ); + clipPath.id = `image-clipPath-${element.id}`; + + const clipRect = svgRoot.ownerDocument!.createElementNS( + SVG_NS, + "rect", + ); + const radius = getCornerRadius( + Math.min(element.width, element.height), + element, + ); + clipRect.setAttribute("width", `${element.width}`); + clipRect.setAttribute("height", `${element.height}`); + clipRect.setAttribute("rx", `${radius}`); + clipRect.setAttribute("ry", `${radius}`); + clipPath.appendChild(clipRect); + addToRoot(clipPath, element); + + g.setAttributeNS(SVG_NS, "clip-path", `url(#${clipPath.id})`); + } + const clipG = maybeWrapNodesInFrameClipPath( element, root, diff --git a/packages/excalidraw/scene/comparisons.ts b/packages/excalidraw/scene/comparisons.ts index 551aa2e6e5..cb14d5810b 100644 --- a/packages/excalidraw/scene/comparisons.ts +++ b/packages/excalidraw/scene/comparisons.ts @@ -42,7 +42,8 @@ export const canChangeRoundness = (type: ElementOrToolType) => type === "embeddable" || type === "arrow" || type === "line" || - type === "diamond"; + type === "diamond" || + type === "image"; export const canHaveArrowheads = (type: ElementOrToolType) => type === "arrow"; diff --git a/packages/excalidraw/tests/__snapshots__/export.test.tsx.snap b/packages/excalidraw/tests/__snapshots__/export.test.tsx.snap index 72b379b8a7..57dff6c1c5 100644 --- a/packages/excalidraw/tests/__snapshots__/export.test.tsx.snap +++ b/packages/excalidraw/tests/__snapshots__/export.test.tsx.snap @@ -21,5 +21,5 @@ exports[`export > exporting svg containing transformed images > svg export outpu - " + " `;