canvas-sketch-util
Version:
Utilities for sketching in Canvas, WebGL and generative art
235 lines (144 loc) • 7.43 kB
Markdown
and so forth.
```js
const { lerp } = require('canvas-sketch-util/math');
console.log(lerp(0, 100, 0.5));
// -> 50
```
- [mod](
- [fract](
- [sign](
- [clamp](
- [clamp01](
- [degToRad](
- [radToDeg](
- [wrap](
- [pingPong](
- [lerp](
- [inverseLerp](
- [lerpArray](
- [lerpFrames](
- [linspace](
- [smoothstep](
- [damp](
- [dampArray](
- [mapRange](
- [expand2D](
- [expand3D](
- [expand4D](
<a name="mod"></a>
Computes `a % b` but handles negatives and always returns a positive result, so that `mod(-1, 4)` will return 3 (instead of -1 with regular modulo).
<a name="fract"></a>
Returns the fractional part of `n`, e.g. `fract(40.25)` will return `0.25`. This is defined as `x - floor(x)`
<a name="sign"></a>
Returns the sign (positive or negative) of `n`. If `n > 0` return 1, if `n < 0` return -1, otherwise return 0.
<a name="clamp"></a>
Clamps the number *n* between *min* (inclusive) and *max* (inclusive).
<a name="clamp01"></a>
Clamps the number *n* between 0 (inclusive) and 1 (inclusive). Convenience alias for `clamp(n, 0, 1)`.
<a name="degToRad"></a>
Converts `degrees` angle into `radians`, e.g. 180º will return `Math.PI`.
<a name="radToDeg"></a>
Converts `radians` angle into `degrees`, e.g. `Math.PI` will return 180º.
<a name="wrap"></a>
Wraps the `value` around the range `from` to `to`. Particularly useful for wrapping angles/radians around a circle.
```js
// Wrap degrees from 0..360
const angle = wrap(-180, 0, 360);
// Wrap radians from -PI to PI
const radians = wrap(-Math.PI * 2, -Math.PI, Math.PI);
```
<a name="pingPong"></a>
PingPongs the value *t*, so that it is never larger than *length* and never smaller than 0.
The returned value will move back and forth between 0 and length.
<a name="lerp"></a>
Linearly interpolates between *min* and *max* using the parameter *t*, where *t* is generally expected to be between 0..1 range. None of the inputs or outputs are clamped.
<a name="inverseLerp"></a>
Produces the inverse of `lerp`, in that you pass a value (a number between the range *min* and *max*) and get back a *t* value typically within the 0..1 range. None of the inputs or outputs are clamped.
<a name="lerpArray"></a>
Linearly interpolates between *minVector* and *maxVector* arrays using the parameter *t*, where *t* is generally expected to be between 0..1 range. The two vectors can be any dimension but are expected to match, and each value is interpolated componentwise. None of the inputs or outputs are clamped.
You can pass `out` to re-use an existing array instead of creating a new one.
Example:
```js
// Choose a random point within a 2D line segment
const start = [ 0, 0 ];
const end = [ 25, 10 ];
const t = Math.random();
const point = lerpArray(start, end, t);
```
<a name="lerpFrames"></a>
A utility to interpolate the evenly-spaced *frames* array using the parameter *t*, clamped between 0..1 range. The *frames* array can be an array of numbers which will use `lerp()`, or an array of arrays (vectors) which will use `lerpArray()`.
For example, it can be used to interpolate color ramps, 2D and 3D paths, keyframed animations, and so forth.
```js
const polyline = [
[ 0, 0 ], [ 20, 0 ], [ 20, 20 ], [ 0, 20 ], [ 0, 0 ]
];
// How far along our polyline to sample
const point = lerpKeyframes(polyline, 0.75);
```
<a name="linspace"></a>
Produces a linearly-spaced array of *N* numbers in an array, interpolating from 0 toward 1. By default, 1 is exclusive, but you can pass `inclusive` as true to interpolate to and include 1 as the final element.
For example:
```js
console.log(linspace(4));
// [ 0, 0.25, 0.5, 0.75 ]
console.log(linspace(5, true));
// [ 0, 0.25, 0.5, 0.75, 1 ]
```
<a name="smoothstep"></a>
Performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`. This is useful in cases where a threshold function with a smooth transition is desired.
<a name="damp"></a>
Smoothly interpolate a number from `a` toward `b` using the `lambda` power and `dt` (delta time typically in seconds) to maintain frame rate independent movement. For details, see [Frame Rate Independent Damping Using Lerp](http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/).
A higher `lambda` value will make the movement more sudden, and a lower value will make the movement more gradual.
<a name="dampArray"></a>
Smoothly interpolate a vector array from `a` toward `b` using the `lambda` power and `dt` (delta time typically in seconds) to maintain frame rate independent movement. For details, see [Frame Rate Independent Damping Using Lerp](http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/).
A higher `lambda` value will make the movement more sudden, and a lower value will make the movement more gradual.
The returned output is stored in `out` array, or if no parameter is given, a new array is created.
<a name="mapRange"></a>
Maps the *value* from one range of `[inputMin..inputMax]` to another range of `[outputMin..outputMax]`, with min/max being inclusive. By default, *value* is not clamped, but you can specify `clamp` as true to clamp the output within `outputMin` and `outputMax`.
```js
// Converts normalized -1..1 coordinate to screen coordinate
const x = -1;
const pixel = mapRange(x, -1, 1, 0, screenWidth, true);
```
<a name="expand2D"></a>
Expands the *value* into a 2D vector array, defaulting to `defaultValue` when *value* or one of its components is not a finite number. Here, *value* can be a number (expanding all components to that number) or an array of numbers.
This is useful to take a user input, like a scalar value, and expand it to a vector.
```js
console.log(expand2D(0.5)); // [ 0.5, 0.5 ]
console.log(expand2D(undefined, 1)); // [ 1, 1 ]
console.log(expand2D([ 0.5 ], 1)); // [ 0.5, 1 ]
console.log(expand2D([ 0.5, 0.5 ], 1)); // [ 0.5, 0.5 ]
console.log(expand2D([ null, 0.5 ], 1)); // [ 0.5, 0.5 ]
```
<a name="expand3D"></a>
Same as [expand2D](
<a name="expand4D"></a>
Same as [expand2D](
---
Holds common math functions, shaping functions, interpolation,