Skip to content

rnkyr/metaballs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Blob effect in iOS

Swift 5.0 iOS 9+ swiftlint

The project demonstrates implementation of a 2D blob effect (or metaballs) written using UIKit. Project contains example setup and separated MetaballsView with the implementation of an effect.

Overview

Mostly inspired by these two articles I implemented the effect utilizing Bezier curves with the help of UIKit. During the R&D process, I tried a couple of approaches (like building pixel-by-pixel, marching squares and some more), but due to the nature of the rendering process on a mobile platform selected one is the most efficient. Each time a user move a ball (changes its position), the host view recalculates curves for each pair of balls.

Implementation details

There's a host view class MetaballsView which is responsible for building, configuring and interaction.

It holds a list of interactable UIViews (yep, it holds it twice due to the hierarchy, but in that case, it doesn't create any retain issues).

blobLayers is a two-dimensional array of CAShapeLayers that used to display blob connection between balls. To be able to directly access layer between i-th and j-th balls, the array is made two-dimensional so it could be accessed like blobLayers[i][j]. Due to mirroring, blobLayers[j][i] should be drawn the same as blobLayers[i][j], but I haven't optimized it yet, just ignoring the path.

The Blob entity calculates and holds information regarding tangent points and handle curves points.

The Metaball entity holds actual ball information and utilizes Blob to build a path with another Metaball and translate it into UIBezierPath. Basically, these two classes could be used to implement the same effect independently from UIKit.

The following image demonstrates the principle behind math.

There're two bezier curves: from point p1 to p3 with control points in h1 and h3, and inversed one from points p2 to p4 through h2, h4. Refer to debugging branch to view details.

For pixel-by-pixel implementation refer to this branch.

Releases

No releases published

Packages

No packages published

Languages