-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
Hey Matthias, I love the interface of your app but I am missing a "copy as function" feature. I see that you have found a niche with the css linear functions but I would love to design my Svelte transitions using the Easing Wizard. Right now, I am using this function that takes the css linear function as argument:
export interface Point {
x: number | null;
y: number;
}
export function cssLinear(str: string): (t: number) => number {
if (!str.startsWith("linear(") || !str.endsWith(")")) {
throw new Error("Invalid linear() easing string");
}
// remove linear( and )
const body = str.slice(7, -1).trim();
// split by commas
const parts = body.split(/\s*,\s*/);
// parse into points { x, y }
const points: Point[] = parts.map((part) => {
const nums = part.trim().split(/\s+/);
if (nums.length === 1) {
// single value → y only, x will be filled later
return { x: null, y: parseFloat(nums[0]) };
}
// value + percentage
const y = parseFloat(nums[0]);
const x = parseFloat(nums[1]) / 100; // convert % to [0,1]
return { x, y };
});
// ensure first and last points have x
if (points[0].x === null) points[0].x = 0;
if (points[points.length - 1].x === null) points[points.length - 1].x = 1;
// interpolate missing x values
for (let i = 1; i < points.length - 1; i++) {
if (points[i].x === null) {
const prevX = points[i - 1].x!;
const nextX = points.find((p, j) => j > i && p.x !== null)?.x ?? 1;
// distribute evenly among consecutive nulls
const nullCount = points.filter((p, j) => j >= i && p.x === null).length;
for (let k = 0; k < nullCount; k++) {
points[i + k].x = prevX + ((nextX - prevX) * (k + 1)) / (nullCount + 1);
}
}
}
// easing function: piecewise linear interpolation
return (t: number): number => {
for (let i = 0; i < points.length - 1; i++) {
const p1 = points[i];
const p2 = points[i + 1];
if (t >= p1.x! && t <= p2.x!) {
const ratio = (t - p1.x!) / (p2.x! - p1.x!);
return p1.y + ratio * (p2.y - p1.y);
}
}
return t; // fallback if out of range
};
}It works but feels like a crutch. Please add that tab next to CSS and Tailwind CSS :)
Cheers,
Nico
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels