Animation-heavy personal portfolio on Next.js: a custom cursor, a page-transition loader, and canvas backgrounds.
canvas-animationscss-modulesdark-themehandcodednextjspersonal-websiteportfolioreact
1import React, { useState, useEffect } from "react";
2import { useRouter } from "next/router";
3import styles from "@styles/components/loader.module.css";
4
5const Loader = () => {
6 const router = useRouter();
7 const [ready, setReady] = useState(router.pathname !== "/");
8
9 useEffect(() => {
10 const handler = () => setReady(true);
11 window.addEventListener("loaderReady", handler);
12 return () => window.removeEventListener("loaderReady", handler);
13 }, []);
14
15 return (
16 <>
17 <div className={styles.grid}>
18 {Array(6)
19 .fill()
20 .map((_, i) => {
21 const column = i + 1;
22 return (
23 <div
24 key={column}
25 className={styles.gridColumn}
26 style={{
27 gridColumn: column,
28 ["--delay"]: `${column * 100}ms`,
29 ["--play-state"]: ready ? "running" : "paused",
30 }}
31 />
32 );
33 })}
34 <div
35 className={styles.indicator}
36 data-ready={ready ? "true" : "false"}
37 aria-hidden="true"
38 >
39 <span className={styles.dot} />
40 <span className={styles.dot} />
41 <span className={styles.dot} />
42 </div>
43 </div>
44 </>
45 );
46};
47
48export default Loader;