PROWAREtech

articles » current » javascript » lerp

JavaScript: LERP - Linear Interpolation Function

A useful function for easing the transition between two values over time (examples included).

LERP

First, LERP for reference:

``````
function lerp(a, b, t) {
return a + (b - a) * t;
}
``````

Or:

``````
function lerp(a, b, t) {
return a * (1 - t) + b * t;
}
``````

Linear interpolation makes it possible to precisely place a point between, before and after two points.

The heart of the code for the above looks like this.

``````
function lerp(a, b, t) {
return a * (1 - t) + b * t;
}
var p1 = {x: 50, y: 100};
var p2 = {x: 250, y: 100};
var t = 0.5; // 0.5 == 50% (the default value)
var p3 = {x: lerp(p1.x, p2.x, t), y: 100};
``````

VLERP

Now, this time, easy-in-out with using vector LERP (2 dimensions only).

VLERP for reference:

``````
function vLerp(p1, p2, t) {
return {
x: lerp(p1.x, p2.x, t),
y: lerp(p1.y, p2.y, t)
};
}
``````

Learn about ease in and out functions at https://easings.net/.

``````
function lerp(a, b, t) {
return a + (b - a) * t;
}
function vLerp(p1, p2, t) {
return {
x: lerp(p1.x, p2.x, t),
y: lerp(p1.y, p2.y, t)
};
}
function drawPoint(ctx, pos, text) {
ctx.beginPath();
ctx.fillStyle = "dodgerblue";
ctx.strokeStyle = "navy";
ctx.arc(pos.x, pos.y, 20, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = "bold 13px Courier";
ctx.fillText(text, pos.x, pos.y);
}
function updateLerpEx(t) {
if(isNaN(t)) { return; }
var cvs = document.getElementById("lerp-canvas");
var ctx = cvs.getContext("2d");
ctx.clearRect(0, 0, cvs.width, cvs.height);
var i = {x: 50, y: 100};
var j = {x: 250, y: 100};
drawPoint(ctx, i, "i");
drawPoint(ctx, j, "j");
drawPoint(ctx, {x: lerp(i.x, j.x, t), y: 100}, t);
}
updateLerpEx(0.5);
function animateEase() {
var cvs = document.getElementById("vlerp-canvas");
var ctx = cvs.getContext("2d");
ctx.clearRect(0, 0, cvs.width, cvs.height);
var i = {x: 30, y: 30};
var j = {x: 270, y: 270};
var t = (Math.sin(new Date().getTime() / 1000) + 1) * 0.5;
var c = vLerp(i, j, t)
drawPoint(ctx, i, "i");
drawPoint(ctx, j, "j");
drawPoint(ctx, c, Math.round(t * 10) / 10);
requestAnimationFrame(animateEase);
}
animateEase();
``````