Disegnare frecce sopra HTML


13

Ho una tabella html e voglio disegnare una freccia da una cella a un'altra cella. Ad esempio in questo modo:

freccia-sopra-html-table

Come si può fare?

HTML di esempio:

<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>

Se ridimensionate il browser, la freccia dovrebbe rimanere nella (nuova) posizione iniziale / finale.


3
Hai già provato qualcosa da solo? Sembra che questo potrebbe essere fatto usando JavaScript e CSS
Alexander Kludt,

@AlexanderKludt in questo caso non ne ho idea. Non sono riuscito a trovare suggerimenti utili con il mio motore di ricerca preferito.
Guettli,

Possiamo supporre che tutte le celle siano uguali in altezza e larghezza come nell'esempio?
Bitifet,

... Se si conoscono anche le proporzioni, ciò può essere fatto solo con css (basato sulla posizione della cella x, y) e controllato dalla funzione js che agisce su css vars. Per utilizzare i selettori, è necessario esplorare il suo contesto per indovinare quelle coordinate nella funzione. Non conoscendo le proporzioni ci sto ancora pensando ...
bitifet

1
@guettli ovviamente! ma poi non sarà una pura soluzione CSS (anche quasi) sarà quindi necessario rilevare i cambiamenti di dimensione e ricalcolare e iniettare kinda aspect_ratio css var. È plausibile, ma non meraviglioso come una soluzione css pura ;-)
bitifet

Risposte:


6

Con un po 'di JavasSript e CSS puoi raggiungere questo obiettivo senza canvas o SVG. Ecco un esempio:

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>


Sembra un bug: la tua freccia è diversa. Termina al primo zero.
Guettli,

Ho cambiato i valori. Ho aggiornato il campione ora per riflettere il tuo esempio.
Kalimah,

Se uso ctrl -(riduci dimensione) la freccia perde la posizione finale.
Guettli,

5

Puoi usare la mia soluzione non completare ancora la freccia di disegno, lascia creare una tela e disegnare una linea da due punti, in base al calcolo del punto iniziale e finale.

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>


Se ridimensiono lo schermo (ctrl + e ctrl -), la linea rossa perde la posizione.
Guettli,

3
quindi aggiungi il ridimensionamento potremmo raggruppare la soluzione in una funzione, e quindi puoi ascoltare il ridimensionamento della finestra e chiamare di nuovo render canvas.
Toan,

4

Soluzione 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>


Uso il cromo e la linea rossa scende verso il basso a partire dal primo "2".
Guettli,

Come si suppone anche, dato che gli ID sono in quelle posizioni
David Machado,

@guettli funziona per ogni posizione basta cambiare l'id e ha in considerazione la posizione iniziale e finale in modo che disegna la freccia con il corretto allineamento
David Machado

Ho aggiornato la tua risposta. La freccia indica ora il primo "9", come nella domanda. Grazie per questa risposta
Guettli,

3

Ecco come lo farei: l'elemento svg utilizza la dimensione della tabella per il valore viewBox. Stai calcolando la dimensione e la posizione delle celle che devi correlare e usa questa posizione per disegnare la linea. Un pennarello viene utilizzato per la punta della freccia.

Si prega di ridimensionare la finestra:

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>

AGGIORNARE:

Dato che qualcuno ha commentato che al ridimensionamento la freccia sta perdendo la sua posizione, sto aggiungendo una gif:

inserisci qui la descrizione dell'immagine


Se ridimensiono lo schermo (ctrl + e ctrl -), la freccia perde la posizione.
Guettli,

Non credo: ho aggiunto una gif
enxaneta il

Sfortunatamente la posizione iniziale della freccia ha perso la posizione dopo ctrl +(dopo ctrl -) imgur.com/8xbEAK2 Iuse Chromium 78.0.3904.70
guettli

3

È possibile utilizzare un elemento SVG e gli stili CSS per la posizione assoluta sovrapposta alla tabella. E ottieni il punto di inizio e di fine dall'API DOM JavaScript comegetBoundingClientRect()

Ecco una demo. (Realizzato con Angular, ma puoi usarlo ovunque. Esempio di puro JavaScript vedi sotto.)

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;

È possibile modificare l'inizio e la fine in modo dinamico. Devi solo reinvocare il metodo per ottenere le posizioni. Nota che uso il pulsante sinistro, superiore, destro per posizionare la freccia sul bordo dell'elemento. È possibile calcolare il punto centrale o il bordo confrontando entrambe le posizioni.

E devi posizionare lo svg sul tavolo. Puoi farlo impostando css position: absolute; left: 0; top: 0. Ma nota che anche il tuo genitore dovrebbe avere l' positionattributo. per esempioposition: relative .

Aggiornamento: qui una demo JavaScript pura. Fare clic a sinistra per visualizzare tutti i file e selezionare index.js per visualizzare i contenuti JS. (come nel codice VS).

Codice completo:

<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>

Basta copiare il codice sopra in un nuovo file html vuoto ed eseguirlo nel browser.

Btw. Puoi anche farlo con una tela. (alternativa a svg)


È necessaria un'implementazione completa qui e non un sito di terze parti. I collegamenti esterni si interrompono nel tempo e renderanno inutile la tua risposta. Il codice che mostri qui è incompleto. stackoverflow.com/help/how-to-answer
Rob

2

Devi mettere la tabella in un div e dare una proprietà, posizione: relative Quindi scrivi HTML per la freccia (usa un'immagine se vuoi) e assegnale una proprietà assoluta e poi modellala come vuoi usando, top, sinistra destra..

Maggiori informazioni sulle proprietà di posizione qui https://www.w3schools.com/css/css_positioning.asp


La tua risposta è corretta Ma manca ancora qualcosa. L'uso di un'immagine per l'immagine funziona bene. Non si adatta bene.
Guettli,

La domanda è taggata "svg" e chiede come "disegnare" la freccia in modo che non risponda alla domanda.
Rob,

usa SVG, il ridimensionamento non sarà un grosso problema
Amit Khare
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.