1
1
mirror of https://github.com/varkor/quiver.git synced 2024-09-17 17:09:31 +03:00

Use an SVG for edge backgrounds

This is a first step in implementing curved edges.
This commit is contained in:
varkor 2019-01-15 16:34:32 +00:00
parent ee48cc1d97
commit 9599d3f030
2 changed files with 36 additions and 15 deletions

View File

@ -233,20 +233,20 @@ body {
}
/* This is so explicit because of the CSS specificity rules. */
.ui.default .edge:hover:not(.selected):not(.source):not(.target) {
background: var(--cell-hover);
.ui.default .edge:hover:not(.selected):not(.source):not(.target) svg.background {
stroke: var(--cell-hover);
}
.edge.source {
background: var(--cell-source);
.edge.source svg.background {
stroke: var(--cell-source);
}
.edge.target {
background: var(--cell-target);
.edge.target svg.background {
stroke: var(--cell-target);
}
.edge.selected {
background: var(--cell-selected);
.edge.selected svg.background {
stroke: var(--cell-selected);
}
.edge .label {

View File

@ -3136,18 +3136,21 @@ class Edge extends Cell {
/// Create the HTML element associated with the edge.
render(ui, pointer_position = null) {
let svg = null;
let [svg, background] = [null, null];
if (this.element !== null) {
// If an element already exists for the edge, then can mostly reuse it when
// re-rendering it.
svg = this.element.querySelector("svg");
svg = this.element.querySelector("svg:not(.background)");
background = this.element.querySelector("svg.background");
// Clear the SVG: we're going to be completely redrawing it. We're going to keep around
// any definitions, though, as we can effectively reuse them.
for (const child of Array.from(svg.childNodes)) {
if (child.tagName !== "defs") {
child.remove();
// Clear the SVGs: we're going to be completely redrawing it. We're going to keep
// around any definitions, though, as we can effectively reuse them.
for (const element of [svg, background]) {
for (const child of Array.from(element.childNodes)) {
if (child.tagName !== "defs") {
child.remove();
}
}
}
} else {
@ -3175,6 +3178,11 @@ class Edge extends Cell {
}));
};
// Create the background. We use an SVG rather than colouring the background
// of the element so that we can curve it according to the edge shape.
background = new DOM.SVGElement("svg", { class: "background" }).element;
this.element.appendChild(background);
// Create the endpoint handles.
for (const end of ["source", "target"]) {
const handle = new DOM.Element("div", { class: `handle ${end}` });
@ -3267,6 +3275,7 @@ class Edge extends Cell {
this.options,
endpoint_offset,
null,
background,
);
// Apply the mask to the edge.
@ -3313,6 +3322,7 @@ class Edge extends Cell {
options,
endpoint_offset,
gap,
background = null,
) {
// Constants for parameters of the arrow shapes.
const SVG_PADDING = Edge.SVG_PADDING;
@ -3339,6 +3349,17 @@ class Edge extends Cell {
}
const { dimensions, alignment } = Edge.draw_edge(svg, options, length, gap, true);
if (background !== null) {
background.setAttribute("width", dimensions.width);
background.setAttribute("height", dimensions.height + EDGE_PADDING * 2);
background.appendChild(new DOM.SVGElement("path", {
d: `M 0 ${EDGE_PADDING + dimensions.height / 2} l ${dimensions.width} 0`,
}, {
strokeWidth: `${dimensions.height + EDGE_PADDING * 2}px`,
}).element);
}
// If the arrow is shorter than expected (for example, because we are using a
// fixed-width arrow style), then we need to make sure that it's still centred
// if the `alignment` is `"centre"`.