Last active
December 31, 2024 15:17
-
-
Save ultrox/9fd8be5f05cb8dbf13fd27e311224dc3 to your computer and use it in GitHub Desktop.
Lerp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Linearly interpolates between two values (`start` and `end`) based on a given interpolation factor `t`. | |
* | |
* @param start - The starting value of the interpolation. | |
* @param end - The ending value of the interpolation. | |
* @param t - A factor between `0.0` and `1.0` that determines the weight of the `end` value. | |
* - `t = 0.0`: Returns the `start` value. | |
* - `t = 1.0`: Returns the `end` value. | |
* - `0.0 < t < 1.0`: Returns a value between `start` and `end`, weighted proportionally to `t`. | |
* - Values outside the range `[0.0, 1.0]` result in extrapolation beyond the `start` and `end` range. | |
* | |
* @returns The interpolated value between `start` and `end`. | |
* | |
* @example | |
* ```typescript | |
* const value = lerp(0, 10, 0.5); // Returns 5 (midpoint) | |
* const value2 = lerp(0, 10, 0.0); // Returns 0 (start) | |
* const value3 = lerp(0, 10, 1.0); // Returns 10 (end) | |
* const value4 = lerp(0, 10, 1.5); // Returns 15 (extrapolation) | |
* ``` | |
*/ | |
const lerp = (start: number, end: number, t: number): number => { | |
return start * (1 - t) + end * t; | |
}; | |
// LERP as I lerend it first time. | |
// This is not the LERP you want to use, because | |
// how naive and 'dirty' it is. | |
// no containment, uses global state, lerp itself mutate stuff. | |
// raf not canceled, never clamped, etc | |
const circleEl = document.querySelector('.circle'); | |
const currentPoint = { x: 0, y: 0 }; | |
const targetPoint = { x: 0, y: 0 }; | |
function lerp() { | |
currentPoint.x = currentPoint.x + (targetPoint.x - currentPoint.x) * 0.1; | |
currentPoint.y = currentPoint.y + (targetPoint.y - currentPoint.y) * 0.1; | |
circleEl.style.setProperty('--x', currentPoint.x); | |
circleEl.style.setProperty('--y', currentPoint.y); | |
requestAnimationFrame(lerp); | |
} | |
requestAnimationFrame(lerp); | |
document.body.addEventListener('pointermove', (event) => { | |
targetPoint.x = event.clientX; | |
targetPoint.y = event.clientY; | |
// circleEl.style.setProperty('--x', event.clientX); | |
// circleEl.style.setProperty('--y', event.clientY); | |
}); |
Author
ultrox
commented
Dec 27, 2024
•
function createFollowAnimation({ onUpdate }) {
let af;
const state = {
targetPoint: { x: 0, y: 0 },
currentPoint: { x: 0, y: 0 }
};
function lerp(start, end, t) {
const k = (s, e) => {
const delta = e - s;
if (Math.abs(delta) < 0.01) {
return e;
}
return s * (1 - t) + t * e;
};
return {
x: k(start.x, end.x),
y: k(start.y, end.y)
};
}
function animate() {
console.count("fko");
cancelAnimationFrame(af);
state.currentPoint = lerp(state.currentPoint, state.targetPoint, 0.1);
if (state.currentPoint === state.targetPoint) {
return;
}
onUpdate(state.currentPoint);
af = requestAnimationFrame(animate);
}
function updateTargetPoint(x, y) {
state.targetPoint = { x, y };
}
return {
start: () => {
document.body.parentNode.addEventListener("pointermove", (event) =>
updateTargetPoint(event.clientX, event.clientY)
);
animate();
}
};
}
// Usage:
const animation = createFollowAnimation({
onUpdate: (point) => {
box.style.setProperty("--x", point.x);
box.style.setProperty("--y", point.y);
}
});
animation.start();
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment