Graphics线性差值函数
Lerp
该函数根据 't' 参数在 [start..end] 范围内进行插值,其中 't' 通常在 [0..1] 范围内。它非常适合回答棘手的数学问题,例如:“56 到 132 之间的 35% 是多少?” 就可以这样计算 lerp(56, 132, 0.35)。
const lerp = (x, y, a) => x * (1 - a) + y * a;
lerp(0, 50, 0.5) // 25
lerp(20, 80, 0) // 20
t 值通常在 0 到 1 之间,可以认为有点像 0 到 100 之间的百分比范围。上面的例子中,0.5 的 t 值就像 50%。所以函数返回 0 到 50 之间的“50% 位置”:25
Clamp
该函数根据你给它的一个数字,然后规定最小值和最大值。如果你的值在最小值和最大值的范围内,它将返回它。如果它比最小值还小,它将返回最小值,如果比最大值还大则返回最大值。
const clamp = (a, min = 0, max = 1) => Math.min(max, Math.max(min, a));
clamp(24, 20, 30) // 24
clamp(12, 20, 30) // 20
clamp(32, 20, 30) // 30
Clamp对于防止错误的数字进入计算、阻止元素渲染到屏幕外等计算非常方便。
Inverse Lerp
与 lerp 的作用相反。不是传递一个小数和开始结束值,而是传递任何值,它会返回一个小数,无论你传递的值是否落在那个范围内。在内部,它还使用了一个Clamp函数。
const invlerp = (x, y, a) => clamp((a - x) / (y - x));
invlerp(50, 100, 75) // 0.5
invlerp(50, 100, 25) // 0
invlerp(50, 100, 125) // 1
对于滚动动画非常有用。比如“用户在本节中滚动了多远?”之类的问题。可以用如下代码巧妙地回答:
const position = el.getBoundingClientRect();
const howFarThrough = invlerp(
position.top,
position.bottom,
window.scrollY
);
Range
它是一种将值从一个数据范围转换为另一个数据范围的函数,非常有用。传入两个数据范围和一个位于数据范围一内的值。
const range = (x1, y1, x2, y2, a) => lerp(x2, y2, invlerp(x1, y1, a));
// Range 1 Range 2 Value
range(10, 100, 2000, 20000, 50) // 10000
比如,将 window.scrollY 从大范围转换为 0px 到 150px 之间的值。
const position = el.getBoundingClientRect();
const transformY = range(
position.top,
position.bottom,
0,
150,
window.scrollY
);
如果用户在该范围上方,它将被限制为 0px。如果在下方,它将被限制为 150 像素。在两者之间的所有位置,它会在值之间均匀插值。
参考
https://gist.github.com/MichaelRocks/f8f66230707bcd88a239
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/coerce-in.html
https://www.trysmudford.com/blog/linear-interpolation-functions/
https://twitter.com/FreyaHolmer/status/1175925036718444554
https://www.youtube.com/watch?v=NzjF1pdlK7Y

浙公网安备 33010602011771号