Maze Pattern
A maze-themed background with customizable colors and size.
Find Your Way
maze-pattern-background-preview.jsx
import MazePatternBackground from "@/components/backgrounds/maze-pattern-background/maze-pattern-background";
const MazePatternBackgroundPreview = () => {
return (
<MazePatternBackground
mazeSize={10}
mazeColor="rgba(162,201,229,0.8)"
style={{
width: "100%",
height: "100%"
}}
wrapperProps={{
style: {
height: "100%",
display: "grid",
placeItems: "center",
}
}}
>
<h1>Find Your Way</h1>
</MazePatternBackground>
);
};
export default MazePatternBackgroundPreview; Installation
Run the command from your project root directory (the folder that contains package.json).
Terminal / Console
npx mosaicui-cli@latest backgrounds/maze-pattern-background 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 = "rgba(0,0,0,0)",
mazeColor = "rgba(127,127,127,0.5)",
mazeSize = 20,
children,
className,
wrapperProps = {},
wrapperTagName = "div",
...rest
} = props;
const {
className: wrapperClassName = "",
...restWrapperProps
} = wrapperProps;
const _mazeSize = Math.max(1, mazeSize);
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 { devicePixelRatio, canvasWidth, canvasHeight } = useMemo(() => {
const devicePixelRatio = Math.max(1, globalThis.devicePixelRatio || 1);
return {
devicePixelRatio,
canvasWidth: width * devicePixelRatio,
canvasHeight: height * devicePixelRatio,
};
}, [width, height]);
const ctx = useMemo(() => {
return canvasRef.current?.getContext("2d");
}, [canvasRef.current]);
const render = useCallback(() => {
ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
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,
devicePixelRatio,
backgroundColor,
mazeColor,
width,
height,
canvasWidth,
canvasHeight,
_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();
}, [mounted, render]);
return (
<div
{...rest}
ref={containerRef}
className={[
className,
styles["maze-pattern-background"]
].join(" ")}
>
<canvas
aria-hidden={true}
width={canvasWidth}
height={canvasHeight}
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;
}
} Props
Configure the component with the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| backgroundColor | string | No | "rgba(0,0,0,0)" | Background color behind the maze. |
| mazeColor | string | No | "rgba(127,127,127,0.5)" | 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. |