Skip to content

Commit

Permalink
fix: Regard lineCap to derive lineDash
Browse files Browse the repository at this point in the history
- Because the length of segments change depending on lineCap
  • Loading branch information
miyanokomiya committed Oct 9, 2024
1 parent 2a6cbd4 commit c4ac861
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/components/floatMenu/StrokePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ColorPickerPanel } from "../molecules/ColorPickerPanel";
import { Color, LineDash, StrokeStyle } from "../../models";
import { SliderInput } from "../atoms/inputs/SliderInput";
import { ToggleInput } from "../atoms/inputs/ToggleInput";
import { getLineCap, getLineDap, getLineDashArray, getLineJoin } from "../../utils/strokeStyle";
import { getLineCap, getLineDap, getLineDashArrayWithCap, getLineJoin } from "../../utils/strokeStyle";
import { InlineField } from "../atoms/InlineField";
import { BlockGroupField } from "../atoms/BlockGroupField";

Expand Down Expand Up @@ -158,7 +158,7 @@ interface LineDashButtonProps {

const LineDashButton: React.FC<LineDashButtonProps> = ({ lineDash, highlight, onClick }) => {
const dashArray = useMemo(() => {
return getLineDashArray(lineDash, 4).join(" ");
return getLineDashArrayWithCap(lineDash, "butt", 4).join(" ");
}, [lineDash]);

const handleClick = useCallback(() => {
Expand Down
14 changes: 12 additions & 2 deletions src/utils/strokeStyle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect, describe, test, vi } from "vitest";
import {
applyStrokeStyle,
createStrokeStyle,
getLineDashArray,
getLineDashArrayWithCap,
isSameStrokeStyle,
renderStrokeSVGAttributes,
} from "./strokeStyle";
Expand Down Expand Up @@ -80,7 +80,17 @@ describe("renderStrokeSVGAttributes", () => {
"stroke-width": 10,
"stroke-linecap": "round",
"stroke-linejoin": "bevel",
"stroke-dasharray": getLineDashArray("dot", 10).join(" "),
"stroke-dasharray": getLineDashArrayWithCap("dot", "round", 10).join(" "),
});
});
});

describe("getLineDashArrayWithCap", () => {
test("should adjust dash array when line cap isn't butt", () => {
expect(getLineDashArrayWithCap("dot", "butt", 10)).toEqual([10, 10]);
expect(getLineDashArrayWithCap("dot", "round", 10)).toEqual([0.01, 20]);
expect(getLineDashArrayWithCap("dot", "square", 10)).toEqual([0.01, 20]);
expect(getLineDashArrayWithCap("short", "round", 10)).toEqual([20, 20]);
expect(getLineDashArrayWithCap("long", "round", 10)).toEqual([50, 20]);
});
});
28 changes: 25 additions & 3 deletions src/utils/strokeStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function applyStrokeStyle(ctx: CanvasRenderingContext2D, stroke: StrokeSt
ctx.strokeStyle = rednerRGBA(stroke.color);
const width = getStrokeWidth(stroke);
ctx.lineWidth = width;
ctx.setLineDash(getLineDashArray(stroke.dash, width));
ctx.setLineDash(getLineDashArrayWithCap(stroke.dash, stroke.lineCap, width));
ctx.lineCap = getLineCap(stroke.lineCap);
ctx.lineJoin = getLineJoin(stroke.lineJoin);
}
Expand All @@ -54,7 +54,7 @@ export function applyDefaultStrokeStyle(ctx: CanvasRenderingContext2D) {
ctx.lineJoin = "miter";
}

export function getLineDashArray(lineDash: LineDash, width = 1): number[] {
function getLineDashArray(lineDash: LineDash, width = 1): number[] {
switch (lineDash) {
case "dot":
return [width, width];
Expand All @@ -67,6 +67,26 @@ export function getLineDashArray(lineDash: LineDash, width = 1): number[] {
}
}

export function getLineDashArrayWithCap(lineDash: LineDash, lineCap: CanvasLineCap = "butt", width = 1): number[] {
switch (lineCap) {
case "butt":
return getLineDashArray(lineDash, width);
default: {
switch (lineDash) {
case "dot":
// Stroke part must have nonzero value to keep the direction
return [0.01, width * 2];
case "short":
return [width * 2, width * 2];
case "long":
return [width * 5, width * 2];
default:
return [];
}
}
}
}

export function renderStrokeSVGAttributes(stroke: StrokeStyle): SVGAttributes {
return stroke.disabled
? { stroke: "none" }
Expand All @@ -76,6 +96,8 @@ export function renderStrokeSVGAttributes(stroke: StrokeStyle): SVGAttributes {
"stroke-width": stroke.width,
"stroke-linecap": getLineCap(stroke.lineCap),
"stroke-linejoin": getLineJoin(stroke.lineJoin),
"stroke-dasharray": stroke.dash ? getLineDashArray(stroke.dash, stroke.width).join(" ") : undefined,
"stroke-dasharray": stroke.dash
? getLineDashArrayWithCap(stroke.dash, stroke.lineCap, stroke.width).join(" ")
: undefined,
};
}

0 comments on commit c4ac861

Please sign in to comment.