在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ 兩個(gè)盒子之間的指引線請(qǐng)問怎么實(shí)現(xiàn)?

兩個(gè)盒子之間的指引線請(qǐng)問怎么實(shí)現(xiàn)?

clipboard.png
請(qǐng)問圖中這種對(duì)應(yīng)關(guān)系的指引線怎么實(shí)現(xiàn),右邊的盒子可能會(huì)有好幾個(gè),怎樣動(dòng)態(tài)的和左邊的盒子建立指引線的聯(lián)系?請(qǐng)了解的大佬給個(gè)實(shí)現(xiàn)的思路和方法

回答
編輯回答
別硬撐
  1. 計(jì)算兩個(gè)盒子的中心點(diǎn)
  2. 用偽元素畫一個(gè) <div> ,用它的某個(gè)邊框作為連線
  3. 用三角函數(shù)計(jì)算盒子的位置,放過去
2018年2月3日 20:25
編輯回答
何蘇葉

::after ::before

2017年10月19日 18:14
編輯回答
逗婦乳

涉及到自適應(yīng)嗎,如果涉及到自適應(yīng),建議把三個(gè)盒子放到一個(gè)容器里面,如果不涉及到自適應(yīng),方式就很多了,只有位置確定好,之間的線條可以用盒子去模擬,也可以用圖片等等

2017年2月6日 15:50
編輯回答
薔薇花

這個(gè)屬于腦圖的效果
我更建議你引入組件庫來幫助你實(shí)現(xiàn)這一效果
https://antv.alipay.com/zh-cn...
https://www.yuque.com/antv/g6...

2018年7月18日 18:44
編輯回答
艷骨

額,我的方法有點(diǎn)笨,就是將線與塊放在一個(gè)容器內(nèi),計(jì)算他們?cè)谌萜鲀?nèi)的左標(biāo),然后連線。c 可以拖拽,線在右側(cè)可以跟隨,但是拖動(dòng)不好用,,,
大概思路如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Page Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
  <style>
    body {
      position: relative;
      border: 1px solid #ccc;
      height: 500px;
      width: 500px;
    }
    body > div {
      position: absolute;
      width: 100px;
      height: 50px;
      background: blueviolet;
      color: white;
    }
    div.line {
      border-top: 2px dashed red;
      height: 0;
    }
    #a {
      top: 200px;
      left: 100px;
    }
    #b {
      top: 100px;
      left: 300px;
    }
    #c {
      top: 300px;
      left: 300px;
    }
  </style>
</head>
<body>
  <div id='a'>A</div>
  <div id='b'>B</div>
  <div id='c' style="background: teal">C, drag me</div>
  <canvas id='anc' style='position: absolute; z-index: 1'></canvas>
  <div id='anb' class='line'></div>
  <script>
    const ela = document.getElementById('a');
    const elb = document.getElementById('b');
    const elc = document.getElementById('c');
    const lineAToB = document.getElementById('anb');
    const lineAToC = document.getElementById('anc');
    const container = document.body;
    let lineCtx = lineAToC.getContext('2d');

    const drawPaddingX = 10;
    const drawPaddingY = 10;

    // 元素左上角,在容器內(nèi)的坐標(biāo)
    let pEla = getCordInContainer(ela);
    let pElb = getCordInContainer(elb);
    let pElc = getCordInContainer(elc);

    // 元素本身的長(zhǎng)寬
    let sEla = { width: ela.offsetWidth, height: ela.offsetHeight };
    let sElb = { width: elb.offsetWidth, height: elb.offsetHeight };
    let sElc = { width: elc.offsetWidth, height: elc.offsetHeight };

    function getCordInContainer(elem) {
      let eX = elem.offsetLeft;
      let eY = elem.offsetTop;
      return { eX, eY };
    }

    // 三角函數(shù)忘得差不多了,這里面角度的符號(hào)沒有確定,隨便寫的。。。
    function setLine() {
      // 這個(gè)坐標(biāo)差,應(yīng)該從兩個(gè)連接點(diǎn)換直角三角形計(jì)算
      let diffXAB = (pElb.eX - sElb.width )- pEla.eX ;
      let diffXAC = (pElb.eX -sElb.width) - pEla.eX ;
      let diffYAB = pEla.eY + sEla.height/2 - sElb.height/2 - pElb.eY ;
      let diffYAC = pEla.eY + sEla.height/2 - sElb.height/2 - pElb.eY ;

      // 求夾角
      let lineABDeg = Math.atan2(diffYAB, diffXAB) * 180 / Math.PI;
      let lineABRad = Math.atan2(diffYAB, diffXAB);
      let lineWidth = diffYAB/Math.sin(lineABRad);
      // 求初始位置,主要是旋轉(zhuǎn)后的偏移量
      let lineStartX = pEla.eX + sEla.width - (lineWidth/2 - lineWidth/2*Math.cos(lineABRad));
      let lineStartY = pEla.eY + sEla.height/2 - lineWidth/2*Math.sin(lineABRad);

      let str = `width: ${lineWidth}px; top: ${lineStartY}px; left: ${lineStartX}px`;
      console.log(str);
      lineAToB.style.cssText= str;
      lineAToB.style.transform = `rotate(${-lineABDeg}deg)`;
    }
    // 將線放置到正確位置
    setLine();
    function drawLine(canElem, ctx) {
      pElc = getCordInContainer(elc);
      sElc = { width: elc.offsetWidth, height: elc.offsetHeight };
      // 這個(gè)坐標(biāo)差,應(yīng)該從兩個(gè)連接點(diǎn)換直角三角形計(jì)算
      // 調(diào)整這個(gè)就可一移動(dòng)到左面
      let diffXAC = (pElc.eX -sElc.width) - pEla.eX + 2 * drawPaddingX;
      let diffYAC = Math.abs(pEla.eY + sEla.height/2 - sElc.height/2 - pElc.eY) + 2 * drawPaddingY;

      let lineStartX = pEla.eX + sEla.width;
      let lineStartY = pEla.eY + sEla.height/2;
      let lineEndX = pElc.eX;
      let lineEndY = pElc.eY + sElc.height/2;
      let lineCordX = Math.min(lineStartX, lineEndY) - drawPaddingX;
      let lineCordY = Math.min(lineStartY, lineEndY) - drawPaddingY;

      
      canElem.width = Math.abs(diffXAC);
      canElem.height = Math.abs(diffYAC);
      canElem.style.setProperty('left', lineCordX + 'px', '');
      canElem.style.setProperty('top', lineCordY + 'px', '');

      ctx.clearRect(0,0, canElem.width, canElem.height);
      ctx.beginPath();
      ctx.moveTo(lineStartX - lineCordX, lineStartY - lineCordY);
      ctx.lineTo(lineEndX - lineCordX, lineEndY - lineCordY);
      ctx.stroke();
    }
    drawLine(lineAToC, lineCtx);
    let draging = false;
    elc.onmousedown = () => {
      draging = true;
    }
    container.onmousemove = _.throttle((e) => {
      if (draging) {
        elc.style.setProperty('left', elc.offsetLeft + e.movementX + 'px', '');
        elc.style.setProperty('top', elc.offsetTop + e.movementY + 'px', '');
        drawLine(lineAToC, lineCtx);
      }
    }, 10);
    container.onmouseleave = () => {
      draging = false;
    }
    container.onmouseup = () => {
      draging = false;
      console.log(draging);
    }
  </script>
</body>
</html>
2018年5月13日 07:41