Installation

npm install humpf
# here is the copy/paste for yarn
yarn add humpf

Imports

Humpf has three main exports as well as a few types for TypeScript users:
(you can click on each to scroll to corresponding section)

import { Spring, SpringConfig, SpringValue } from 'humpf';
// Types exports (for TypeScript users only)

Springexport

Create a spring function using an optional config.
const spring = Spring();

This function returns a SpringFn function.

The Spring function accept an optional config parameter.

const spring = Spring({ equilibrium: 200 });

This config object must be of type SpringConfig (all properties are optional).

SpringConfigexport

The SpringConfig namespace contains a few helper function to create and minipulate SpringConfig object.

The SpringConfig export is also a type, see below for the definition of that type.

export const SpringConfig = {
// presets
basic,
gentle,
wobbly,
stiff,
slow,
// special presets
decay,
static,
// utils
findEquilibrium,
angularFrequencyFromMass,
angularFrequencyFromSpringConstant
};

Presets

Preset functions let you create pre defined SpringConfig object.

const spring = Spring(SpringConfig.basic());

Decay

Decay take a SpringConfig and returns a new SpringConfig where the equilibrium is proportional to the velocity and the dampingRatio is 1

You can use this to animate the end of a "drag" motion, once the user lift its finger but the object has some velocity left.

Initial velocity: 50

const spring = Spring(SpringConfig.decay({ velocity: 50 }));

You can adjust the "force" of the decay by changing the angularFrequency

Initial velocity: 50

Angular Frenquency: 1

const spring = Spring(SpringConfig.decay({ velocity: 50 }));

Static

The SpringConfig.static function produce a spring that does not move.

const spring = Spring(SpringConfig.static(200));
spring(time); // { pos: 200, vel: 0 }

findEquilibrium

Take a velocity and an optional angularFrequency and return the decay equilibrium.

const equilibrium = SpringConfig.findEquilibrium(50, 2);

angularFrequencyFromMass

Take a mass and an optional springContant and return the corresponding angularFrequency.

const angularFrequency = SpringConfig.angularFrequencyFromMass(100, 1);

angularFrequencyFromSpringConstant

Take a springContant and an optional mass and return the corresponding angularFrequency.

const angularFrequency = SpringConfig.angularFrequencyFromMass(1, 100);

SpringConfigtype

The SpringConfig type is used to create a Spring

Here are all its properties as well as the default values.

const DEFAULT_CONFIG: SpringConfig = {
// initial position
position: 0,
// initial velocity
velocity: 0,
// position to approach
equilibrium: 100,
// angular frequency of motion
angularFrequency: 1,
// damping ratio of motion
dampingRatio: 1,
// [advanced] multiply time by this value
timeScale: 1 / 100,
// time at which the animation should start (after timeScale has been applied)
timeStart: 0
};

To better understand the different options of the spring and how to use them take a look a the Article.

SpringFntype

The SpringFn type is the function returned by the Spring function.

This function take only one parameter: the time (as a number) and return a SpringResult object.

type SpringFn = (t: number) => SpringResult;

SpringResulttype

This object is the result of calling a SpringFn

This object contains two property pos and vel, corresponding to the position and velocity of the spring motion.

interface SpringResult {
pos: number;
vel: number;
}

Here is a small example combining everything above:

import { Spring, SpringConfig } from "humpf";
const spring = Spring(SpringConfig.basic());
spring(0); // { pos: 0, vel: 0}
spring(200); // { pos: 59, vel: 27 }
spring(400); // { pos: 90, vel: 7 }
spring(600); // { pos: 98, vel: 1 }
spring(800); // { pos: 100, vel: 0 }

SpringValueexport

The SpringValue constructor is a higher level tool to manage a spring animated value over time.

SpringValue is a function that take two optional parameters:

The result of this function is a SpringValue type.

const value = SpringValue(initialSpringConfig, options);

SpringValueOptionstype

The SpringValueOptions type is used to create a SpringValue.

export interface SpringValueOptions {
velocityThreshold: number; // (default: 0.01)
positionThreshold: number; // (default: 0.001)
onSpringChange: () => void;
now: () => number;
}

SpringValuetype

export interface SpringValue {
// get the current position
position: () => number;
// get the current velocity
velocity: () => number;
// is the current motion stable (done)
stable: () => boolean;
// get the current SpringConfig
getConfig: () => Readonly<Required<SpringConfig>>;
// Update the internal SpringConfig with a decay
decay: (angularFrequency?: number) => void;
// Update the internal SpringConfig and compute
// timeStart, position and velocity to get a continuous motion
update: (config: Partial<SpringConfig>) => void;
// Same as update except the config will override
// timeStart, position and velocity if provided
replace: (config: Partial<SpringConfig>) => void;
}

SpringValue example

Here is a simple example where we update the equilibrium of a SpringValue to be the same as the x position of the mouse.

This SpringValue is then used to animate the x position of the red ball.

// create the SpringValue
const xValue = SpringValue();
// update the equilibrium when the mouse move
body.addEventListener("mousemove", (event) => {
event.preventDefault();
xValue.update({ equilibrium: event.clientX - 15 });
});
// on each frame update the position of the bass
function render() {
const x = xValue.position();
ballElement.style.transform = `translate(${x}px, 0px)`;
requestAnimationFrame(render);
}
// start the render loop
render();
Open in CodeSandbox