A simple, efficient spring animation library for smooth, natural motionšŸŽ¼

Harmonica

Harmonica Image
Latest Release GoDoc Build Status

A simple, efficient spring animation library for smooth, natural motion.

Harmonica OpenGL Demo

It even works well on the command line.

Harmonica TUI Demo

Usage

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.

Settings

NewSpring takes three values:

  • Time Delta: the time step to operate on. Game engines typically provide a way to determine the time delta, however if that's not available you can simply set the framerate with the included FPS(int) utility function. Make the framerate you set here matches your actual framerate.
  • Angular Velocity: this translates roughly to the speed. Higher values are faster.
  • Damping Ratio: the springiness of the animation, generally between 0 and 1, though it can go higher. Lower values are springier. For details, see below.

Damping Ratios

The damping ratio affects the motion in one of three different ways depending on how it's set.

Under-Damping

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.

Critical Damping

A spring is critically-damped the damping ratio is exactly 1. A critically damped spring will reach equilibrium as fast as possible without oscillating.

Over-Damping

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.

Acknowledgements

This library is a fairly straightforward port of Ryan Juckettā€™s excellent damped simple harmonic oscillator originally writen in C++ in 2008 and published in 2012. Ryanā€™s writeup on the subject is fantastic.

License

MIT


Part of Charm.

The Charm logo

Charmēƒ­ēˆ±å¼€ęŗ ā€¢ Charm loves open source

Owner
Charm
We build tools to make the command line glamorous
Charm
Comments
  • `go mod tidy` unable to pull Projectile, Point, Vector etc

    `go mod tidy` unable to pull Projectile, Point, Vector etc

    To reproduce, create a new go module with the contents of https://github.com/charmbracelet/harmonica/blob/master/examples/physics/main.go, run go mod tidy and run go build

    I expected a binary to compile, but instead I received:

    ; go build                                                                                                                                                                                                             
    # iamadrawist
    ./main.go:34:24: undefined: harmonica.Projectile
    ./main.go:35:23: undefined: harmonica.Point
    ./main.go:77:23: undefined: harmonica.Point
    ./main.go:78:23: undefined: harmonica.Vector
    ./main.go:79:23: undefined: harmonica.TerminalGravity
    ./main.go:81:25: undefined: harmonica.NewProjectile
    

    I think this is because the harmonica github project's most recently published tagged version is 0.1, which does not contain these files.

  • Generalize package to include projectiles

    Generalize package to include projectiles

    This update generalizes the package from a spring-centric one to a general-purpose animation library with thanks to @maaslalaniā€™s projectile motion contribution.

  • Change waitASec to wait

    Change waitASec to wait

    This is a tiny refactor that doesn't change any functionality.

    While playing around with this library, I saw that waitASec sometimes sleeps for 500ms and 750ms, for me this makes sense to call it wait instead of waitASec and accept a time.Duration instead of an int.

    Not a big deal either way though! Feel free to merge or close this PR.

    Great work on this library! :D

  • Expose Velocity and Acceleration on Projectiles

    Expose Velocity and Acceleration on Projectiles

    Exposes Velocity and Acceleration of the Projectile.

    This allows clients of harmonica projectiles to view the internal velocity and acceleration to perform calculations or checks based on these values.

    Use case: https://github.com/maaslalani/confetty/pull/4

  • Return pointer to projectile from `NewProjectile`

    Return pointer to projectile from `NewProjectile`

    I was mostly able to port all of the code from https://github.com/maaslalani/confetty to use the harmonica physics code.

    Using harmonica from confetty: https://github.com/maaslalani/confetty/pull/2

    All I needed to change was returning a pointer to the projectile instead of the value from the NewProjectile function and everything worked.

  • Introduce 2D + 3D projectile motion

    Introduce 2D + 3D projectile motion

    This PR introduces 2D and 3D projectile motion to be used with Harmonica. It's fairly simple for now but usable with stuff like https://github.com/maaslalani/confetty

    Example Usage:

    projectile := NewProjectile(FPS(60), Point{6.0, 100.0, 0.0}, Vector{2.0, 0.0, 0.0}, Vector{2.0, -9.81, 0.0})
    
    someUpdateLoop(func() {
      pos := projectile.Update()
    })
    

    NOTE, this is still missing:

    1. Projectile mass
    2. Forces (projectile.AddForce(Force{...})...))
    3. Collisions (maybe?)
  • issue running an example

    issue running an example

    when attempted to run example provided at https://github.com/charmbracelet/harmonica/blob/master/examples/spring/opengl/main.go returns error as below. wondering if am missing to install any package ?

    (base) āžœ  temp go run main.go
    # pkg-config --cflags  -- gl gl
    Package gl was not found in the pkg-config search path.
    Perhaps you should add the directory containing `gl.pc'
    to the PKG_CONFIG_PATH environment variable
    No package 'gl' found
    Package gl was not found in the pkg-config search path.
    Perhaps you should add the directory containing `gl.pc'
    to the PKG_CONFIG_PATH environment variable
    No package 'gl' found
    pkg-config: exit status 1
    # github.com/go-gl/glfw/v3.3/glfw
    vendor/github.com/go-gl/glfw/v3.3/glfw/c_glfw.go:4:10: fatal error: glfw/src/context.c: No such file or directory
        4 | #include "glfw/src/context.c"
          |          ^~~~~~~~~~~~~~~~~~~~
    compilation terminated.
    
    
  • Example with gio based gui

    Example with gio based gui

    Looks like a perfect match for gio.

    https://github.com/gioui/gio-example

    gio is a golang gui and from a brief look at your code it looks like a very good match for GIO,

    gio gives the opportunity to update gui elements on each frame tick for example.

