A simple, efficient spring animation library for smooth, natural motion.
It even works well on the command line.
Harmonica is framework-agnostic and works well in 2D and 3D contexts. Simply
call NewSpring
with your settings to initialize and
Update
on each frame to animate.
import "github.com/charmbracelet/harmonica"
// A thing we want to animate.
sprite := struct{
x, xVelocity float64
y, yVelocity float64
}{}
// Where we want to animate it.
const targetX = 50.0
const targetY = 100.0
// Initialize a spring with framerate, angular frequency, and damping values.
spring := harmonica.NewSpring(harmonica.FPS(60), 6.0, 0.5)
// Animate!
for {
sprite.x, sprite.xVelocity = spring.Update(sprite.x, sprite.xVelocity, targetX)
sprite.y, sprite.yVelocity = spring.Update(sprite.y, sprite.yVelocity, targetY)
time.Sleep(time.Second/60)
}
For details, see the examples and the docs.
NewSpring
takes three values:
FPS(int)
utility function. Make0
1
, though it can go higher. Lower values are springier. For details,The damping ratio affects the motion in one of three different ways depending on how it's set.
A spring is under-damped when its damping ratio is less than 1
. An
under-damped spring reaches equilibrium the fastest, but overshoots and will
continue to oscillate as its amplitude decays over time.
A spring is critically-damped the damping ratio is exactly 1
. A critically
damped spring will reach equilibrium as fast as possible without oscillating.
A spring is over-damped the damping ratio is greater than 1
. An over-damped
spring will never oscillate, but reaches equilibrium at a slower rate than
a critically damped spring.
This library is a fairly straightforward port of Ryan Juckett’s excellent damped simple harmonic oscillator originally written in C++ in 2008 and published in 2012. Ryan’s writeup on the subject is fantastic.
We’d love to hear your thoughts on this project. Feel free to drop us a note!
Part of Charm.
Charm热爱开源 • Charm loves open source