this is spin.
@keyframes spin {
to {
transform: rotate(360deg)
}
}
this is what it looks like.
<div style="animation: 10s linear 0s infinite spin; display: flex; justify-content: center; align-items: center">
<!-- content -->
</div>


we can adjust the period using animation-duration and the phase using a negative animation-delay. (this makes the animation play immediately, but offset in time.)
<div style="animation: 10s linear 0s infinite spin; display: flex; justify-content: center; align-items: center">
<!-- content -->
</div>
<div style="animation: 5s linear 0s infinite spin; display: flex; justify-content: center; align-items: center">
<!-- content -->
</div>
<div style="animation: 10s linear -8s infinite spin; display: flex; justify-content: center; align-items: center">
<!-- content -->
</div>






we can spin the other way by using reverse.
<div style="animation: 10s linear 0s infinite reverse spin; display: flex; justify-content: center; align-items: center">
<!-- content -->
</div>


if we want to move in a circle, we can move our content to the side.
<div style="animation: 10s linear 0s infinite spin; display: flex; justify-content: center; align-items: center">
<div style="transform: translate(100px)">
<!-- content -->
</div>
</div>


we can adjust the radius by adjusting how much we move.
<div style="animation: 10s linear 0s infinite spin; display: flex; justify-content: center; align-items: center">
<div style="transform: translate(150px)">
<!-- content -->
</div>
</div>


we can stack spins by nesting divs that use spin.
<div style="animation: 10s linear 0s infinite spin; display: flex; justify-content: center; align-items: center">
<div style="transform:translate(100px)">
<div style="animation: 10s linear 0s infinite spin; display: flex; justify-content: center; align-items: center">
<div style="transform:translate(100px)">
<!-- content -->
</div>
</div>
</div>
</div>


now, what if we wanted motion that was different than spin? can we move in a triangle instead?
yes! if we express our target motion as a closed path in the complex plane, we can use a fourier series to approximate it using a sum of spins! (there are many good explainers out there.)
we'll sample our target motion, compute a discrete fourier transform, then pick out the largest components for our approximation.
(implementation details: we need to cancel out each rotation before applying the next one, since otherwise subsequent rotations will be affected by it. this also has the benefit of not rotating your content, like in the previous examples. spin also goes clockwise [decreasing angle], so we need to reverse it.)
here's a triangle made from only 4 spins! (well, 8, if you count the 4 extra spins to cancel those out.)


here's some examples! (note: might lag browser)
2 points (square wave) (20 components)

4 points (20 components)

sine wave (2 components)

linear (triangle wave) (8 components)

sawtooth wave (20 components)

triangle (20 components)

square (20 components)

"marquee" (20 components)

"dvd screensaver" (20 components)

bounce (20 components)

eggbug (30 components, using @nex3's vectorized eggbug)