Pixelizer is an efficient image pixelizer written in go

Pixelizer is an image pixelizer written in go. It allows very simple and intuitive CLI pixelization. Installation To install Pixelizer, you

Nov 10, 2022
This is old and unmaintained code, ignore it. starfish is a simple, SDL based, 2D graphics and user input library for Go. If you intend to work on it, please fork from the 'devel' branch, not 'master'. Current release: 0.12.0

What is starfish? What starfish is: starfish is a simple 2D graphics and user input library for Go built on SDL. What starfish is not: While it is bui

Jun 4, 2019
Pure Golang Library that allows simple LSB steganography on images
Pure Golang Library that allows simple LSB steganography on images

Steganography Lib Steganography is a library written in Pure go to allow simple LSB steganography on images. It is capable of both encoding and decodi

Dec 22, 2022
Very simple SVG to PNG converter library using the Inkscape.

svg2png Description Very simple SVG to PNG converter library using the Inkscape.

Jan 11, 2022
geoserver is a Go library for manipulating a GeoServer instance via the GeoServer REST API.
geoserver is a Go library for manipulating a GeoServer instance via the GeoServer REST API.

Geoserver geoserver Is a Go Package For Manipulating a GeoServer Instance via the GeoServer REST API. How to install: go get -v gopkg.in/hishamkaram/g

Dec 22, 2022
General purpose library for reading, writing and working with OpenStreetMap data

osm This package is a general purpose library for reading, writing and working with OpenStreetMap data in Go (golang). It has the ability to read OSM

Dec 30, 2022
S2 geometry library in Go

Overview S2 is a library for spherical geometry that aims to have the same robustness, flexibility, and performance as the best planar geometry librar

Jan 8, 2023
Go package for fast high-level image processing powered by libvips C library

bimg Small Go package for fast high-level image processing using libvips via C bindings, providing a simple programmatic API. bimg was designed to be

Jan 2, 2023
Image processing library and rendering toolkit for Go.

blend Image processing library and rendering toolkit for Go. (WIP) Installation: This library is compatible with Go1. go get github.com/phrozen/blend

Nov 11, 2022
Go bindings to OpenGL Utility Library

GLU This package offers minimal bindings for GLU functions. Usage go get github.com/go-gl-legacy/glu License Copyright 2012 The go-gl Authors. All ri

Aug 18, 2018
Go binding for the cairo graphics library

go-cairo Go binding for the cairo graphics library Based on Dethe Elza's version https://bitbucket.org/dethe/gocairo but significantly extended and up

Dec 19, 2022
A library for playing with colors in go (golang).
A library for playing with colors in go (golang).

go-colorful A library for playing with colors in Go. Supports Go 1.13 onwards. Why? I love games. I make games. I love detail and I get lost in detail

Dec 30, 2022
A lightning fast image processing and resizing library for Go

govips A lightning fast image processing and resizing library for Go This package wraps the core functionality of libvips image processing library by

Jan 8, 2023
A library to read, write, and transform Stereolithography (.stl) files in Go.

stl A library to read, write, and transform Stereolithography (.stl) files in Go. It is used in the command line STL manipulation tool stltool. Featur

Sep 26, 2022
Go Language Library for SVG generation
Go Language Library for SVG generation

SVGo: A Go library for SVG generation The library generates SVG as defined by the Scalable Vector Graphics 1.1 Specification (http://www.w3.org/TR/SVG

Jan 6, 2023
Twilio Go library

twilio-go A client for accessing the Twilio API with several nice features: Easy-to-use helpers for purchasing phone numbers and sending MMS messages

Nov 30, 2022
:eyeglasses: Go library for [d]encoding glTF 2.0 files
:eyeglasses: Go library for [d]encoding glTF 2.0 files

gltf A Go module for efficient and robust serialization/deserialization of glTF 2.0, a royalty-free specification for the efficient transmission and l

Jan 1, 2023
Port of webcolors library from Python to Go

go-webcolors A library for working with color names and color value formats defined by the HTML and CSS specifications for use in documents on the Web

Sep 26, 2022
Avatar generation library for GO language
Avatar generation library for GO language

GOvatar GOvatar is an avatar generation library written in GO Install To install the library and command-line program, use the following: $ go get -u

Dec 29, 2022