我有一个简单的html表,其中包含一些我用td标签创建的单元格。 现在我需要从单元格A2到C2绘制一个箭头。 我想创建一个jQuery函数来获取单元格A2和C2中间的XY坐标,然后以某种方式画一个箭头。
如图所示,实现外观的好方法是什么?
答案 0 :(得分:1)
您可以使用canvas元素动态地执行此操作,以包含箭头,您将通过2D上下文绘制函数动态绘制箭头。您可以使用javascript绝对定位canvas元素。
以下是示例代码:
HTML:
<canvas id="canvas" width="100" height="100">
</canvas>
<table>
<tr><td>1</td><td>2</td></tr>
<tr><td>3</td><td>4</td></tr>
<tr><td>5</td><td>6</td></tr>
</table>
使用Javascript:
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
canvas.style.top = 7 + "px";
canvas.style.left = 7 + "px";
var fromx = 0;
var fromy = 12;
var tox = 25;
var toy = 12;
var headlen = 10; // length of head in pixels
var angle = Math.atan2(toy-fromy,tox-fromx);
var arrowSize = 2;
var headlen = 10;
var angle = Math.atan2(toy-fromy,tox-fromx);
//starting path of the arrow from the start square to the end square and drawing the stroke
ctx.beginPath();
ctx.moveTo(fromx, fromy);
ctx.lineTo(tox, toy);
ctx.strokeStyle = "#cc0000";
ctx.lineWidth = arrowSize;
ctx.stroke();
//starting a new path from the head of the arrow to one of the sides of the point
ctx.beginPath();
ctx.moveTo(tox, toy);
ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));
//path from the side point of the arrow, to the other side point
ctx.lineTo(tox-headlen*Math.cos(angle+Math.PI/7),toy-headlen*Math.sin(angle+Math.PI/7));
//path from the side point back to the tip of the arrow, and then again to the opposite side point
ctx.lineTo(tox, toy);
ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));
//draws the paths created above
ctx.strokeStyle = "#cc0000";
ctx.lineWidth = arrowSize;
ctx.stroke();
ctx.fillStyle = "#cc0000";
ctx.fill();
CSS:
#canvas {
position: absolute;
top: 0px;
left: 0px;
width: 100px;
height: 100px;
}
您可以通过编程方式获取表元素的定位信息,以便为fromx,fromy等设置正确的值,并设置canvas.style.top和canvas.style.left。
中的箭头绘图代码答案 1 :(得分:0)
首先,我们可以获得相对于文档的单元格的中心。然后,我们可以在画布上(相对于文档)从头到尾画一个箭头。诀窍是在画布上设置pointer-events: none
,这样我们就不会意外地与它进行交互。
// gets the center of a table cell relative to the document
function getCellCenter(table, row, column) {
var tableRow = $(table).find('tr')[row];
var tableCell = $(tableRow).find('td')[column];
var offset = $(tableCell).offset();
var width = $(tableCell).innerWidth();
var height = $(tableCell).innerHeight();
return {
x: offset.left + width / 2,
y: offset.top + height / 2
}
}
// draws an arrow on the document from the start to the end offsets
function drawArrow(start, end) {
// create a canvas to draw the arrow on
var canvas = document.createElement('canvas');
canvas.width = $('body').innerWidth();
canvas.height = $('body').innerHeight();
$(canvas).css('position', 'absolute');
$(canvas).css('pointer-events', 'none');
$(canvas).css('top', '0');
$(canvas).css('left', '0');
$(canvas).css('opacity', '0.85');
$('body').append(canvas);
// get the drawing context
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'steelblue';
ctx.strokeStyle = 'steelblue';
// draw line from start to end
ctx.beginPath();
ctx.moveTo(start.x, start.y);
ctx.lineTo(end.x, end.y);
ctx.lineWidth = 2;
ctx.stroke();
// draw circle at beginning of line
ctx.beginPath();
ctx.arc(start.x, start.y, 4, 0, Math.PI * 2, true);
ctx.fill();
// draw pointer at end of line (needs rotation)
ctx.beginPath();
var angle = Math.atan2(end.y - start.y, end.x - start.x);
ctx.translate(end.x, end.y);
ctx.rotate(angle);
ctx.moveTo(0, 0);
ctx.lineTo(-10, -7);
ctx.lineTo(-10, 7);
ctx.lineTo(0, 0);
ctx.fill();
// reset canvas context
ctx.setTransform(1, 0, 0, 1, 0, 0);
return canvas;
}
// finds the center of the start and end cells, and then calls drawArrow
function drawArrowOnTable(table, startRow, startColumn, endRow, endColumn) {
drawArrow(
getCellCenter($(table), startRow, startColumn),
getCellCenter($(table), endRow, endColumn)
);
}
// draw an arrow from (1, 0) to (2, 4)
drawArrowOnTable('table', 1, 0, 2, 4);
&#13;
table, td {
border-collapse: collapse;
}
td {
border: 1px solid #ddd;
padding: 6px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td>A1</td>
<td>B1</td>
<td>C1</td>
<td>D1</td>
<td>E1</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
<td>C2</td>
<td>D2</td>
<td>E2</td>
</tr>
<tr>
<td>A3</td>
<td>B3</td>
<td>C3</td>
<td>D3</td>
<td>E3</td>
</tr>
</table>
<pre>drawArrowOnTable('table', 1, 0, 2, 4);</pre>
</body>
</html>
&#13;