leumas-private-shared
Version:
Private React JSX Package For Leumas Shared Components, Headers, Footers, Asides, Login Pages, API Key Manager and much more. Styles and everything reusable to avoid DRY code across all of our subdomains
101 lines (86 loc) • 2.66 kB
JSX
import React, { useEffect, useRef, useState } from 'react';
import { styled } from '@mui/system';
const CanvasWrapper = styled('canvas')`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
background-color: black;
`;
const FunZoneBackground = ({ children }) => {
const canvasRef = useRef(null);
const [isHovered, setIsHovered] = useState(false);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
const w = window.innerWidth;
const h = window.innerHeight;
const rate = 60;
const arc = 100;
const size = 7;
const speed = 20;
const colors = ['red', '#f57900', 'yellow', '#ce5c00', '#5c3566'];
const parts = new Array(arc).fill().map(() => ({
x: Math.ceil(Math.random() * w),
y: Math.ceil(Math.random() * h),
toX: Math.random() * 5 - 1,
toY: Math.random() * 2 - 1,
c: colors[Math.floor(Math.random() * colors.length)],
size: Math.random() * size,
}));
const mouse = { x: 0, y: 0 };
canvas.width = w;
canvas.height = h;
const DistanceBetween = (p1, p2) => {
const dx = p2.x - p1.x;
const dy = p2.y - p1.y;
return Math.sqrt(dx * dx + dy * dy);
};
const MouseMove = (e) => {
mouse.x = e.layerX;
mouse.y = e.layerY;
};
const particles = () => {
ctx.clearRect(0, 0, w, h);
canvas.addEventListener('mousemove', MouseMove, false);
parts.forEach((li) => {
const distanceFactor = Math.max(
Math.min(15 - DistanceBetween(mouse, li) / 10, 10),
1
);
ctx.beginPath();
ctx.arc(li.x, li.y, li.size * distanceFactor, 0, Math.PI * 2, false);
ctx.fillStyle = li.c;
ctx.strokeStyle = li.c;
if (Math.random() > 0.5) ctx.stroke();
else ctx.fill();
li.x += li.toX * 0.05;
li.y += li.toY * 0.05;
if (li.x > w) li.x = 0;
if (li.y > h) li.y = 0;
if (li.x < 0) li.x = w;
if (li.y < 0) li.y = h;
});
setTimeout(particles, 1000 / rate);
};
if (isHovered) {
particles();
}
return () => {
canvas.removeEventListener('mousemove', MouseMove);
};
}, [isHovered]);
return (
<div
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
style={{ position: 'relative', width: '100%', height: '100%' }}
>
<CanvasWrapper ref={canvasRef} />
{children}
</div>
);
};
export default FunZoneBackground;