利用画布封装箭头直线
作为前端搬运工一枚 封装一个画布箭头直线功能 这也是前几天写的, 刚好手头忙完了就当记录一下我这个卑微且无力的打工仔。
1. x1: 直线起点的相对水平坐标。
2. y1: 直线起点的相对垂直坐标。
3. x2: 直线终点的相对水平坐标。
4. y2: 直线终点的相对垂直坐标。
5. width: 画布的宽度。
6. height: 画布的高度。
7. parentX: 父组件的水平偏移量,用于计算绝对位置。
8. parentY: 父组件的垂直偏移量,用于计算绝对位置。
import React, { useEffect, useRef } from 'react';
function ArrowLine(props) {
const { x1, y1, x2, y2, width, height, parentX, parentY } = props;
const canvasRef = useRef(null);
// 计算直线起点和终点的绝对位置
const absX1 = parentX + x1;
const absY1 = parentY + y1;
const absX2 = parentX + x2;
const absY2 = parentY + y2;
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
// 设置线条和填充颜色为红色 默认黑色
ctx.strokeStyle = 'red';
ctx.fillStyle = 'red';
// 绘制直线
ctx.beginPath();
ctx.moveTo(absX1, absY1);
ctx.lineTo(absX2, absY2<img src=");" alt="" width="30%" />
ctx.stroke();
// 绘制箭头
const angle = Math.atan2(absY2 - absY1, absX2 - absX1); // 计算直线的角度
const arrowLength = 10;
ctx.beginPath();
ctx.moveTo(absX2, absY2);
ctx.lineTo(
absX2 - arrowLength * Math.cos(angle - Math.PI / 6), // 计算箭头左侧点的坐标
absY2 - arrowLength * Math.sin(angle - Math.PI / 6)
);
ctx.lineTo(
absX2 - arrowLength * Math.cos(angle + Math.PI / 6), // 计算箭头右侧点的坐标
absY2 - arrowLength * Math.sin(angle + Math.PI / 6)
);
ctx.lineTo(absX2, absY2);
ctx.fill();
}, [absX1, absY1, absX2, absY2]);
return (
<canvas ref={canvasRef} width={width} height={height} style={{ position: 'absolute', left: 0, top: 0 }} />
);
}
export default ArrowLine;
注意:这个组件的父组件是用 position:'relative',相对定位形成的,传进来的每一个点位都是通过子绝父相 计算好的,不管是画布的宽 高 还是点位。都是动态的 会根据屏幕的大小从而生成新的点位。 面向有点难堪 不影响