Building on my last article, Pretty Metaballs, I have seen a number of metaball examples that connect two circles, or that do so in a hub-and-spoke fashion.

Image for post
Image for post
Varun Vachhar’s Metaballs
Image for post
Image for post
paper.js hub-and-spoke meta-balls example

However, I wanted to create a function that would generate a single SVG path representing a meta-metaball! The function f(g) -> path would take g, a group element containing two or more circle elements, and output a closed path (ends with the Z command) around these circles. The result would look as follows:

Image for post
Image for post
Animation of meta-metaball

Here’s an example of an algorithm to do just that, as well as issues that might arise when building this tool:

Metaball circles to path algorithm

Image for post
Image for post
Metaball tangent points (modified, from Varun Vachhar)
  1. Traverse the DOM and get all circle elements with the group.
  2. Sort circles (i.e. vertically, horizontally, by Euclidean distance, etc).
  3. Find the 4 tangent points (TP) and 4 bezier curve handle points (see http://varun.ca/metaballs/)
  4. Start the path with M (moveTo) at TP 1 between circles 1 & 2.
  5. Draw a bezier curve, C, between TPs 1 & 2.
  6. Draw an arc, A, between TP 2 (circles 1–2) and TP 1 (circles 2–3).
  7. For terminal circles (0 or length-1), draw an arc between TP 2 & 3.
  8. Repeat twice (iterate once sorted and once reversed).
  9. Close the path with Z (the final arc should close where we started).

To illustrate this algorithm, I’ve created a graphic to show tangent points in red, handle points in yellow, and labels for the various components of the path (i.e. arcs & curves).

Image for post
Image for post
Annotated multi-metaball

Common issues when writing SVG algorithms

  • childNodes doesn’t work for SVG elements and children for SVG isn’t widely supported. Instead, I use querySelectorAll, though getElementsByTagName should work as well.
  • document.createElement doesn’t work for SVG elements, you have to document.createElementNS instead (and supply the SVG XML namespace).
  • Pay attention to the largeArcFlag & sweepFlag!
  • If you want to use SVG line animations, parameterize the starting point so the animation starts in a place of your choosing.

Where can we take it from here?

Image for post
Image for post
Two overlapping meta-metaballs

We can apply this algorithm to two or more partially-overlapping metaballs and use the CSS property mix-blend-mode to control how these paths blend together. In the above example, I’m using mix-blend-mode: screen.

That’s it for now, happy coding!

Written by

Writing to learn, writing to share. Science, Software & Sarcasm — https://barrasso.me

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store