[Editor] Remove the outline which is inside the free highlight shape

When an highlight is self-intersecting, the outline was drawn inside.
In order to remove it, we use a svg mask to exclude the shape inside
when drawing the outlines.
That leads to change the outline 1px,white-2px,blue-1px,white to a
2px,white-2px,blue: the part of the stroke which is inside the shape
is removed because of the mask.
This commit is contained in:
Calixte Denizet 2024-01-26 17:16:07 +01:00
parent 4ec43488ff
commit b88c6f9c39
2 changed files with 68 additions and 14 deletions

View File

@ -135,9 +135,33 @@ class DrawLayer {
path.setAttribute("d", outlines.toSVGPath());
path.setAttribute("vector-effect", "non-scaling-stroke");
let maskId;
if (outlines.free) {
root.classList.add("free");
const mask = DrawLayer._svgFactory.createElement("mask");
defs.append(mask);
maskId = `mask_p${this.pageIndex}_${id}`;
mask.setAttribute("id", maskId);
mask.setAttribute("maskUnits", "objectBoundingBox");
const rect = DrawLayer._svgFactory.createElement("rect");
mask.append(rect);
rect.setAttribute("width", "1");
rect.setAttribute("height", "1");
rect.setAttribute("fill", "white");
const use = DrawLayer._svgFactory.createElement("use");
mask.append(use);
use.setAttribute("href", `#${pathId}`);
use.setAttribute("stroke", "none");
use.setAttribute("fill", "black");
use.setAttribute("fill-rule", "nonzero");
}
const use1 = DrawLayer._svgFactory.createElement("use");
root.append(use1);
use1.setAttribute("href", `#${pathId}`);
if (maskId) {
use1.setAttribute("mask", `url(#${maskId})`);
}
const use2 = use1.cloneNode();
root.append(use2);
use1.classList.add("mainOutline");

View File

@ -56,7 +56,8 @@
fill-rule: evenodd;
fill: none;
&.hovered {
&:not(.free) {
&.hovered:not(.selected) {
stroke: var(--hover-outline-color);
stroke-width: var(--outline-width);
}
@ -75,5 +76,34 @@
}
}
}
&.free {
/*
When drawing the outline we use a mask in order to remove the parts
that are inside the shape. Unfortunately, this removes the part of the
outline that is inside the shape. To "fix" this we increase the width
to have what we want to be visible outside the shape.
This is not a perfect solution, but it works well enough.
*/
&.hovered:not(.selected) {
stroke: var(--hover-outline-color);
stroke-width: calc(2 * var(--outline-width));
}
&.selected {
.mainOutline {
stroke: var(--outline-around-color);
stroke-width: calc(
2 * (var(--outline-width) + var(--outline-around-width))
);
}
.secondaryOutline {
stroke: var(--outline-color);
stroke-width: calc(2 * var(--outline-width));
}
}
}
}
}
}