画布封装箭头直线

74 阅读2分钟

利用画布封装箭头直线

作为前端搬运工一枚 封装一个画布箭头直线功能 这也是前几天写的, 刚好手头忙完了就当记录一下我这个卑微且无力的打工仔。

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',相对定位形成的,传进来的每一个点位都是通过子绝父相 计算好的,不管是画布的宽 高 还是点位。都是动态的 会根据屏幕的大小从而生成新的点位。 面向有点难堪 不影响

线图.png