From 623390a5de1352fd5b5e567cebd09a86f4c64b97 Mon Sep 17 00:00:00 2001 From: Claas Date: Tue, 19 Aug 2025 23:41:32 +0200 Subject: [PATCH] Add animated path --- src/Graph.tsx | 70 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/src/Graph.tsx b/src/Graph.tsx index 78cb766..0315346 100644 --- a/src/Graph.tsx +++ b/src/Graph.tsx @@ -136,7 +136,7 @@ function XAxisMarks({ }: { height: number; xMarks: number[]; - projectX: (x: number) => number; + projectX: Projector; }) { return ( @@ -152,7 +152,7 @@ function XAxisMarks({ data-x={xMark} class="stroke-[0.5] stroke-gray-400" /> - + {xMark} @@ -167,7 +167,7 @@ function YAxisMarks({ projectY, }: { yMarks: number[]; - projectY: (y: number) => number; + projectY: Projector; }) { return ( @@ -184,7 +184,7 @@ function YAxisMarks({ class="stroke-[0.5] stroke-gray-400" /> - + {yMark} @@ -194,6 +194,67 @@ function YAxisMarks({ ); } +type Projector = (value: number) => number; +let rerenderCount = 0; + +function Path({ + points, + projectX, + projectY, +}: { + points: Point[]; + projectX: Projector; + projectY: Projector; +}) { + const projected = points + .values() + .map(({ x, y }) => ({ + x: projectX(x), + y: projectY(y), + })) + .toArray(); + + let data = ""; + + /** + * A semicolon-separated list of entire path definitions (d="..."). This is where you define the key shapes: + */ + const values = `M${projected + .map(({ x, y }) => `${x},100`) + .join(" L")}; M${projected.map(({ x, y }) => `${x},${y}`).join(" L")}`; + console.debug("values", values); + /** + * A list of time markers (0 to 1) corresponding to each shape in {@link values}. This controls the timing of the bounce. + * For example, `0; 0.8; 1` would spend 80% of the duration moving to the overshoot shape and 20% settling back. + */ + const keyTimes = "0; 1"; + + /** + * "ease-out" easing function bezier curve points (x1, y1, x2, y2) in keySplines syntax. + * [MDN easing-function](https://developer.mozilla.org/en-US/docs/Web/CSS/easing-function#cubic-bezier-easing-function) + */ + const EASE_OUT_KEY_SPLINES = "0.42 0 1 1"; + + return ( + `${x},${y}`).join(" L")}`} + class="stroke-emerald-300 fill-none stroke-[0.5]" + > + {rerenderCount++} + + + ); +} + export default function Graph({ entries }: Properties) { // Need to curb time stamp or we get overflow const now = new Date(); @@ -323,6 +384,7 @@ export default function Graph({ entries }: Properties) { ); }} + {({ x, y }) => { return ( -- 2.51.2