You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.3 KiB
88 lines
2.3 KiB
import { useCallback, useEffect, useRef } from "react";
|
|
|
|
const primaryLineColor = "rgb(203,213,245)";
|
|
const subLineColor = "rgb(226,231,232)";
|
|
|
|
export default function GridLayer(props: {
|
|
width: number;
|
|
height: number;
|
|
leftPadding: number;
|
|
rightPadding: number;
|
|
topPadding: number;
|
|
bottomPadding: number;
|
|
columns: number;
|
|
rows: number;
|
|
colCellNum: number;
|
|
rowCellNum: number;
|
|
}) {
|
|
const xStartPx = props.leftPadding;
|
|
const xEndPx = props.width - props.rightPadding;
|
|
const xStepPx = (props.width - props.leftPadding - props.rightPadding) / props.columns;
|
|
const xUnitPx = xStepPx / props.colCellNum;
|
|
const yStartPx = props.topPadding;
|
|
const yEndPx = props.height - props.bottomPadding;
|
|
const yStepPx = (props.height - props.topPadding - props.bottomPadding) / props.rows;
|
|
const yUnitPx = yStepPx / props.rowCellNum;
|
|
|
|
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
|
const drawGrid = useCallback(
|
|
(ctx: CanvasRenderingContext2D) => {
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = subLineColor;
|
|
for (let i = 1; i < props.columns * props.colCellNum; ++i) {
|
|
if (i % props.colCellNum === 0) continue;
|
|
ctx.moveTo(xStartPx + xUnitPx * i, yStartPx);
|
|
ctx.lineTo(xStartPx + xUnitPx * i, yEndPx);
|
|
}
|
|
for (let j = 1; j < props.rows * props.rowCellNum; ++j) {
|
|
if (j % props.rowCellNum === 0) continue;
|
|
ctx.moveTo(xStartPx, yStartPx + yUnitPx * j);
|
|
ctx.lineTo(xEndPx, yStartPx + yUnitPx * j);
|
|
}
|
|
ctx.stroke();
|
|
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = primaryLineColor;
|
|
for (let i = 0; i <= props.columns; ++i) {
|
|
ctx.moveTo(xStartPx + xStepPx * i, yStartPx);
|
|
ctx.lineTo(xStartPx + xStepPx * i, yEndPx);
|
|
}
|
|
for (let j = 0; j <= props.rows; ++j) {
|
|
ctx.moveTo(xStartPx, yStartPx + yStepPx * j);
|
|
ctx.lineTo(xEndPx, yStartPx + yStepPx * j);
|
|
}
|
|
ctx.stroke();
|
|
},
|
|
[
|
|
props.colCellNum,
|
|
props.columns,
|
|
props.rowCellNum,
|
|
props.rows,
|
|
xEndPx,
|
|
xStartPx,
|
|
xStepPx,
|
|
xUnitPx,
|
|
yEndPx,
|
|
yStartPx,
|
|
yStepPx,
|
|
yUnitPx,
|
|
]
|
|
);
|
|
|
|
useEffect(() => {
|
|
// 获取canvas的2D绘图上下文
|
|
const canvas = canvasRef.current;
|
|
if (!canvas) return;
|
|
|
|
const context = canvas.getContext("2d");
|
|
if (!context) return;
|
|
// 使用context对象进行绘图
|
|
drawGrid(context);
|
|
}, [drawGrid]);
|
|
|
|
return (
|
|
<div>
|
|
<canvas ref={canvasRef} width={props.width} height={props.height}></canvas>
|
|
</div>
|
|
);
|
|
}
|