【问题标题】:Drawing arrows above HTML在 HTML 上方绘制箭头
【发布时间】:2020-03-07 05:27:00
【问题描述】:

我有一个 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>

如果您调整浏览器的大小,箭头应该停留在(新的)开始/结束位置。

【问题讨论】:

  • 您自己尝试过吗?听起来这可以使用 javascript 和 css 完成
  • @AlexanderKludt 在这种情况下我不知道。我无法通过我最喜欢的搜索引擎找到有用的提示。
  • 我们可以假设所有单元格的高度和宽度都像示例中一样吗?
  • ...如果纵横比也已知,则可以仅使用 css(基于单元格 x,y 位置)并由作用于 css vars 的 js 函数控制。要使用选择器,必须探索其上下文以猜测函数中的那些坐标。不知道长宽比我还在考虑它......
  • @guettli 当然!但它不会是一个纯粹的 CSS 解决方案(甚至几乎),你需要检测大小变化并重新计算和注入 kinda aspect_ratio css var。这是合理的,但不如纯 css 解决方案那么美妙 ;-)

标签: javascript html svg


【解决方案1】:

只需一点 JavasSript 和 CSS,您就可以在没有画布或 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>

【讨论】:

  • 看起来像一个错误:您的箭头不同。它在第一个零处结束。
  • 我更改了值。我现在更新了示例以反映您的示例。
  • 如果我使用ctrl -(减小大小),箭头会失去结束位置。
【解决方案2】:

您可以使用我的解决方案尚未完成绘制箭头, 让我们根据起点和终点的计算创建一个画布并从两点绘制一条线。

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 -),那么红线就会失去位置。
  • 所以添加resize我们可以在一个函数中分组解决方案,然后你可以监听窗口resize并再次调用render canvas。
【解决方案3】:

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>

【讨论】:

  • 我用的是chrome,红线从第一个“2”开始往下走。
  • 应该也是如此,因为 id 位于这些位置
  • @guettli 它适用于每个位置只需切换 id 并且它考虑了开始和结束位置,因此它以正确对齐方式绘制箭头
  • 我更新了你的答案。箭头现在指向第一个“9”,就像问题中一样。谢谢你的回答。
【解决方案4】:

我会这样做: 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>

更新:

由于有人评论说在调整大小时箭头失去了它的位置,所以我添加了一个 gif:

【讨论】:

  • 如果我调整屏幕大小(ctrl + 和 ctrl -),那么箭头就会失去位置。
  • 我不这么认为:我添加了一个 gif
  • 不幸的是箭头的起始位置在ctrl +之后丢失了位置(ctrl -之后)imgur.com/8xbEAK2 Iuse Chromium 78.0.3904.70
【解决方案5】:

您可以使用 SVG 元素和 css 样式来覆盖表格的绝对位置。并通过getBoundingClientRect()等JavaScript DOM API获取起点和终点

Here 是一个演示。 (使用 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;

您可以动态更改开始和结束。您只需重新调用该方法即可获得职位。请注意,我使用左、上、右、按钮将箭头放置在元素的边缘。您可以通过比较这两个位置来计算中心点或边缘。

您必须将 svg 放在桌子上。您可以通过设置 css position: absolute; left: 0; top: 0 来做到这一点。但请注意,您的父母也应该有position 属性。例如position: relative.

更新:Here 是一个纯 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 文件中,然后在浏览器中运行即可。

顺便说一句。您也可以使用画布执行此操作。 (替代 svg)

【讨论】:

  • 您需要一个完整的实现,而不是第三方站点。外部链接会随着时间的流逝而失效,并且会使您的答案毫无用处。您在此处显示的代码不完整。 stackoverflow.com/help/how-to-answer
【解决方案6】:

你需要把表格放在一个div中,并给出一个属性,position: relative 然后为箭头编写 HTML(如果你愿意,可以使用图像)并给它一个绝对属性,然后使用你想要的样式设置它,上,左,右..

在此处阅读有关职位属性的更多信息https://www.w3schools.com/css/css_positioning.asp

【讨论】:

  • 你的答案是正确的。但仍然缺少一些东西。为图像使用图像效果很好。它不能很好地扩展。
  • 这个问题被标记为“svg”,他问如何“画”箭头,所以这不能回答这个问题。
  • 使用 SVG,缩放不会有太大问题
猜你喜欢
  • 2011-09-28
  • 1970-01-01
  • 2012-06-22
  • 1970-01-01
  • 2018-04-12
  • 2010-10-22
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多