<div class="penrose">
<div class="triangle"></div>
<div class="triangle"></div>
<div class="triangle"></div>
<div class="triangle"></div>
<div class="triangle"></div>
<div class="triangle"></div>
<div class="ball"></div>
</div>
*, *::before, *::after {
padding: 0;
margin: 0 auto;
box-sizing: border-box;
}
body {
background-color: #111;
color: #fff;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
$speed: 20s;
.penrose {
position: relative;
filter: drop-shadow(0 0 25px #000) drop-shadow(0 0 50px hsl(40, 75%, 15%));
}
.triangle {
position: absolute;
&:nth-child(-n + 3) {
width: 146px; height: 36px;
transform: translate(-50%, -50%) rotate(var(--aAngle)) translateX(31.4px) translateY(36px) skewX(-30deg);
background-image: linear-gradient(to right, #000a, #0000 50%);
animation: triangleZ1 $speed infinite step-end;
@keyframes triangleZ1 {
0%, 85% { z-index: 2; }
25% { z-index: -2; }
}
}
&:nth-child(n + 4) {
width: 50px; height: 205px;
transform: translate(-50%, -50%) rotate(var(--aAngle)) translateX(59.2px) translateY(-48.5px) skewX(30deg);
background-image: linear-gradient(#000a, #0000 50%);
animation: triangleZ2 $speed infinite step-end;
@keyframes triangleZ2 {
0%, 50% { z-index: 2;}
33.333% { z-index: -2;}
}
}
&:nth-child(3n) { background-color: hsl(40, 75%, 50%); --aAngle: 0; animation-delay: $speed * -1 / 3; }
&:nth-child(3n + 1) { background-color: hsl(40, 75%, 20%); --aAngle: 120deg; animation-delay: $speed * -0 / 3; }
&:nth-child(3n + 2) { background-color: hsl(40, 75%, 40%); --aAngle: 240deg; animation-delay: $speed * -2 / 3; }
}
.ball {
position: absolute;
width: 30px; height: 30px;
animation: ball $speed infinite ease-in-out;
@keyframes ball {
0%, 100% { transform: translate(-50%, -50%) translateX(0px) translateY(-171px); }
8.333% { transform: translate(-50%, -50%) translateX(110px) translateY(20px); }
16.666% { transform: translate(-50%, -50%) translateX(-30px) translateY(20px); }
25% { transform: translate(-50%, -50%) translateX(35px) translateY(-125px); }
33.333% { transform: translate(-50%, -50%) translateX(148px) translateY(90px); }
41.666% { transform: translate(-50%, -50%) translateX(-80px) translateY(90px); }
50% { transform: translate(-50%, -50%) translateX(0px) translateY(-50px); }
58.333% { transform: translate(-50%, -50%) translateX(110px) translateY(90px); }
66.666% { transform: translate(-50%, -50%) translateX(-148px) translateY(90px); }
75% { transform: translate(-50%, -50%) translateX(-25px) translateY(-115px); }
83.333% { transform: translate(-50%, -50%) translateX(50px) translateY(12px); }
91.666% { transform: translate(-50%, -50%) translateX(-110px) translateY(12px); }
}
&::before {
content: '';
position: absolute;
top: -50%; left: -100%;
width: 300%; height: 200%;
background-image: radial-gradient(#0005, #0000 50%);
animation: shadowDir $speed infinite step-end;
@keyframes shadowDir {
0% { transform: rotate(0deg) skewX(30deg); }
33.333% { transform: rotate(120deg) skewX(30deg); }
66.666% { transform: rotate(60deg) skewX(30deg); }
}
}
&::after {
content: '';
position: absolute;
width: 100%; height: 100%;
border-radius: 50%;
background-image: radial-gradient(circle at top, lightblue, #000 100%);
}
}
View Compiled
This Pen doesn't use any external CSS resources.