Spaces:
Sleeping
Sleeping
| const d_connector_top = 5; | |
| const d_connector_mask = 0; | |
| function connect(mask, tbox, index) { | |
| const tbox_rect = tbox.getBoundingClientRect(); | |
| const img = document.querySelector(".image-wrapper img"); | |
| const img_rect = img.getBoundingClientRect(); | |
| let coords; | |
| if (tbox.classList.contains("right")) { | |
| coords = connectToRight(mask, img_rect, tbox_rect); | |
| } else { | |
| coords = connectToLeft(mask, img_rect, tbox_rect); | |
| } | |
| // get the border color of this mask | |
| const maskColor = mask.dataset.color; | |
| // --- build a fresh SVG connector --- | |
| const connector = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | |
| connector.setAttribute("width", "1px"); | |
| connector.setAttribute("height", "1px"); | |
| connector.setAttribute("class", "connector"); | |
| connector.setAttribute("id", `connector${index}`); | |
| connector.style.position = "absolute"; | |
| connector.style.top = coords.top + "px"; | |
| connector.style.left = coords.left + "px"; | |
| // straight line | |
| const straight = document.createElementNS("http://www.w3.org/2000/svg", "line"); | |
| straight.setAttribute("class", "straight"); | |
| straight.setAttribute("x1", coords.x0); | |
| straight.setAttribute("y1", coords.y0); | |
| straight.setAttribute("x2", coords.x1); | |
| straight.setAttribute("y2", coords.y1); | |
| straight.setAttribute("stroke", maskColor); | |
| // diagonal line | |
| const diagonal = document.createElementNS("http://www.w3.org/2000/svg", "line"); | |
| diagonal.setAttribute("class", "diagonal"); | |
| diagonal.setAttribute("x1", coords.x1); | |
| diagonal.setAttribute("y1", coords.y1); | |
| diagonal.setAttribute("x2", coords.x2); | |
| diagonal.setAttribute("y2", coords.y2); | |
| diagonal.setAttribute("stroke", maskColor); | |
| connector.appendChild(straight); | |
| connector.appendChild(diagonal); | |
| const wrapper = document.querySelector(".image-wrapper"); | |
| wrapper.appendChild(connector); | |
| } | |
| function connectToRight(mask, img_rect, tbox_rect) { | |
| const width = img_rect.width; | |
| const height = img_rect.height; | |
| const top = parseFloat(mask.dataset.top) * height; | |
| const left = parseFloat(mask.dataset.left) * width; | |
| const w1 = img_rect.right - (img_rect.left + left) + 15; | |
| const w2 = tbox_rect.left - (img_rect.left + left) - w1 - d_connector_mask; | |
| const h2 = (tbox_rect.top + tbox_rect.bottom) / 2 - (img_rect.top + top) - d_connector_top; | |
| const [x0, y0] = [0, 0]; | |
| const [x1, y1] = [x0 + w1, 0]; | |
| const [x2, y2] = [x0 + w1 + w2, h2]; | |
| return { top, left, x0, y0, x1, y1, x2, y2 }; | |
| } | |
| function connectToLeft(mask, img_rect, tbox_rect) { | |
| const width = img_rect.width; | |
| const height = img_rect.height; | |
| const top = parseFloat(mask.dataset.top) * height; | |
| const left = parseFloat(mask.dataset.left) * width; | |
| const w1 = left + 15; | |
| const w2 = (img_rect.left + left) - tbox_rect.right - w1 - d_connector_mask; | |
| const h2 = (tbox_rect.top + tbox_rect.bottom) / 2 - (img_rect.top + top) - d_connector_top; | |
| const [x0, y0] = [0, 0]; | |
| const [x1, y1] = [x0 - w1, 0]; | |
| const [x2, y2] = [x0 - w1 - w2, h2]; | |
| return { top, left, x0, y0, x1, y1, x2, y2 }; | |
| } | |
| function redrawAll() { | |
| const wrapper = document.querySelector(".image-wrapper"); | |
| // clear old connectors first | |
| wrapper.querySelectorAll("svg.connector").forEach(el => el.remove()); | |
| const masks = document.querySelectorAll(".svg"); | |
| masks.forEach((mask, index) => { | |
| const tbox = document.querySelector(`#tbox${index}`); | |
| if (tbox) { | |
| connect(mask, tbox, index); | |
| } | |
| }); | |
| } | |
| redrawAll(); | |
| window.addEventListener("resize", redrawAll); | |
| window.addEventListener("scroll", redrawAll); |