Skip to content

Commit

Permalink
feat: add 404 animation (#1059)
Browse files Browse the repository at this point in the history
* feat: add 404 animation

* fix

* defer loading
  • Loading branch information
marcklingen authored Dec 3, 2024
1 parent 519b04d commit 19099d2
Show file tree
Hide file tree
Showing 6 changed files with 710 additions and 7 deletions.
90 changes: 90 additions & 0 deletions components/not-found-animation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import dynamic from "next/dynamic";
import { Canvas, useFrame } from "@react-three/fiber";
import { OrbitControls, Environment } from "@react-three/drei";
import { useRef } from "react";
import * as THREE from "three";
import { useTheme } from "nextra-theme-docs";

const CANVAS_STYLES = {
width: "100%",
height: "50vh",
minHeight: "400px",
} as const;

function MetallicKnot() {
const meshRef = useRef<THREE.Mesh>(null);
const { resolvedTheme } = useTheme();

useFrame((state) => {
if (meshRef.current) {
meshRef.current.rotation.x =
Math.sin(state.clock.elapsedTime * 0.3) * 0.2;
meshRef.current.rotation.y =
Math.sin(state.clock.elapsedTime * 0.2) * 0.3;
meshRef.current.position.y =
Math.sin(state.clock.elapsedTime * 0.5) * 0.1;
}
});

return (
<mesh ref={meshRef}>
<torusKnotGeometry args={[0.8, 0.2, 200, 32]} />
<meshPhysicalMaterial
color={resolvedTheme === "dark" ? "#E11312" : "#0A60B5"}
metalness={0.9}
roughness={0.1}
clearcoat={1}
clearcoatRoughness={0.1}
reflectivity={1}
envMapIntensity={2}
/>
</mesh>
);
}

function NotFoundAnimationComponent() {
return (
<Canvas
camera={{ position: [0, 0, 5], fov: 45 }}
gl={{
antialias: true,
toneMapping: THREE.ACESFilmicToneMapping,
toneMappingExposure: 1.5,
}}
style={CANVAS_STYLES}
>
<ambientLight intensity={0.2} />
<ambientLight intensity={0.1} color="#E01211" />
<spotLight
position={[10, 10, 10]}
angle={0.15}
penumbra={1}
intensity={1}
color="#ffffff"
/>
<spotLight
position={[-10, -10, -10]}
angle={0.15}
penumbra={1}
intensity={0.5}
color="#E01211"
/>
<MetallicKnot />
<OrbitControls
enableZoom={false}
enablePan={false}
autoRotate
autoRotateSpeed={1}
/>
<Environment preset="sunset" />
</Canvas>
);
}

export const NotFoundAnimation = dynamic(
() => Promise.resolve(NotFoundAnimationComponent),
{
ssr: false,
loading: () => <div style={CANVAS_STYLES} />,
}
);
3 changes: 2 additions & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.1",
"@react-three/drei": "^9.119.0",
"@react-three/fiber": "^8.17.10",
"@supabase/supabase-js": "^2.46.2",
"@tanstack/react-table": "^8.20.5",
"@vercel/og": "^0.6.4",
Expand Down Expand Up @@ -61,6 +63,7 @@
"tailwind-merge": "^2.5.5",
"tailwindcss": "^3.4.15",
"tailwindcss-animate": "^1.0.7",
"three": "^0.171.0",
"zod": "^3.23.8"
},
"devDependencies": {
Expand Down
5 changes: 4 additions & 1 deletion pages/404.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { NotFoundPage } from "nextra-theme-docs";
import { NotFoundAnimation } from "@/components/not-found-animation";

<div className="text-center py-20">
<div className="text-center sm:py-20">

<NotFoundAnimation />

# 404: Page Not Found

Expand Down
Loading

0 comments on commit 19099d2

Please sign in to comment.