การวาดลูกศรด้านบน HTML


13

ฉันมีตาราง html และฉันต้องการวาดลูกศรจากเซลล์หนึ่งไปยังอีกเซลล์หนึ่ง ตัวอย่างเช่นนี้:

ลูกศรข้างต้น html ของตาราง

สิ่งนี้จะเกิดขึ้นได้อย่างไร?

ตัวอย่าง HTML:

<html>

 <body>

<table>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td id="end">9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td id="start">0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>


</body>

</html>

หากคุณปรับขนาดเบราว์เซอร์ลูกศรควรอยู่ในตำแหน่งเริ่มต้น / สิ้นสุด (ใหม่)


3
คุณลองทำอะไรด้วยตัวเองหรือยัง เสียงเช่นนี้สามารถทำได้โดยใช้ javascript และ css
Alexander Kludt

@AlexanderKludt ในกรณีนี้ฉันไม่มีเงื่อนงำ ฉันไม่พบคำแนะนำที่เป็นประโยชน์กับเครื่องมือค้นหาโปรดของฉัน
guettli

เราสามารถสมมติได้ว่าเซลล์ทั้งหมดมีความสูงและความกว้างเท่ากันในตัวอย่างหรือไม่
bitifet

... ถ้ารู้จักอัตราส่วนภาพก็สามารถทำได้ด้วยเพียงแค่ css (ตามเซลล์ x, ตำแหน่ง y) และควบคุมโดยฟังก์ชัน js ที่ทำหน้าที่บน css vars ในการใช้ตัวเลือกจะต้องสำรวจบริบทเพื่อคาดเดาพิกัดเหล่านั้นในฟังก์ชัน ไม่ทราบอัตราส่วนกว้างยาวฉันยังคิดอยู่ ...
bitifet

1
@guettli แน่นอน! แต่แล้วมันจะไม่เป็นโซลูชัน CSS บริสุทธิ์ (เกือบ) คุณจะต้องตรวจสอบการเปลี่ยนแปลงขนาดและคำนวณใหม่และฉีด kinda width_ratio css var เป็นไปได้ แต่ไม่น่าอัศจรรย์เท่าสารละลาย css บริสุทธิ์ ;-)
bitifet

คำตอบ:


6

ด้วย JavasSript และ CSS คุณสามารถทำได้โดยไม่ต้องใช้ Canvas หรือ SVG นี่คือตัวอย่าง:

function getPosition(el) {
   return {
     x: el.offsetLeft + el.offsetWidth / 2,
     y: el.offsetTop + el.offsetHeight / 2
   };
 }

 function getDistance(a, b) {
   const from = getPosition(a);
   const to = getPosition(b);

   return {
   //https://stackoverflow.com/a/17628488/529024
     distance: Math.hypot(from.x - to.x, from.y - to.y),
     angle: Math.atan2(to.x - from.x, from.y - to.y) * 180 / Math.PI,
     position: {
       start: from,
       end: to
     }
   }
 }

function init(){
// Get values and elements then set style
 const values = getDistance(
   document.getElementById("start"),
   document.getElementById("end")
 );
 
 
 let wrapper = document.getElementById('wrapper');
 let arrow = document.getElementById('arrow');
 let bottom = wrapper.offsetHeight - values.position.start.y;
 arrow.style.height = values.distance + "px";
 arrow.style.transform = `rotate(${values.angle}deg)`;
 arrow.style.bottom = bottom + "px";
 arrow.style.left = values.position.start.x + "px";
}

init();

window.addEventListener('resize', function(){
 init();
});
#wrapper {
  position: relative;
  left: 50px;
  top: 100px;
}

#arrow {
  position: absolute;
  width: 2px;
  background-color: red;
  transform-origin: bottom center;
}

#arrow::before {
    position: absolute;
    height: 0px;
    width: 0px;
    border: 6px solid transparent;
    border-bottom: 8px solid red;
    content: "";
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
  }
<div id='wrapper'>
  <div id='arrow'></div>
  <table>
    <tr>
      <td >0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td id="end">9</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td>9</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td>9</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td>9</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td>9</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td>9</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td>9</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td>9</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td>9</td>
    </tr>
    <tr>
      <td id="start">0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
      <td>9</td>
    </tr>
  </table>
</div>


ดูเหมือนว่ามีข้อผิดพลาด: ลูกศรของคุณแตกต่าง มันสิ้นสุดที่ศูนย์แรก
guettli

ฉันเปลี่ยนค่า ฉันอัปเดตตัวอย่างทันทีเพื่อสะท้อนถึงตัวอย่างของคุณ
Kalimah

ถ้าฉันใช้ctrl -(ลดขนาด) ลูกศรจะสูญเสียตำแหน่งสิ้นสุด
guettli

5

