<div id="app"></div>
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background: linear-gradient(tomato -200%, black 70%, plum 250%);
overflow: hidden;
}
.star {
height: 10rem;
width: 10rem;
border: 1px solid rgba(255, 255, 255, .3);
border-radius: 50%;
z-index: 0;
transform: scale(1.1);
}
.star::before {
content: '';
position: absolute;
height: 20%;
width: 20%;
z-index: 10;
left: 40%;
top: 40%;
background: white;
border-radius: 50%;
box-shadow: 0 0 100px 100px white;
animation: pulse 5s infinite ease-out;
will-change: opacity;
}
.star-point {
height: 20rem;
width: 1px;
background: rgba(255, 255, 255, .5);
position: absolute;
left: 50%;
top: -50%;
box-shadow: 0 0 50px 40px rgba(255, 255, 255, .2);
border-radius: 50%;
will-change: transform;
}
.star-point-1 {
transform: rotate(-45deg);
z-index: 1;
animation: spin-backward 200s infinite linear;
}
.star-point-2 {
transform: rotate(45deg);
z-index: 2;
animation: spin-forward 200s infinite linear;
}
.star-point-3 {
z-index: 5;
height: 30rem;
top: -10rem;
animation: spin-forward 200s infinite linear;
}
.star-point-5 {
z-index: 6;
height: 30rem;
top: -10rem;
animation: spin-backward 200s infinite linear;
}
.star-point-4 {
transform: rotate(90deg);
z-index: 4;
}
@keyframes pulse {
0% {
opacity: 1;
}
50% {
opacity: 0.9;
}
100% {
opacity: 1;
}
}
@keyframes spin-forward {
100% {
transform: rotate(360deg);
}
}
@keyframes spin-backward {
100% {
transform: rotate(-360deg);
}
}
.generate-new-button {
position: absolute;
top: 2rem;
right: 2rem;
color: white;
background: transparent;
padding: 1rem;
text-transform: uppercase;
border-radius: 2px;
font-family: Arial;
letter-spacing: 2px;
font-size: .75rem;
cursor: pointer;
border: 2px solid white;
will-change: transform;
transition: transform 0.3s;
}
.generate-new-button:hover {
transform: scale(1.1);
}
.generate-new-button:focus {
outline: none;
}
const StarPoint = ({
className,
animationDuration
}) =>
<div
className={`${className} star-point`}
style={{animationDuration: animationDuration}}
/>;
const Star = ({
style,
animationDuration
}) =>
<div class="star" style={style}>
<StarPoint className="star-point-1" animationDuration={animationDuration}/>
<StarPoint className="star-point-2" animationDuration={animationDuration}/>
<StarPoint className="star-point-3" animationDuration={animationDuration}/>
<StarPoint className="star-point-4" animationDuration={animationDuration}/>
<StarPoint className="star-point-5" animationDuration={animationDuration}/>
</div>;
class App extends React.Component {
constructor() {
super();
}
renderStars = () => {
const stars = [];
const { height, width } = document.getElementsByTagName('body')[0].getBoundingClientRect();
const getN = () => Math.random().toFixed(2);
const left = () => getN() * width;
const top = () => getN() * height;
const animationDuration = () => `${getN() * 200}s`;
const scale = () => `scale(${getN() * 0.05})`;
const rotate = () => `rotate(${getN() * 1000}deg)`;
for (let i = 0; i < 20; i++) {
const transform = `${scale()} ${rotate()}`;
stars.push(
<Star style={{
transform: transform,
position: 'absolute',
left: left(),
top: top(),
}}
animationDuration={animationDuration()}
/>
);
for (let i = 0; i < 20; i++) {
const oneOrTwo = () => i % 2 === 0 ? '1px' : '2px';
stars.push(
<div
style={{
height: oneOrTwo(),
width: oneOrTwo(),
borderRadius: '50%',
background: 'white',
position: 'absolute',
left: left(),
top: top(),
}}
/>
)
}
}
return stars;
}
render() {
return [
this.renderStars(),
<Star />,
<button
className="generate-new-button"
onClick={() => this.forceUpdate()}
>
Generate New
</button>
]
}
}
ReactDOM.render(<App />, document.getElementById('app'));
View Compiled
This Pen doesn't use any external CSS resources.