diff --git a/src/components/icons.tsx b/src/components/icons.tsx
index e8174788..2c9debfd 100644
--- a/src/components/icons.tsx
+++ b/src/components/icons.tsx
@@ -222,14 +222,12 @@ export const SendToBackIcon = React.memo(
d="M18 7.333C18 6.597 17.403 6 16.667 6H7.333C6.597 6 6 6.597 6 7.333v9.334C6 17.403 6.597 18 7.333 18h9.334c.736 0 1.333-.597 1.333-1.333V7.333z"
fill={activeElementColor(theme)}
stroke={activeElementColor(theme)}
- strokeLinejoin="round"
strokeWidth="2"
/>
>,
@@ -335,7 +333,6 @@ export const DistributeHorizontallyIcon = React.memo(
({ theme }: { theme: "light" | "dark" }) =>
createIcon(
<>
-
stroke={iconFillColor(theme)}
strokeWidth="2"
/>
-
-
-
-
+ >
+
+
+
+
+
>,
{ width: 182, height: 182, mirror: true },
),
@@ -536,60 +507,18 @@ export const UngroupIcon = React.memo(
stroke={iconFillColor(theme)}
strokeWidth="2"
/>
-
-
-
-
-
-
+ >
+
+
+
+
+
+
+
>,
{ width: 182, height: 182, mirror: true },
),
@@ -631,9 +560,10 @@ export const StrokeWidthIcon = React.memo(
({ theme, strokeWidth }: { theme: "light" | "dark"; strokeWidth: number }) =>
createIcon(
,
{ width: 40, height: 20 },
@@ -648,6 +578,7 @@ export const StrokeStyleSolidIcon = React.memo(
stroke={iconFillColor(theme)}
strokeWidth={2}
fill="none"
+ strokeLinecap="round"
/>,
{
width: 40,
@@ -665,6 +596,7 @@ export const StrokeStyleDashedIcon = React.memo(
strokeWidth={2.5}
strokeDasharray={"10, 8"}
fill="none"
+ strokeLinecap="round"
/>,
{ width: 40, height: 20 },
),
@@ -674,11 +606,12 @@ export const StrokeStyleDottedIcon = React.memo(
({ theme }: { theme: "light" | "dark" }) =>
createIcon(
,
{ width: 40, height: 20 },
),
@@ -691,6 +624,7 @@ export const SloppinessArchitectIcon = React.memo(
d="M3.00098 16.1691C6.28774 13.9744 19.6399 2.8905 22.7215 3.00082C25.8041 3.11113 19.1158 15.5488 21.4962 16.8309C23.8757 18.1131 34.4155 11.7148 37.0001 10.6919"
stroke={iconFillColor(theme)}
strokeWidth={2}
+ strokeLinecap="round"
fill="none"
/>,
{ width: 40, height: 20, mirror: true },
@@ -704,6 +638,7 @@ export const SloppinessArtistIcon = React.memo(
d="M3 17C6.68158 14.8752 16.1296 9.09849 22.0648 6.54922C28 3.99995 22.2896 13.3209 25 14C27.7104 14.6791 36.3757 9.6471 36.3757 9.6471M6.40706 15C13 11.1918 20.0468 1.51045 23.0234 3.0052C26 4.49995 20.457 12.8659 22.7285 16.4329C25 20 36.3757 13 36.3757 13"
stroke={iconFillColor(theme)}
strokeWidth={2}
+ strokeLinecap="round"
fill="none"
/>,
{ width: 40, height: 20, mirror: true },
@@ -717,6 +652,7 @@ export const SloppinessCartoonistIcon = React.memo(
d="M3 15.6468C6.93692 13.5378 22.5544 2.81528 26.6206 3.00242C30.6877 3.18956 25.6708 15.3346 27.4009 16.7705C29.1309 18.2055 35.4001 12.4762 37 11.6177M3.97143 10.4917C6.61158 9.24563 16.3706 2.61886 19.8104 3.01724C23.2522 3.41472 22.0773 12.2013 24.6181 12.8783C27.1598 13.5536 33.3179 8.04068 35.0571 7.07244"
stroke={iconFillColor(theme)}
strokeWidth={2}
+ strokeLinecap="round"
fill="none"
/>,
{ width: 40, height: 20, mirror: true },
@@ -730,6 +666,7 @@ export const EdgeSharpIcon = React.memo(
d="M10 17L10 5L35 5"
stroke={iconFillColor(theme)}
strokeWidth={2}
+ strokeLinecap="round"
fill="none"
/>,
{ width: 40, height: 20, mirror: true },
@@ -743,6 +680,7 @@ export const EdgeRoundIcon = React.memo(
d="M10 17V15C10 8 13 5 21 5L33.5 5"
stroke={iconFillColor(theme)}
strokeWidth={2}
+ strokeLinecap="round"
fill="none"
/>,
{ width: 40, height: 20, mirror: true },
@@ -902,6 +840,7 @@ export const TextAlignLeftIcon = React.memo(
,
{ width: 448, height: 512 },
),
@@ -924,6 +863,7 @@ export const TextAlignRightIcon = React.memo(
,
{ width: 448, height: 512 },
),
diff --git a/src/locales/en.json b/src/locales/en.json
index 72581b4a..d5d292be 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -158,6 +158,7 @@
"ellipse": "Ellipse",
"arrow": "Arrow",
"line": "Line",
+ "freedraw": "Draw",
"text": "Text",
"library": "Library",
"lock": "Keep selected tool active after drawing"
diff --git a/src/renderer/renderElement.ts b/src/renderer/renderElement.ts
index 9485a033..24070da9 100644
--- a/src/renderer/renderElement.ts
+++ b/src/renderer/renderElement.ts
@@ -32,8 +32,8 @@ const defaultAppState = getDefaultAppState();
const CANVAS_PADDING = 20;
-const DASHARRAY_DASHED = [12, 8];
-const DASHARRAY_DOTTED = [3, 6];
+const getDashArrayDashed = (strokeWidth: number) => [8, 8 + strokeWidth];
+const getDashArrayDotted = (strokeWidth: number) => [1.5, 6 + strokeWidth];
export interface ExcalidrawElementWithCanvas {
element: ExcalidrawElement | ExcalidrawTextElement;
@@ -122,12 +122,17 @@ const drawElementOnCanvas = (
case "rectangle":
case "diamond":
case "ellipse": {
+ context.lineJoin = "round";
+ context.lineCap = "round";
rc.draw(getShapeForElement(element) as Drawable);
break;
}
case "arrow":
case "draw":
case "line": {
+ context.lineJoin = "round";
+ context.lineCap = "round";
+
(getShapeForElement(element) as Drawable[]).forEach((shape) => {
rc.draw(shape);
});
@@ -202,9 +207,9 @@ export const generateRoughOptions = (element: ExcalidrawElement): Options => {
seed: element.seed,
strokeLineDash:
element.strokeStyle === "dashed"
- ? DASHARRAY_DASHED
+ ? getDashArrayDashed(element.strokeWidth)
: element.strokeStyle === "dotted"
- ? DASHARRAY_DOTTED
+ ? getDashArrayDotted(element.strokeWidth)
: undefined,
// for non-solid strokes, disable multiStroke because it tends to make
// dashes/dots overlay each other
@@ -568,6 +573,7 @@ export const renderElementToSvg = (
node.setAttribute("stroke-opacity", `${opacity}`);
node.setAttribute("fill-opacity", `${opacity}`);
}
+ node.setAttribute("stroke-linecap", "round");
node.setAttribute(
"transform",
`translate(${offsetX || 0} ${
@@ -583,6 +589,8 @@ export const renderElementToSvg = (
generateElementShape(element, generator);
const group = svgRoot.ownerDocument!.createElementNS(SVG_NS, "g");
const opacity = element.opacity / 100;
+ group.setAttribute("stroke-linecap", "round");
+
(getShapeForElement(element) as Drawable[]).forEach((shape) => {
const node = rsvg.draw(shape);
if (opacity !== 1) {
diff --git a/src/tests/scene/__snapshots__/export.test.ts.snap b/src/tests/scene/__snapshots__/export.test.ts.snap
index 56dfa7b7..a482bf18 100644
--- a/src/tests/scene/__snapshots__/export.test.ts.snap
+++ b/src/tests/scene/__snapshots__/export.test.ts.snap
@@ -35,6 +35,7 @@ exports[`exportToSvg with default arguments 1`] = `