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

5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
  1. import { useCallback, useEffect, useRef } from "react";
  2. const primaryLineColor = "rgb(203,213,245)";
  3. const subLineColor = "rgb(226,231,232)";
  4. export default function GridLayer(props: {
  5. width: number;
  6. height: number;
  7. leftPadding: number;
  8. rightPadding: number;
  9. topPadding: number;
  10. bottomPadding: number;
  11. columns: number;
  12. rows: number;
  13. colCellNum: number;
  14. rowCellNum: number;
  15. }) {
  16. const xStartPx = props.leftPadding;
  17. const xEndPx = props.width - props.rightPadding;
  18. const xStepPx = (props.width - props.leftPadding - props.rightPadding) / props.columns;
  19. const xUnitPx = xStepPx / props.colCellNum;
  20. const yStartPx = props.topPadding;
  21. const yEndPx = props.height - props.bottomPadding;
  22. const yStepPx = (props.height - props.topPadding - props.bottomPadding) / props.rows;
  23. const yUnitPx = yStepPx / props.rowCellNum;
  24. const canvasRef = useRef<HTMLCanvasElement | null>(null);
  25. const drawGrid = useCallback(
  26. (ctx: CanvasRenderingContext2D) => {
  27. ctx.beginPath();
  28. ctx.strokeStyle = subLineColor;
  29. for (let i = 1; i < props.columns * props.colCellNum; ++i) {
  30. if (i % props.colCellNum === 0) continue;
  31. ctx.moveTo(xStartPx + xUnitPx * i, yStartPx);
  32. ctx.lineTo(xStartPx + xUnitPx * i, yEndPx);
  33. }
  34. for (let j = 1; j < props.rows * props.rowCellNum; ++j) {
  35. if (j % props.rowCellNum === 0) continue;
  36. ctx.moveTo(xStartPx, yStartPx + yUnitPx * j);
  37. ctx.lineTo(xEndPx, yStartPx + yUnitPx * j);
  38. }
  39. ctx.stroke();
  40. ctx.beginPath();
  41. ctx.strokeStyle = primaryLineColor;
  42. for (let i = 0; i <= props.columns; ++i) {
  43. ctx.moveTo(xStartPx + xStepPx * i, yStartPx);
  44. ctx.lineTo(xStartPx + xStepPx * i, yEndPx);
  45. }
  46. for (let j = 0; j <= props.rows; ++j) {
  47. ctx.moveTo(xStartPx, yStartPx + yStepPx * j);
  48. ctx.lineTo(xEndPx, yStartPx + yStepPx * j);
  49. }
  50. ctx.stroke();
  51. },
  52. [
  53. props.colCellNum,
  54. props.columns,
  55. props.rowCellNum,
  56. props.rows,
  57. xEndPx,
  58. xStartPx,
  59. xStepPx,
  60. xUnitPx,
  61. yEndPx,
  62. yStartPx,
  63. yStepPx,
  64. yUnitPx,
  65. ]
  66. );
  67. useEffect(() => {
  68. // 获取canvas的2D绘图上下文
  69. const canvas = canvasRef.current;
  70. if (!canvas) return;
  71. const context = canvas.getContext("2d");
  72. if (!context) return;
  73. // 使用context对象进行绘图
  74. drawGrid(context);
  75. }, [drawGrid]);
  76. return (
  77. <div>
  78. <canvas ref={canvasRef} width={props.width} height={props.height}></canvas>
  79. </div>
  80. );
  81. }