I am trying to figure out how can I create custom ease for d3 animation.
To elaborate, in CSS, animation-timing
function is controlled by cubic-bezier
value.
In my element, I have three rect- red, green, and blue.
red
rect is moved with an explicit cubic-bezier value animation-timing-function: cubic-bezier(0.42, 0, 1, 1);
.
For green
rect I have explicitly calculated the keyFrame
time%
and progress
using the following, given a cubic-bezier value. By doing this, I am explicitly telling the green
rect to move as per the calculation. Also, by doing this, I can convert a CSS cubic-bezier value to the pennerâs equation `(t,b,c,d) form.
// create percentage container
const pct = [];
for (let i = 0; i <= 100; i++) {
pct.push(i / 100);
}
//cubic-bezier
//const cubicBezCurvVal = "0.42, 0, 1, 1"
//split bezier curve value
var cleanVal = cubicBezCurvVal.split(",");
//clean space with map -retunrns new array with the function, original array unchnaged
var cleanVal = cleanVal.map((x) => parseFloat(x.replace(/ /g, "")));
//p0
const p0 = {
x: 0,
y: 0
};
//p3
const p3 = {
x: 1,
y: 1
};
//p1
const p1 = {
x: cleanVal[0],
y: cleanVal[1]
};
//p2
const p2 = {
x: cleanVal[2],
y: cleanVal[3]
};
const x0 = p0.x; //=0
const y0 = p0.y; //=0
const x1 = p1.x;
const y1 = p1.y;
const x2 = p2.x;
const y2 = p2.y;
const x3 = p3.x; //=1
const y3 = p3.y; //=1
/*given a time percentage, calculates the x-axis of the cubic bezier graph, i.e. time elpased% */
const x = (t) =>
Math.pow(1 - t, 3) * x0 +
3 * Math.pow(1 - t, 2) * t * x1 +
3 * (1 - t) * Math.pow(t, 2) * x2 +
Math.pow(t, 3) * x3;
/*given a time percentage, calculates the y-axis of the cubic bezier graph, i.e. progres% */
const y = (t) =>
Math.pow(1 - t, 3) * y0 +
3 * Math.pow(1 - t, 2) * t * y1 +
3 * (1 - t) * Math.pow(t, 2) * y2 +
Math.pow(t, 3) * y3;
//penner's easing equation p=f(t)
const c = width - 50; // c of t,b,c,d of penner's equation
const b = 0; // b of t,b,c,d of penner's equation
//create container
const time = []; //to collect values of x(t), i.e. time elapsed %
const progress = []; //to collect values of y(t), i.e. progress %
//get the time first --- goes into keyframe---not dependent on progress,i.e. y(t)
pct.forEach((a) => {
time.push(x(a));
});
//get the progress for each time --- goes into progress --- not dependent on time x(t)
pct.forEach((a) => {
progress.push(y(a) * c + b);
});
I also have blue
rect and I was wondering how can translate the same cubic-bezier value into a custom -ease function for d3?
I referred to custom bounce and tried this which did not work unfortunately.
function progress1(t) {
//p0
const p0 = {
x: 0,
y: 0
};
//p3
const p3 = {
x: 1,
y: 1
};
//p1
const p1 = {
x: cleanVal[0],
y: cleanVal[1]
};
//p2
const p2 = {
x: cleanVal[2],
y: cleanVal[3]
};
const x0 = p0.x; ///0
const y0 = p0.y; ///0
const x1 = p1.x;
const y1 = p1.y;
const x2 = p2.x;
const y2 = p2.y;
const x3 = p3.x; ////1
const y3 = p3.y; ////1
const progress =
Math.pow(1 - t, 3) * y0 +
3 * Math.pow(1 - t, 2) * t * y1 +
3 * (1 - t) * Math.pow(t, 2) * y2 +
Math.pow(t, 3) * y3;
return t >= 1 ? 1 : progress;
}