From 4838df315931bb883f704ec3e1abe2685f296cdf Mon Sep 17 00:00:00 2001 From: HsiangNianian Date: Sat, 22 Apr 2023 19:52:26 +0800 Subject: 😀 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/pack-home/PackBenchmarksGraph.tsx | 333 +++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 docs/components/pages/pack-home/PackBenchmarksGraph.tsx (limited to 'docs/components/pages/pack-home/PackBenchmarksGraph.tsx') diff --git a/docs/components/pages/pack-home/PackBenchmarksGraph.tsx b/docs/components/pages/pack-home/PackBenchmarksGraph.tsx new file mode 100644 index 0000000..a4792b8 --- /dev/null +++ b/docs/components/pages/pack-home/PackBenchmarksGraph.tsx @@ -0,0 +1,333 @@ +import cn from "classnames"; +import { + animate, + motion, + useInView, + useAnimation, + AnimationPlaybackControls, +} from "framer-motion"; +import Image from "next/image"; +import { useEffect, useRef, useState } from "react"; +import benchmarkData from "./benchmark-data/data.json"; +import { Gradient } from "../home-shared/Gradient"; +import gradients from "../home-shared/gradients.module.css"; +import { + BenchmarkBar, + BenchmarkCategory, + BenchmarkData, + BenchmarkNumberOfModules, +} from "./PackBenchmarks"; + +interface BenchmarksGraphProps { + category: BenchmarkCategory; + numberOfModules: BenchmarkNumberOfModules; + bars: BenchmarkBar[]; + pinTime?: true; +} + +export function BenchmarksGraph({ + category, + numberOfModules, + bars, + pinTime, +}: BenchmarksGraphProps) { + const data: BenchmarkData = benchmarkData[category][numberOfModules]; + const keys = bars.map((bar) => bar.key); + const longestTime = Math.max(...keys.map((key) => data[key])) * 1000; + const longestTimeWithPadding = longestTime * 1.15; + const graphRef = useRef(null); + const graphInView = useInView(graphRef, { once: true, margin: "-128px" }); + + return ( +
+
+ +
+
+ {bars.map((bar) => { + return ( + + } + duration={data[bar.key] * 1000} + longestTime={longestTimeWithPadding} + inView={graphInView} + pinTime={pinTime} + > + ); + })} +
+
+ ); +} + +const START_DELAY = 0.0; + +const graphBarVariants = { + initial: { + width: 0, + }, + progress: { + width: "100%", + }, +}; + +const graphBarWrapperVariants = { + hidden: { + opacity: 0, + }, + show: { + opacity: 1, + }, +}; + +function GraphBar({ + turbo, + duration, + longestTime, + inView, + Label, + pinTime, +}: { + turbo?: boolean; + duration: number; + longestTime: number; + Label: JSX.Element; + inView?: boolean; + // Pin the time + pinTime?: true; +}) { + const controls = useAnimation(); + const [timer, setTimer] = useState(0); + const [timerAnimation, setTimerAnimation] = + useState(); + const [barWidth, setBarWidth] = useState(0); + const [, setFinished] = useState(false); + + async function stopAnimation() { + timerAnimation && timerAnimation.stop(); + controls.stop(); + } + + async function resetAnimation() { + setTimer(0); + setFinished(false); + await controls.start("initial"); + } + + async function startAnimation() { + const transition = { + duration: duration / 1000, + delay: START_DELAY, + }; + setBarWidth((duration / longestTime) * 100); + await controls.start("show"); + controls + .start("progress", { + ...transition, + ease: "linear", + }) + .then(() => { + setFinished(true); + }); + const timerAnimationRef = animate(0, duration, { + ...transition, + ease: "linear", + onUpdate(value) { + setTimer(value); + }, + }); + setTimerAnimation(timerAnimationRef); + } + + async function playFullAnimation() { + await stopAnimation(); + await controls.start("hidden"); + await resetAnimation(); + await startAnimation(); + } + + useEffect(() => { + if (inView) { + void startAnimation(); + } else { + void stopAnimation(); + void resetAnimation(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [inView]); + + useEffect(() => { + if (!inView) return; + void playFullAnimation(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [duration, longestTime]); + + return ( +
+
{Label}
+
+ + + + + + +
+
+ ); +} + +const GraphTimer = ({ + turbo, + timer, + duration, +}: { + turbo: boolean; + timer: number; + duration: number; +}) => { + return ( +
+ {turbo && ( +
+ Turbopack + Turbopack + +
+ )} +

+

+
+ ); +}; + +function roundTo(num: number, decimals: number) { + const factor = Math.pow(10, decimals); + return Math.round(num * factor) / factor; +} + +const Time = ({ + value, + maxValue, +}: { + value: number; + maxValue: number; +}): JSX.Element => { + let unitValue: string; + let unit: string; + if (maxValue < 1000) { + unitValue = Math.round(value).toFixed(0); + unit = "ms"; + } else { + const roundedValue = roundTo(value / 1000, 1); + unitValue = roundedValue.toFixed(1); + unit = "s"; + } + + return ( + <> + {unitValue} + {unit} + + ); +}; + +function GraphLabel({ + label, + turbo, + swc, + mobileOnly, + esbuild, +}: { + label: string; + turbo?: boolean; + swc?: boolean; + mobileOnly?: boolean; + esbuild?: boolean; +}) { + return ( +
+

{label}

+ {turbo && ( +

+ turbo +

+ )} + {swc && ( +

+ with SWC +

+ )} + {esbuild && ( +

esbuild

+ )} +
+ ); +} -- cgit v1.2.3-70-g09d2