LineRow.js :

import React, { Component } from 'react';


function rect(props) {

const { ctx, fromX, fromY, toX, toY, color } = props;
var headlen = 10; //自定义箭头线的长度
var theta = 30; //自定义箭头线与直线的夹角,个人觉得45°刚刚好
var arrowX, arrowY; //箭头线终点坐标
// 计算各角度和对应的箭头终点坐标
var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI;
var angle1 = (angle + theta) * Math.PI / 180;
var angle2 = (angle - theta) * Math.PI / 180;
var topX = headlen * Math.cos(angle1);
var topY = headlen * Math.sin(angle1);
var botX = headlen * Math.cos(angle2);
var botY = headlen * Math.sin(angle2);
ctx.beginPath();
//画直线
ctx.moveTo(fromX, fromY);
ctx.lineTo(toX, toY);

arrowX = toX + topX;
arrowY = toY + topY;
//画上边箭头线
ctx.moveTo(arrowX, arrowY);
ctx.lineTo(toX, toY);

arrowX = toX + botX;
arrowY = toY + botY;
//画下边箭头线
ctx.lineTo(arrowX, arrowY);

ctx.strokeStyle = color;
ctx.stroke();
}

class LineRow extends Component {
componentDidMount() {
this.updateCanvas();
}
componentDidUpdate() {
this.updateCanvas();
}
updateCanvas() {
try {
var canvas = document.getElementById('canvas1');


if (!canvas) { console.log('Canvas not found.'); }
else {

if (!canvas.getContext) { console.log('Context not supported.'); }
else {
const ctx = this.refs.canvas.getContext('2d');
if (!ctx) { console.log('Context 2D not available.'); }
else {
// 调用react函数, 从坐标(0,0)到(200,200)处, 颜色为黑色.
rect({ ctx, fromX: 0, fromY: 0, toX: 200, toY: 200, color: "#000" });
}
}
}
}
catch (exc) { console.log(exc); }
}

render() {
return (
<div>
<canvas id="canvas1" ref="canvas" width={300} height={300} />
</div>
)
}
}

export default LineRow;

index.js :

import React from 'react';
import ReactDOM from 'react-dom';


import LineRow from './LineRow'

ReactDOM.render(
<React.StrictMode>
{ <LineRow />}
</React.StrictMode>,
document.getElementById('root')
);

效果:

React中使用Canvas画箭头 - 前端_自定义