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
121 lines (104 loc) • 2.88 kB
JSX
import React from 'react';
import { styled, keyframes, css } from '@mui/system';
const starCount = 50;
const fall = keyframes`
to {
transform: translate3d(-30em, 0, 0);
}
`;
const tailFade = keyframes`
0%, 50% {
width: var(--star-tail-length);
opacity: 1;
}
70%, 80% {
width: 0;
opacity: 0.4;
}
100% {
width: 0;
opacity: 0;
}
`;
const blink = keyframes`
50% {
opacity: 0.6;
}
`;
const randomRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const BackgroundWrapper = styled('div')`
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: radial-gradient(ellipse at bottom, #0d1d31 0%, #0c0d13 100%);
overflow: hidden;
position: relative;
width: 100%;
`;
const StarsWrapper = styled('div')`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: rotate(-45deg);
`;
const Star = styled('div')`
--star-color: var(--primary-color);
--star-tail-length: 6em;
--star-tail-height: 2px;
--star-width: calc(var(--star-tail-length) / 6);
--fall-duration: 9s;
--tail-fade-duration: var(--fall-duration);
position: absolute;
top: var(--top-offset);
left: 0;
width: var(--star-tail-length);
height: var(--star-tail-height);
color: var(--star-color);
background: linear-gradient(45deg, currentColor, transparent);
border-radius: 50%;
filter: drop-shadow(0 0 6px currentColor);
transform: translate3d(104em, 0, 0);
animation: ${fall} var(--fall-duration) var(--fall-delay) linear infinite, ${tailFade} var(--tail-fade-duration) var(--fall-delay) ease-out infinite;
@media screen and (max-width: 750px) {
animation: ${fall} var(--fall-duration) var(--fall-delay) linear infinite;
}
&::before, &::after {
position: absolute;
content: '';
top: 0;
left: calc(var(--star-width) / -2);
width: var(--star-width);
height: 100%;
background: linear-gradient(45deg, transparent, currentColor, transparent);
border-radius: inherit;
animation: ${blink} 2s linear infinite;
}
&::before {
transform: rotate(45deg);
}
&::after {
transform: rotate(-45deg);
}
${(props) => css`
--star-tail-length: ${randomRange(500, 750) / 100}em;
--top-offset: ${randomRange(0, 10000) / 100}vh;
--fall-duration: ${randomRange(6000, 12000) / 1000}s;
--fall-delay: ${randomRange(0, 10000) / 1000}s;
`}
`;
const MeteorShowerBackground = ({ children }) => {
return (
<BackgroundWrapper>
<StarsWrapper>
{Array.from({ length: starCount }).map((_, i) => (
<Star key={i} />
))}
</StarsWrapper>
{children}
</BackgroundWrapper>
);
};
export default MeteorShowerBackground;