คุณสามารถใช้วิธีแก้ปัญหาของฉันยังไม่เสร็จลูกศรวาดให้สร้างผ้าใบและวาดเส้นจากสองจุดขึ้นอยู่กับการคำนวณจุดเริ่มต้นและจุดสิ้นสุด

Example running: https://jsfiddle.net/tabvn/uk7hsj3a    

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title></title>
</head>
<body>
<table id="my-table">
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td id="end">9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td id="start">0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
</table>

<script type="text/javascript">

  var table = document.getElementById('my-table')
  var startElement = document.getElementById('start')
  var endElement = document.getElementById('end')

  var startPoint = {x: startElement.offsetLeft + table.offsetLeft, y: startElement.offsetTop + table.offsetTop}
  var endPoint = {x: endElement.offsetLeft + table.offsetLeft, y: endElement.offsetTop + table.offsetTop}
  
  var canvas = document.createElement('canvas')
  canvas.width = table.clientWidth
  canvas.height = table.clientHeight
  canvas.style.position = 'absolute'
  canvas.style.top = startPoint.y < endPoint.y ? startPoint.y + 'px' : endPoint.y + 'px'
  canvas.style.left = startPoint.x < endPoint.x ? startPoint.x + 'px' : endPoint.x + 'px'

  var ctx = canvas.getContext('2d')

  ctx.beginPath()
  ctx.strokeStyle = 'red'
  ctx.fillStyle = 'red'
  ctx.moveTo(startPoint.x - (startElement.clientWidth / 2), startPoint.y)
  ctx.lineTo(endPoint.x - (endElement.clientWidth / 2), endPoint.y)
  ctx.stroke()
  document.body.insertBefore(canvas, table, 30)

</script>

</body>
</html>


ถ้าฉันปรับขนาดหน้าจอ (ctrl + และ ctrl -) จากนั้นเส้นสีแดงจะสูญเสียตำแหน่ง
guettli

3
เพื่อเพิ่มการปรับขนาดเราสามารถจัดกลุ่มการแก้ปัญหาในฟังก์ชั่นและจากนั้นคุณสามารถฟังการปรับขนาดหน้าต่างและโทรผ้าใบอีกครั้งทำให้การแสดงผล
Toan

4

โซลูชัน Javascript:

drawLine();

function drawLine () {
  var table = document.getElementById('my-table')
  var startElement = document.getElementById('start')
  var endElement = document.getElementById('end')

  let arrowRadius = 10;

  let xStart = null;
  let xEnd = null;
  if (startElement.offsetLeft > endElement.offsetLeft) {
    xStart = startElement.offsetLeft + (arrowRadius/2);//to add padding just add more wherever theres this pattern 
    xEnd = endElement.offsetLeft + endElement.offsetWidth / 2;
  } else if (startElement.offsetLeft < endElement.offsetLeft) {
    xStart = startElement.offsetLeft + startElement.offsetWidth - (arrowRadius/2);
    xEnd = endElement.offsetLeft;
  } else {
    xStart = startElement.offsetLeft + startElement.offsetWidth / 2;
    xEnd = endElement.offsetLeft + endElement.offsetWidth / 2;
  }

  let yStart = null;
  let yEnd = null;
  if (startElement.offsetTop > endElement.offsetTop) {
    yStart = startElement.offsetTop + (arrowRadius/2);
    yEnd = endElement.offsetTop + endElement.offsetHeight + (arrowRadius/2);
  } else if (startElement.offsetTop < endElement.offsetTop) {
    yStart = startElement.offsetTop + startElement.offsetHeight - (arrowRadius/2);
    yEnd = endElement.offsetTop - (arrowRadius/2);
  } else {
    yStart = startElement.offsetTop + startElement.offsetHeight / 2;
    yEnd = endElement.offsetTop + endElement.offsetHeight / 2;
  }

  let coordBegin = {
    x: xStart,
    y: yStart
  };
  let coordEnd = {
    x: xEnd,
    y: yEnd
  };

  var canvas = document.createElement('canvas')
  canvas.width = table.offsetWidth
  canvas.height = table.offsetHeight
  canvas.style.position = 'absolute'

  var ctx = canvas.getContext('2d')
  drawArrowhead(ctx, coordBegin, coordEnd, arrowRadius);
  ctx.beginPath()
  ctx.strokeStyle = 'red'
  ctx.fillStyle = 'red'
  ctx.moveTo(coordBegin.x, coordBegin.y)
  ctx.lineTo(coordEnd.x, coordEnd.y)
  ctx.stroke()

  document.body.insertBefore(canvas, table)
}




