Skip to main content

Spring Animation (spring)

An animation module based on a physical spring model. It simulates spring motion through tension and friction parameters, producing natural bounce effects.

Principle

Spring motion is controlled by two physical parameters:

  • Tension — Spring stiffness, larger values cause faster rebounds
  • Friction — Damping coefficient, larger values cause faster oscillation decay

Motion equation: acceleration = tension × (target position - current position) - friction × current velocity

The simulation advances using Euler integration with a fixed step size (1ms), automatically handling overshoot and oscillation.

Data Structure

struct spring_t {
float start; /* Current position */
float stop; /* Target position */
float velocity; /* Current velocity */
float tension; /* Tension */
float friction; /* Friction */
float acc; /* Accumulated time remainder */
};

API

void spring_init(struct spring_t * s, float start, float stop, float velocity, float tension, float friction);

Initialize the spring. start is the starting position, stop is the target position, velocity is the initial velocity, tension is the spring stiffness, and friction is the damping coefficient.

int spring_step(struct spring_t * s, float dt);

Advance by dt seconds, internally integrating with 1ms steps. Returns 1 if motion has not ended, returns 0 when the target is reached (both position and velocity are within 0.005 precision). dt is capped at 83ms; values exceeding this are truncated.

float spring_position(struct spring_t * s);

Get the current position.

float spring_velocity(struct spring_t * s);

Get the current velocity.

Parameter Reference

Effecttensionfriction
Fast rebound40030
Medium rebound20020
Slow rebound10015
Almost no oscillation20040
Noticeable oscillation20010

Usage Examples

Basic Spring Animation

struct spring_t s;
spring_init(&s, 0, 300, 0, 200, 20);

while(spring_step(&s, 0.016))
{
float pos = spring_position(&s);
set_position(pos);
}
float final_pos = spring_position(&s); /* ≈ 300 */

With Initial Velocity

struct spring_t s;
spring_init(&s, 0, 100, 500, 180, 15); /* Initial velocity 500 toward target */

Chained Animation

spring_init(&s, current_pos, new_target, 0, 200, 20);
/* Re-initialize each time the target changes */