input#spinStop(type='checkbox', name='spinStop')
- var ngon = 180
.chain
- for (var i = 0; i < ngon; ++i) {
.segment
- }
label(for='spinStop')
span S
span.flip
span.InTo TO
span.letterP P
View Compiled
body {
margin: 0;
background: #000;
height: 100vh;
display: grid;
overflow: hidden;
perspective: 100vmin;
}
body, body * {
transform-style: preserve-3d;
}
.chain {
display: flex;
flex-direction: row;
align-self: center;
position: absolute;
inset: 25vh -10vw;
justify-content: space-between;
animation: spin 6s linear infinite;
--spinAxis: x;
pointer-events: none;
}
@keyframes spin {
100% {
rotate: var(--spinAxis) 360deg;
}
}
.segment {
width: 1px;
height: 100%;
position: relative;
rotate: var(--spinAxis) calc(var(--turn)*12deg);
display: flex;
justify-content: center;
}
.segment::before {
content: '';
position: absolute;
width: 5vmin;
aspect-ratio: 1;
background-image: radial-gradient(at 30% 30%, #fff, hsl(calc(60deg*(var(--hue) - 1)) 100% 85%) 10%, hsl(calc(60deg*var(--hue)) 100% 25%) 50%, hsl(calc(60deg*(var(--hue) + .5)) 100% 10%) 66%, hsl(calc(60deg*(var(--hue) + .5)) 100% 5%) 75%);
border-radius: 50%;
box-shadow: inset -1px -1px hsl(calc(60deg*(var(--hue) + 1)) 100% 50%);
animation: counterSpin 6s linear infinite;
}
@keyframes counterSpin {
0% {
rotate: var(--spinAxis) calc(-1*var(--turn)*12deg);
}
100% {
rotate: var(--spinAxis) calc(-1*var(--turn)*12deg - 360deg);
}
}
.chain, .segment::before {
animation-delay: -.8s;
}
/* LOOPS / ITERATIONS */
@for $i from 1 through 6 {
.segment:nth-child(6n+#{$i}) {
--hue: #{$i};
}
}
@for $i from 1 through 30 {
.segment:nth-child(30n+#{$i}) {
--turn: #{$i};
}
}
/* PLAY/PAUSE TOGGLE */
input {
display: none;
}
label {
font-family: courier new;
font-size: 15vmin;
font-weight: bolder;
color: #fff;
place-self: center;
perspective: 50vmin;
}
label, span {
display: flex;
transition: all 1s ease-in-out;
}
.flip {
rotate: y 180deg;
}
.letterP {
rotate: y -180deg;
}
.InTo {
position: relative;
backface-visibility: hidden;
}
.InTo::before {
content: 'IN';
position: absolute;
inset: 0;
backface-visibility: hidden;
display: flex;
rotate: y 180deg;
}
#spinStop:not(:checked) ~ label {
isolation: isolate;
}
#spinStop:checked ~ label :is(.flip,.letterP)
{
rotate: y 0deg;
}
#spinStop:not(:checked) ~ .chain,
#spinStop:not(:checked) ~ .chain .segment::before {
animation-play-state: paused;
}
@media (orientation: portrait) {
.chain {
inset: -10vh 25vw;
flex-direction: column;
--spinAxis: y;
}
.segment {
width: 100%;
height: 1px;
justify-content: unset;
}
}
View Compiled
/* A step-by-step guide of how to make a 2D version of this, with comments on each line of code, in a tutorial on my blog at:
https://dev.to/mackfitz/particles-spiral-patterns-in-css-part-i-2p9n
https://mackfitz.hashnode.dev/particles-spiral-patterns-in-css-part-i */
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.