function drawArrowhead(context, from, to, radius) {
    var x_center = to.x;
    var y_center = to.y;

    var angle;
    var x;
    var y;

    context.beginPath();

    angle = Math.atan2(to.y - from.y, to.x - from.x)
    x = radius * Math.cos(angle) + x_center;
    y = radius * Math.sin(angle) + y_center;

    context.moveTo(x, y);

    angle += (1.0/3.0) * (2 * Math.PI)
    x = radius * Math.cos(angle) + x_center;
    y = radius * Math.sin(angle) + y_center;

    context.lineTo(x, y);

    angle += (1.0/3.0) * (2 * Math.PI)
    x = radius *Math.cos(angle) + x_center;
    y = radius *Math.sin(angle) + y_center;

    context.lineTo(x, y);

    context.closePath();
    context.fillStyle = 'red';
    context.fill();
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title></title>
</head>
<body>
<table id="my-table">
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td id="end">9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        </tr>
    <tr>
        <td id="start">0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
</table>

</body>
</html>


ฉันใช้โครเมี่ยมและเส้นสีแดงลดลงโดยเริ่มจาก "2" ตัวแรก
guettli

อย่างที่ควรจะเป็นเช่นกันเนื่องจากรหัสอยู่ในตำแหน่งเหล่านั้น
David Machado

@guettli การทำงานสำหรับทุกตำแหน่งเพียงแค่เปลี่ยนรหัสและก็มีเข้าบัญชีที่เริ่มต้นและตำแหน่งสิ้นสุดจึงดึงลูกศรกับจัดตำแหน่งที่เหมาะสม
เดวิด Machado

ฉันอัปเดตคำตอบของคุณ ลูกศรชี้ไปที่ "9" ตัวแรกตอนนี้เหมือนในคำถาม ขอบคุณสำหรับคำตอบนี้
guettli

3

นี่คือวิธีที่ฉันจะทำ: องค์ประกอบ svg ใช้ขนาดของตารางสำหรับค่า viewBox คุณกำลังคำนวณขนาดและตำแหน่งของเซลล์ที่คุณต้องการเชื่อมโยงและใช้ตำแหน่งนี้เพื่อวาดเส้น เครื่องหมายถูกใช้สำหรับส่วนปลายของลูกศร

โปรดปรับขนาดหน้าต่าง:

let cells = Array.from(document.querySelectorAll("td"));
// index of cells to be correlated
let n1 = 90;
let n2 = 9;
// a function to draw the arrow
function drawArrow(){
//get the size of the table
let size = theTable.getBoundingClientRect();
//set the viewBox attribute for the svg element
theSVG.setAttributeNS(null, "viewBox", `0 0 ${size.width} ${size.height}`)
//get the size and the position of the cells
let c1 = cells[n1].getBoundingClientRect();
let c2 = cells[n2].getBoundingClientRect();
//set the x1, y1, x2,y2 attributes of the line
theLine.setAttributeNS(null,"x1",`${c1.left + c1.width/2}`);
theLine.setAttributeNS(null,"y1",`${c1.top + c1.height/2}`);
theLine.setAttributeNS(null,"x2",`${c2.left + c2.width/2}`);
theLine.setAttributeNS(null,"y2",`${c2.top + c1.height/2}`); 
}


drawArrow()


window.setTimeout(function() {
  drawArrow()
  window.addEventListener('resize', drawArrow, false);
}, 15);
body {
  margin: 0;
  padding: 0;
}
table,svg{
  width: 100%;
  border-collapse: collapse;
  margin: 0;
  position:absolute;
}
td {
  border: 1px solid #d9d9d9;
  padding: 0.5em;
  text-align: center;
}

svg{background:rgba(0,0, 255,.5)}
<table id="theTable">
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td id="end">9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
 <tr><td id="start">0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
</table>

<svg id="theSVG">
  <defs>
    <marker id="arrow" markerWidth="6" markerHeight="12" refX="8" refY="6" orient="auto">
        <path d="M 0 0 L 8 6 L 0 12" />
    </marker>
  </defs>
  <line id="theLine" marker-end="url(#arrow)" stroke="black" />  
</svg>

UPDATE:

เนื่องจากมีคนแสดงความคิดเห็นว่าเมื่อปรับขนาดลูกศรกำลังสูญเสียตำแหน่งของฉันจึงเพิ่ม gif:

ป้อนคำอธิบายรูปภาพที่นี่


ถ้าฉันปรับขนาดหน้าจอ (ctrl + และ ctrl -) จากนั้นลูกศรจะสูญเสียตำแหน่ง
guettli

ฉันไม่คิดอย่างนั้น: ฉันได้เพิ่ม gif
enxaneta

น่าเสียดายที่ตำแหน่งเริ่มต้นของลูกศรแพ้ตำแหน่งหลังจากctrl +(หลังctrl -) imgur.com/8xbEAK2 Iuse Chromium 78.0.3904.70
guettli

3

คุณสามารถใช้องค์ประกอบ SVG และสไตล์ css สำหรับตำแหน่งที่แน่นอนซ้อนทับตารางของคุณ และรับจุดเริ่มต้นและจุดสิ้นสุดโดย JavaScript DOM API เช่นgetBoundingClientRect()

นี่คือตัวอย่าง (ผลิตด้วย Angular แต่คุณสามารถใช้ได้ทุกที่ตัวอย่าง JavaScript ที่แท้จริงดูด้านล่าง)

const startElement = document.querySelector('#start');
const endElement = document.querySelector('#end');

const startRect = startElement.getBoundingClientRect();
const endRect = endElement.getBoundingClientRect();

const startX = startRect.right;
const startY = startRect.top;

const endX = endRect.left;
const endY = endRect.bottom;

คุณสามารถเปลี่ยนการเริ่มต้นและสิ้นสุดแบบไดนามิก คุณจะต้อง reinvoke วิธีการที่จะได้รับตำแหน่ง โปรดทราบว่าฉันใช้ปุ่มซ้าย, ด้านบน, ขวา, เพื่อวางลูกศรบนขอบขององค์ประกอบ คุณสามารถคำนวณจุดกึ่งกลางหรือขอบโดยการเปรียบเทียบทั้งสองตำแหน่ง

และคุณต้องวาง svg ไว้บนโต๊ะ คุณสามารถทำได้โดยชุด position: absolute; left: 0; top: 0CSS แต่โปรดทราบว่าผู้ปกครองของคุณควรมีpositionแอตทริบิวต์ position: relativeเช่น

อัปเดต: นี่คือตัวอย่างของ JavaScript อย่างแท้จริง คลิกที่ด้านซ้ายเพื่อดูไฟล์ทั้งหมดและเลือก index.js เพื่อดูไฟล์ JS (เหมือนใน VS Code)

รหัสสมบูรณ์:

<table style="position: absolute; left: 0; top: 0;">
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td id="end">9</td>
    </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
    <tr>
        <td>0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
    <tr>
        <td id="start">0</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>

    <svg style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 1">
        <defs>
            <marker id="arrow" markerWidth="10" markerHeight="10" refX="5" refY="3" orient="auto"
                markerUnits="strokeWidth" viewBox="0 0 20 20">
                <path d="M0,0 L0,6 L9,3 z" fill="#f00" />
            </marker>
        </defs>

        <line id="svg-line" stroke="#f00" stroke-width="5"
            marker-end="url(#arrow)" />
    </svg>
</table>
<script>
const svgLine = document.querySelector('#svg-line');

const startElement = document.querySelector("#start");
const endElement = document.querySelector("#end");

const startRect = startElement.getBoundingClientRect();
const endRect = endElement.getBoundingClientRect();


const startX = startRect.right;
const startY = startRect.top;

const endX = endRect.left;
const endY = endRect.bottom;

svgLine.setAttribute('x1', startX);
svgLine.setAttribute('y1', startY);
svgLine.setAttribute('x2', endX);
svgLine.setAttribute('y2', endY);
</script>

เพียงแค่คัดลอกโค้ดข้างต้นในไฟล์ html ที่ว่างเปล่าใหม่แล้วรันในเบราว์เซอร์ของคุณ

Btw คุณสามารถทำได้ด้วยผ้าใบ (ทางเลือกสำหรับ svg)


คุณต้องมีการติดตั้งอย่างสมบูรณ์ที่นี่และไม่ใช่ไซต์ของบุคคลที่สาม ลิงก์ภายนอกจะตายไปตามกาลเวลาและจะทำให้คำตอบของคุณไร้ประโยชน์ รหัสที่คุณแสดงที่นี่ไม่สมบูรณ์ stackoverflow.com/help/how-to-answer
Rob

2

คุณต้องวางตารางใน div และให้คุณสมบัติตำแหน่ง: สัมพันธ์จากนั้นเขียน HTML สำหรับลูกศร (ใช้รูปภาพถ้าคุณต้องการ) และให้คุณสมบัติเป็นแบบสัมบูรณ์แล้วกำหนดสไตล์ตามที่คุณต้องการใช้ด้านบน ซ้ายขวา..

อ่านเพิ่มเติมเกี่ยวกับคุณสมบัติตำแหน่งได้ที่นี่https://www.w3schools.com/css/css_positioning.asp


คำตอบของคุณถูกต้อง แต่ก็ยังมีบางสิ่งที่ขาดหายไป การใช้ภาพสำหรับภาพทำงานได้ดี มันไม่ได้ปรับขนาดอย่างดี
guettli

คำถามถูกติดแท็ก "svg" และเขาถามวิธี "วาด" ลูกศรดังนั้นสิ่งนี้จะไม่ตอบคำถาม
Rob

ใช้ SVG การปรับจะไม่เป็นปัญหามากนัก
Amit Khare
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.