Skip to content

Commit c5e578d

Browse files
authored
Fix large arc (#25)
* Fix large arc not to be drawn too rough * Add changeset * Update
1 parent 0c9211d commit c5e578d

File tree

2 files changed

+48
-30
lines changed

2 files changed

+48
-30
lines changed

.changeset/happy-cooks-kiss.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"slidev-addon-fancy-arrow": patch
3+
---
4+
5+
Fix large arcs not to be drawn too rough

components/use-rough-arrow.ts

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,7 @@ export function useRoughArrow(props: {
6161
twoWay,
6262
centerPositionParam,
6363
} = props;
64-
const options = {
65-
stroke: "currentColor",
66-
strokeWidth: width,
67-
fill: "currentColor",
68-
fillStyle: "solid",
64+
const baseOptions = {
6965
// We don't support the `bowing` param because it's not so effective for arc.
7066
...(roughness !== undefined && { roughness }),
7167
...(seed !== undefined && { seed }),
@@ -88,6 +84,12 @@ export function useRoughArrow(props: {
8884
return;
8985
}
9086

87+
const lineOptions = {
88+
...baseOptions,
89+
stroke: "currentColor",
90+
strokeWidth: width,
91+
};
92+
9193
if (centerPositionParam === 0) {
9294
// Straight line.
9395
// This can be interpreted as the arc's center is at infinity.
@@ -96,7 +98,7 @@ export function useRoughArrow(props: {
9698
point1.y,
9799
point2.x,
98100
point2.y,
99-
options,
101+
lineOptions,
100102
);
101103
const angle =
102104
Math.atan2(point2.y - point1.y, point2.x - point1.x) - Math.PI / 2;
@@ -163,16 +165,18 @@ export function useRoughArrow(props: {
163165
endAngle += 2 * Math.PI;
164166
}
165167

166-
const D = 2 * R;
167-
const svg = roughSvg.arc(
168-
center.x,
169-
center.y,
170-
D,
171-
D,
172-
startAngle,
173-
endAngle,
174-
false,
175-
options,
168+
// RoughJS has .arc() method as follows with which we can more easily understand what arc we are drawing (that's why we left it commented out),
169+
// however, it doesn't work well in our case as https://github.com/whitphx/slidev-addon-fancy-arrow/issues/17
170+
// because large arcs are drawn too rough with it.
171+
// const D = 2 * R;
172+
// const svg = roughSvg.arc(center.x, center.y, D, D, startAngle, endAngle, false, lineOptions);
173+
// So we use .path() instead as below.
174+
const largeArcFlag =
175+
centerPositionParam < -1 || 1 < centerPositionParam ? 1 : 0;
176+
const sweepFlag = centerPositionParam > 0 ? 1 : 0;
177+
const svg = roughSvg.path(
178+
`M${point1.x} ${point1.y} A${R} ${R} 0 ${largeArcFlag} ${sweepFlag} ${point2.x} ${point2.y}`,
179+
lineOptions,
176180
);
177181

178182
return {
@@ -197,22 +201,28 @@ export function useRoughArrow(props: {
197201
return (30 * Math.log(line.value.lineLength)) / Math.log(200);
198202
});
199203

200-
const arrowHead1 = computed(() =>
201-
createArrowHeadSvg(
204+
const arrowHeads = computed(() => {
205+
const arrowHeadOptions = {
206+
...baseOptions,
207+
stroke: "currentColor",
208+
strokeWidth: width,
209+
fill: "currentColor",
210+
fillStyle: "solid",
211+
};
212+
const arrowHead1 = createArrowHeadSvg(
202213
rc.value as RoughSVG,
203214
computedArrowHeadSize.value,
204215
arrowHeadType,
205-
options,
206-
),
207-
);
208-
const arrowHead2 = computed(() =>
209-
createArrowHeadSvg(
216+
arrowHeadOptions,
217+
);
218+
const arrowHead2 = createArrowHeadSvg(
210219
rc.value as RoughSVG,
211220
computedArrowHeadSize.value,
212221
arrowHeadType,
213-
options,
214-
),
215-
);
222+
arrowHeadOptions,
223+
);
224+
return [arrowHead1, arrowHead2];
225+
});
216226

217227
return computed(() => {
218228
svg.value.innerHTML = "";
@@ -227,18 +237,21 @@ export function useRoughArrow(props: {
227237

228238
svg.value.appendChild(line.value.svg);
229239

230-
arrowHead2.value.setAttribute(
240+
const arrowHead1 = arrowHeads.value[0];
241+
const arrowHead2 = arrowHeads.value[1];
242+
243+
arrowHead2.setAttribute(
231244
"transform",
232245
`translate(${point2Ref.value.x},${point2Ref.value.y}) rotate(${(line.value.angle2 * 180) / Math.PI + (centerPositionParam >= 0 ? 90 : -90)})`,
233246
);
234-
svg.value.appendChild(arrowHead2.value);
247+
svg.value.appendChild(arrowHead2);
235248

236249
if (twoWay) {
237-
arrowHead1.value.setAttribute(
250+
arrowHead1.setAttribute(
238251
"transform",
239252
`translate(${point1Ref.value.x},${point1Ref.value.y}) rotate(${(line.value.angle1 * 180) / Math.PI + (centerPositionParam >= 0 ? -90 : 90)})`,
240253
);
241-
svg.value.appendChild(arrowHead1.value);
254+
svg.value.appendChild(arrowHead1);
242255
}
243256

244257
return svg.value.innerHTML;

0 commit comments

Comments
 (0)