我想找到最簡單的準系統(也就是說,如果可能的話,沒有庫;這是一個學習練習)方法來在組件之間畫一條簡單的線。 
我已經嘗試了幾件事。我還沒有完全作業,他們看起來都需要一些認真的時間來解決它們。我想知道的是正確/首選的方法是什么,以便我將時間花在正確的事情上,這是未來的觀點:
- 我可以在任意兩個盒子之間添加任意數量的連接線,而不僅僅是連續的
- 這些行服從調整大小和向下和向上滾動卡片
- 有些卡片可能沒有終點,而是會終止頁面的左上角,等待卡片滾動到視圖中或被創建。
嘗試
我的第一個想法是左側完整列組件中的<canvas>,但將畫布和其中的繪圖與我的 div 對齊是一種痛苦,并且具有無限滾動的畫布。無法讓它作業。
接下來我嘗試了<div>s。就像McBrackets在這里所做的那樣。為 div 的頂部、底部和外邊緣著色,并將其與有問題的兩張卡片對齊,但是雖然我可以將它相對于卡片 a 定位,但我不知道如何將它停在卡片 b 處。
最后我嘗試了<SVG>s。只需.getElementById()再添加如下以上說明的SVG路徑。IE
const connectingPath =
"M " aRect.left " " aRect.top " "
"H " (aRect.left - 50)
"V " (bRect.top)
"H " (bRect.left);
似乎什么都沒有,事實證明它很難除錯,而且它看起來像一個更復雜的解決方案,因為我需要考慮調整大小等等。
uj5u.com熱心網友回復:
您可以通過從要連接的盒子中進行一些測量來應用類似的東西;offsetTop和clientHeight。
更新為未繪制的卡片要求添加了一些邏輯。
雖然這并不能完全模擬卡片的動態填充,但我進行了更新以展示如何處理僅繪制一張卡片的場景。
- 使用默認值(1 和 5)單擊連接。這將顯示從框 1 開始的打開連接器。
- 單擊“添加框 5”。這將添加缺少的框并更新連接器。
這里剩下的作業是創建一個事件監聽scroll器來檢查連接器串列。從那里您可以檢查兩個框是否出現在 DOM 中(參見checkConnectors函式)。如果它們出現,則傳遞addConnector將它們完全連接的值。
const connectButton = document.getElementById("connect");
const container = document.getElementById("container");
const error = document.getElementById("error");
const addBoxButton = document.getElementById("addBox");
const connectors = new Map();
const getMidpoint = element => element.offsetTop element.clientHeight / 2;
const getElementAtBoxId = id => document.getElementById(`box${id}`);
connectButton.addEventListener("click", () => {
const firstBoxId = document.getElementById("selectFirstBox").value;
const secondBoxId = document.getElementById("selectSecondBox").value;
if (firstBoxId === null && secondBoxId === null) return;
error.style.display = firstBoxId === secondBoxId ? "block" : "none";
if (firstBoxId === secondBoxId) return;
const firstInput = getElementAtBoxId(firstBoxId);
const secondInput = getElementAtBoxId(secondBoxId);
// Check for undrawn cards
if (firstInput && !secondInput || !firstInput && secondInput) {
addConnector(firstBoxId, firstInput, secondBoxId, secondInput, true);
return;
}
const firstBox = firstInput.offsetTop < secondInput.offsetTop ? firstInput : secondInput;
const secondBox = firstInput.offsetTop < secondInput.offsetTop ? secondInput : firstInput;
addConnector(firstBoxId, firstBox, secondBoxId, secondBox);
});
function addConnector(firstBoxId, firstBox, secondBoxId, secondBox, half = false) {
const args = { firstBoxId, firstBox, secondBoxId, secondBox, half };
if (!firstBox && !secondBox) throw new Error(`Invalid params: ${JSON.stringify(args)}`);
const connectorId = `${firstBoxId}:${secondBoxId}`;
let connector, color;
if (connectors.has(connectorId)) color = connectors.get(connectorId).color;
else color = '#' Math.floor(Math.random() * 16777215).toString(16);
if (half) {
const box = firstBox ? firstBox : secondBox;
// if firstBox draw up else draw down
if (firstBox) {
connector = buildConnector(getMidpoint(box), box.parentElement.clientHeight);
connector.style.borderBottom = "unset";
} else {
// similar logic for draw up
}
} else {
connector = buildConnector(getMidpoint(firstBox), getMidpoint(secondBox));
}
connector.style.borderColor = color;
container.appendChild(connector);
connectors.set(connectorId, { ...args, color });
}
function buildConnector(height1, height2) {
const connector = document.createElement("div");
connector.classList.add("connector");
connector.style.top = `${height1}px`;
connector.style.height = `${Math.abs(height2 - height1)}px`;
return connector;
}
window.addEventListener("resize", () => {
for (const connector of connectors.values()) {
const { firstBoxId, firstBox, secondBoxId, secondBox, half } = connector;
if(firstBox || secondBox) {
addConnector(firstBoxId, firstBox, secondBoxId, secondBox, half);
console.log(`resize detected, adjusting connector between ${firstBoxId} and ${secondBoxId}`);
}
}
});
addBoxButton.addEventListener("click", () => {
const box = document.createElement("div");
box.innerText = 5;
box.id = "box5";
box.classList.add("box");
container.appendChild(box);
addBoxButton.style.display = 'none';
// check if connectors need to be updated
checkConnectors();
});
function checkConnectors() {
for (const connector of connectors.values()) {
if (connector.half) {
let { firstBox, firstBoxId, secondBox, secondBoxId } = connector;
firstBox = firstBox ? firstBox : getElementAtBoxId(firstBoxId);
secondBox = secondBox ? secondBox : getElementAtBoxId(secondBoxId);
// both boxes in DOM -> update connector
if (firstBox && secondBox) {
addConnector(firstBoxId, firstBox, secondBoxId, secondBox);
}
}
}
}
.box {
border: solid 1px;
width: 60px;
margin-left: 30px;
margin-bottom: 5px;
text-align: center;
}
#inputs {
margin-top: 20px;
}
#inputs input {
width: 150px;
}
.connector {
position: absolute;
border-top: solid 1px;
border-left: solid 1px;
border-bottom: solid 1px;
width: 29px;
}
#error {
display: none;
color: red;
}
<div id="container">
<div id="box1" class="box">1</div>
<div id="box2" class="box">2</div>
<div id="box3" class="box">3</div>
<div id="box4" class="box">4</div>
</div>
<div id="inputs">
<input id="selectFirstBox" type="number" placeholder="Provide first box id" min="1" value="1" max="5" />
<input id="selectSecondBox" type="number" placeholder="Provide second box id" min="1" value="5" max="5" />
<div id="error">Please select different boxes to connect.</div>
</div>
<button id="connect">Connect</button>
<button id="addBox">Add box 5</button>
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/407565.html
標籤:
下一篇:在svg圓圈內顯示影像-(關閉)
