Skip to content

Commit

Permalink
Fix issue #1788 (can't use path as clip mask)
Browse files Browse the repository at this point in the history
  • Loading branch information
GeometryCollective committed Jun 10, 2024
1 parent fa97681 commit 00f0429
Showing 1 changed file with 80 additions and 64 deletions.
144 changes: 80 additions & 64 deletions packages/core/src/renderer/Path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,77 +49,93 @@ export const RenderPath = (
shape: Path<number>,
{ canvasSize }: RenderProps,
): SVGGElement => {
// TODO: distinguish between fill opacity and stroke opacity
const startArrowId = shape.name.contents + "-startArrowId";
const endArrowId = shape.name.contents + "-endArrowId";
const elem = document.createElementNS("http://www.w3.org/2000/svg", "g");
const strokeColor = toSvgPaintProperty(shape.strokeColor.contents);
const strokeOpacity = toSvgOpacityProperty(shape.strokeColor.contents);
// Keep track of which input properties we programatically mapped
const attrToNotAutoMap: string[] = [];

const startArrowhead = getArrowhead(shape.startArrowhead.contents);
const endArrowhead = getArrowhead(shape.endArrowhead.contents);
// TODO: distinguish between fill opacity and stroke opacity
const strokeColor = toSvgPaintProperty(shape.strokeColor.contents);
const strokeOpacity = toSvgOpacityProperty(shape.strokeColor.contents);

if (startArrowhead) {
const startArrowId = shape.name.contents + "-startArrowId";
const startArrowheadSize = shape.startArrowheadSize.contents;
const flip = shape.flipStartArrowhead.contents;
elem.appendChild(
arrowHead(
startArrowId,
strokeColor,
strokeOpacity,
startArrowhead,
startArrowheadSize,
flip,
),
);
}
if (endArrowhead) {
const endArrowId = shape.name.contents + "-endArrowId";
const endArrowheadSize = shape.endArrowheadSize.contents;
elem.appendChild(
arrowHead(
endArrowId,
strokeColor,
strokeOpacity,
endArrowhead,
endArrowheadSize,
false,
),
);
}
// Keep track of which input properties we programatically mapped
const attrToNotAutoMap: string[] = [];

// Map/Fill the shape attributes while keeping track of input properties mapped
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
attrToNotAutoMap.push(...attrFill(shape, path));
attrToNotAutoMap.push(...attrStroke(shape, path));

attrToNotAutoMap.push(
"name",
"startArrowhead",
"flipStartArrowhead",
"endArrowhead",
);
path.setAttribute("d", toPathString(shape.d.contents, canvasSize));
attrToNotAutoMap.push("d");

const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
attrToNotAutoMap.push(...attrFill(shape, path));
attrToNotAutoMap.push(...attrStroke(shape, path));
var elem;

path.setAttribute("d", toPathString(shape.d.contents, canvasSize));
attrToNotAutoMap.push("d");
if (startArrowhead) {
path.setAttribute("marker-start", `url(#${startArrowId})`);
attrToNotAutoMap.push("startArrowhead");
}
if (endArrowhead) {
path.setAttribute("marker-end", `url(#${endArrowId})`);
attrToNotAutoMap.push("endArrowhead");
}
elem.appendChild(path);
attrToNotAutoMap.push(...attrTitle(shape, elem));
// TODO: If there are arrowheads, we create a group containing both the marker
// definitions and the path definition. However, this group is not actually
// required by SVG; it's just a kludge we use here so that we can return just
// a single SVGGElement rather than a list. Enclosing in <g>...</g> also
// prevents this path from being used as a clipping mask (if it has arrowheads).
const startArrowhead = getArrowhead(shape.startArrowhead.contents);
const endArrowhead = getArrowhead(shape.endArrowhead.contents);
if( startArrowhead || endArrowhead )
{
const groupElem = document.createElementNS("http://www.w3.org/2000/svg", "g");
const startArrowId = shape.name.contents + "-startArrowId";
const endArrowId = shape.name.contents + "-endArrowId";

// Directly Map across any "unknown" SVG properties
attrAutoFillSvg(shape, elem, attrToNotAutoMap);
if (startArrowhead) {
const startArrowId = shape.name.contents + "-startArrowId";
const startArrowheadSize = shape.startArrowheadSize.contents;
const flip = shape.flipStartArrowhead.contents;
groupElem.appendChild(
arrowHead(
startArrowId,
strokeColor,
strokeOpacity,
startArrowhead,
startArrowheadSize,
flip,
),
);
}
if (endArrowhead) {
const endArrowId = shape.name.contents + "-endArrowId";
const endArrowheadSize = shape.endArrowheadSize.contents;
groupElem.appendChild(
arrowHead(
endArrowId,
strokeColor,
strokeOpacity,
endArrowhead,
endArrowheadSize,
false,
),
);
}

// Map/Fill the shape attributes while keeping track of input properties mapped
attrToNotAutoMap.push(
"name",
"startArrowhead",
"flipStartArrowhead",
"endArrowhead",
);

if (startArrowhead) {
path.setAttribute("marker-start", `url(#${startArrowId})`);
attrToNotAutoMap.push("startArrowhead");
}
if (endArrowhead) {
path.setAttribute("marker-end", `url(#${endArrowId})`);
attrToNotAutoMap.push("endArrowhead");
}
groupElem.appendChild(path);
elem = groupElem;
} else {
elem = path;
}

attrToNotAutoMap.push(...attrTitle(shape, elem));

// Directly Map across any "unknown" SVG properties
attrAutoFillSvg(shape, elem, attrToNotAutoMap);

return elem;
return elem;
};
export default RenderPath;

0 comments on commit 00f0429

Please sign in to comment.