Maze Pattern
A maze-themed background with customizable colors and size.
Find Your Way
1. Copy the component file
Create a new file called maze-pattern-background.jsx in
your reusable components folder (for example
/src/components/) and paste the following code
into it.
maze-pattern-background.jsx
import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import styles from "./maze-pattern-background.module.css";
const MazePatternBackground = (props) => {
const {
backgroundColor = "#000000",
mazeColor = "#6572e6",
mazeSize = 20,
children,
className,
wrapperProps = {},
wrapperTagName = "div",
...rest
} = props;
const {
className: wrapperClassName = "",
...restWrapperProps
} = wrapperProps;
const Wrapper = wrapperTagName || "div";
const containerRef = useRef(null);
const canvasRef = useRef(null);
const [mounted, setMounted] = useState(false);
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const ctx = useMemo(() => {
return canvasRef.current?.getContext("2d");
}, [canvasRef.current]);
const render = useCallback(() => {
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, width, height);
ctx.save();
for (let y = 0; y < height; y += mazeSize) {
for (let x = 0; x < width; x += mazeSize) {
ctx.beginPath();
if (Math.random() < 0.5) {
ctx.moveTo(x, y);
ctx.lineTo(x + mazeSize, y + mazeSize);
} else {
ctx.moveTo(x + mazeSize, y);
ctx.lineTo(x, y + mazeSize);
}
ctx.strokeStyle = mazeColor;
ctx.lineWidth = 1;
ctx.stroke();
ctx.closePath();
}
}
ctx.restore();
}, [ctx, backgroundColor, mazeColor, width, height, mazeSize]);
useEffect(() => {
const updateContainerDimensions = () => {
const {
width,
height,
} = containerRef.current.getBoundingClientRect();
setWidth(width);
setHeight(height);
};
const resizeObserver = new ResizeObserver(updateContainerDimensions);
resizeObserver.observe(containerRef.current);
updateContainerDimensions();
setMounted(true);
return () => {
resizeObserver.disconnect();
};
}, []);
useLayoutEffect(() => {
if (!mounted) return;
render();
}, [render]);
return (
<div
{...rest}
ref={containerRef}
className={[
className,
styles["maze-pattern-background"]
].join(" ")}
>
<canvas
aria-hidden={true}
width={width}
height={height}
ref={canvasRef}
/>
<Wrapper
{...restWrapperProps}
className={[
wrapperClassName,
styles["wrapper"]
].join(" ")}
>
{children}
</Wrapper>
</div>
)
};
export default memo(MazePatternBackground); 2. Copy the CSS module file
In the same folder, create a file called maze-pattern-background.module.css and paste the following CSS.
maze-pattern-background.module.css
.maze-pattern-background {
position: relative;
> canvas {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 1;
}
> .wrapper {
position: relative;
z-index: 2;
}
} 3. Use the component
Now you can import and use the component anywhere in your project.
maze-pattern-background-preview.jsx
import MazePatternBackground from "@/components/backgrounds/maze-pattern-background/maze-pattern-background";
const MazePatternBackgroundPreview = () => {
return (
<MazePatternBackground
style={{
width: "100%",
height: "100%"
}}
wrapperProps={{
style: {
height: "100%",
background: "rgba(0,0,0,0.25)",
display: "grid",
placeItems: "center",
color: "#fff",
}
}}
mazeSize={10}
>
<h1>Find Your Way</h1>
</MazePatternBackground>
);
};
export default MazePatternBackgroundPreview; Props
Configure the component with the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| backgroundColor | string | No | "#000000" | Background color behind the maze. |
| mazeColor | string | No | "#6572e6" | Color of the maze lines. |
| mazeSize | number | No | 20 | Size of each maze cell in pixels. |
| children | ReactNode | Yes | — | Content rendered on top of the maze background. |
| className | string | No | — | Additional CSS classes applied to the main container. |
| wrapperProps | React.HTMLAttributes<any> | No | — | Extra props passed to the wrapper element containing the children. |
| wrapperTagName | string | No | "div" | HTML tag used as the wrapper element around the children. |