Skip to content

Instantly share code, notes, and snippets.

@fdecampredon
Last active July 1, 2016 18:34
Show Gist options
  • Save fdecampredon/2c8e9ff8b20132e57306142f72f7297c to your computer and use it in GitHub Desktop.
Save fdecampredon/2c8e9ff8b20132e57306142f72f7297c to your computer and use it in GitHub Desktop.
Make bezier curve look alike sine
function quadraticBezier(t, p0, p1, p2) {
const x = (1 - t) * (1 - t) * p0.x + 2 * (1 - t) * t * p1.x + t * t * p2.x;
const y = (1 - t) * (1 - t) * p0.y + 2 * (1 - t) * t * p1.y + t * t * p2.y;
return { x, y };
}
const computeMiddle = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => ({
x: (x1 + x2) / 2,
y: (y1 + y2) / 2,
});
function sineBezier(origin, target, direction = 1) {
const { x: x1, y: y1 } = origin;
const { x: x2, y: y2 } = target;
const deltaX = (x1 - x2);
const deltaY = (y1 - y2);
const theta = Math.atan2(deltaY, deltaX) + Math.PI;
const dist = Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2);
const amplitude = dist / 20;
const middle = computeMiddle(origin, target);
const quarter = computeMiddle(origin, middle);
const threeQuarter = computeMiddle(middle, target);
const controlPointA = {
x: quarter.x + amplitude * Math.cos(theta + direction * Math.PI / 2),
y: quarter.y + amplitude * Math.sin(theta + direction * Math.PI / 2),
};
const controlPointB = {
x: threeQuarter.x + amplitude * Math.cos(theta - direction * Math.PI / 2),
y: threeQuarter.y + amplitude * Math.sin(theta - direction * Math.PI / 2),
};
return (t) => {
if (t <= 0.5) {
return quadraticBezier(
t * 2,
origin,
controlPointA,
middle,
);
}
return quadraticBezier(
(t - 0.5) * 2,
middle,
controlPointB,
target,
);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment