Skip to content

Usage

ixfx has a functional approach to forces. There are a range of pre-defined ‘force functions’ which can be combined together to manipulate data.

First, a thing that can be affected by a force has the Type ForceAffected . That means it has some of these properties:

type ForceAffected = {
position?:Point
velocity?:Point
acceleration?:Point
mass?:number
angularAcceleration?:number;
angularVelocity?:number;
angle?:number;
};

A basic thing, able to be force-affected can be as simple as:

const thing = {
position: { x: 0.5, y: 0.5 },
mass: 1
}

Velocity and acceleration are vectors, capturing movement in both x & y directions. They are also signed. A negative x value will mean that the thing is moving left, while a positive x value will mean it is moving to the right.

Now, rather than changing the position or velocity yourself, update it with the supplied ‘force functions’. These return a function which in turn apply the force to a thing.

We first create the forces we want to use.

For example, to give our thing some acceleration we might create an accelerationForce , and to slow it down, some friction based on velocityForce .

import { Forces } from "https://unpkg.com/ixfx/dist/modulation.js"
// Accelerate to right with a force of { x:0.1, y:0 }
const accelForce = Forces.accelerationForce({
x: 0.1,
y: 0
})
// Reduce velocity due to friction
const frictionForce = Forces.velocityForce(0.00001);

Now that the forces have been created, they can be used. Typically, you do this in an animation loop, so the thing gets updated over time.

Forces.apply takes an input ‘thing’ (ie. a Type Forces.ForceAffected object) and applies a list of forces in order, returning a copy of the input after all the changes have been made.

// Initialise thing
let thing = { position: { x: 0.5, y: 0.5 }, mass: 1 };
const loop = () => {
// Apply accelForce and frictionForce on to thing,
// setting it back again to the same variable
thing = Forces.apply(thing,
accelForce,
frictionForce);
// eg. use newly calculated position
moveElement(el, thing.position);
// Keep loop running
window.requestAnimationFrame(loop);
}
loop();

After applying a force, properties will be updated - typically its position and velocity. It’s up to you to use these values somehow, for example moving a HTML element or rendering on the canvas.

Once initialised, you probably don’t want to modify the thing directly, but rather do so through the application of forces.

The object you pass in to Forces.apply could have additional properties, these are preserved.

Force settings

When working with forces, keep in mind that the scaling of the numbers is interdependent. Values are very much ‘set to taste’, and while experimenting, try orders of magnitude up and down in order to figure out its effect.

For coordinates, it’s best to keep them relative (ie. x and y on a 0..1 scale), and map them to screen coordinates at only when necessary.