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
127 lines (114 loc) • 3.36 kB
JSX
import React, { useEffect } from 'react';
import { styled, keyframes, css } from '@mui/system';
const fadeinFrames = keyframes`
0% { opacity: 1; }
50% { opacity: 0.7; }
100% { opacity: 1; }
`;
const scaleFrames = keyframes`
0% { transform: scale3d(0.4, 0.4, 1); }
50% { transform: scale3d(2.2, 2.2, 1); }
100% { transform: scale3d(0.4, 0.4, 1); }
`;
const createMoveFrames = (i, startPositionY) => keyframes`
from {
transform: translate3d(${Math.random() * 100}vw, ${startPositionY}vh, 0);
}
to {
transform: translate3d(${Math.random() * 100}vw, -${startPositionY + Math.random() * 30}vh, 0);
}
`;
const Container = styled('div')`
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
background-color: #021027;
`;
const BackgroundImage = styled('img')`
display: block;
position: absolute;
top: 0;
left: 0;
object-fit: cover;
width: 100%;
height: 100%;
mask-image: radial-gradient(
white 0%,
white 30%,
transparent 80%,
transparent
);
`;
const CircleContainer = styled('div')`
position: absolute;
transform: translateY(-10vh);
animation-iteration-count: infinite;
animation-timing-function: linear;
width: ${(props) => props.size}px;
height: ${(props) => props.size}px;
left: ${(props) => props.left}%;
top: ${(props) => props.top}%;
animation: ${(props) => props.moveFrames} ${(props) => props.moveDuration}ms infinite linear,
${fadeinFrames} 200ms infinite, ${scaleFrames} 2s infinite;
animation-delay: ${(props) => props.moveDelay}ms;
& .circle {
width: 100%;
height: 100%;
border-radius: 50%;
mix-blend-mode: screen;
background-image: radial-gradient(
hsl(180, 100%, 80%),
hsl(180, 100%, 80%) 10%,
hsla(180, 100%, 80%, 0) 56%
);
animation-delay: ${(props) => props.circleDelay}ms;
}
`;
const Message = styled('p')`
position: absolute;
right: 20px;
bottom: 10px;
color: white;
font-family: "Josefin Slab", serif;
line-height: 27px;
font-size: 18px;
text-align: right;
pointer-events: none;
animation: ${keyframes`
from { opacity: 0; }
to { opacity: 1; }
`} 1.5s ease 5s forwards;
opacity: 0;
`;
const CiteBackground = ({ children }) => {
useEffect(() => {
const circles = Array.from({ length: 100 }, (_, i) => {
const startPositionY = Math.random() * 10 + 100;
const moveFrames = createMoveFrames(i, startPositionY);
return (
<CircleContainer
key={i}
size={Math.random() * 8 + 1}
left={Math.random() * 100}
top={Math.random() * 100}
moveFrames={moveFrames}
moveDuration={28000 + Math.random() * 9000}
moveDelay={Math.random() * 37000}
circleDelay={Math.random() * 4000}
>
<div className="circle" />
</CircleContainer>
);
});
return () => circles;
}, []);
return (
<Container>
<BackgroundImage src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/221808/sky.jpg" className="background" />
<Message>all your dreams can come true<br />if you have the courage to pursue them</Message>
{children}
</Container>
);
};
export default CiteBackground;