Pure CSS animation #2: Metaballs
For a new project, I’m trying to experiment metaballs in a pictographic way. I am designing an identity that is composed of elements like loaders, spinners, and arrows that go in a futuristic interface way.

For that, I decided to make a series of elements that are designed by dots. That dots will be connected to each other by a blobby organic link depending on their size and moves.
During my studies, I did use libraries like paper.js to do things that I could do in processing directly on a website (before P5js arrived). And there is a metaballs example on their page.
But I searched for a way to get that in pure CSS, to make it lightweight and use JS for a more important side of the website. The method to make it simple is to play with blur and contrast. We just have to blur children’s items to smooth them and create overlaying sprites. After that, change the threshold increasing contrast, and posterize the result.
#parent { background: #fff;
-webkit-filter: brightness(1) contrast(100);
filter: brightness(1) contrast(100);}.child { background: #000;
width: 50px;
height: 50px;
border-radius: 50%;
-webkit-filter: blur(10px);
filter: blur(10px);}
After that, I wanted to make a really complex element, closer to a logotype, that has more personality.
I began to make a three-dot line, that I could re-use as a loader later. The code is quite the same and very simple.
.metaballs { -webkit-filter: brightness(.9) contrast(100);
filter: brightness(1) contrast(100);
position: fixed;
background: #fff;
width: 100vw;
height: 100vh;
padding: 10px 0px;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%) scale(2);
transform: translate(-50%, -50%) scale(2); & div {
background: lime;
left: 50%;
top: 50%;
width: 45px;
height: 45px;
-webkit-ftransform: translate(-50%, -50%);
transform: translate(-50%, -50%);
border-radius: 50%;
-webkit-filter: blur(12px);
filter: blur(10px);
position: absolute;
-webkit-animation-duration: 2s;
-webkit-animation-fill-mode: both;
-webkit-animation-name: pulse;
-webkit-animation-iteration-count: infinite;
&:first-child {
left: calc(50% - 60px);
}
&:last-child {
left: calc(50% + 60px);
}
@for $i from 1 through 3 { &:nth-of-type(#{$i}) {
-webkit-animation-delay: #{$i * 0.5}s;
} } }}@-webkit-keyframes pulse { 40% {
-webkit-transform: translate(-50%, -50%) scale(1.4);
}}
Now I have a line and decide to duplicate it and rotate it to create a circle. I played again with the scss for loop and the transform-origin to make a sun-link shape. The metaballs effect is focused line by line to bring them together. And I make the white background disappear using mix-blend-mode.
.metaballs__line { position: absolute;
-webkit-filter: brightness(.9) contrast(120);
filter: brightness(1) contrast(100);
mix-blend-mode: lighten; background: #000;
width: 200px;
height: 150px;
left: 50%;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
transform-origin: 0 50%; @for $i from 1 through 16 { &:nth-of-type(#{$i}) { -webkit-transform: translateY(-50%) rotate(#{$i*360/16}deg);
transform: translateY(-50%) rotate(#{$i*360/16}deg); } }}