feat: considerable progress

Signed-off-by: Ameya Shenoy <shenoy.ameya@gmail.com>
This commit is contained in:
Ameya Shenoy 2025-06-05 02:17:50 +05:30
parent 3a9b5a38af
commit 57f3540834
10 changed files with 204 additions and 9 deletions

View file

@ -13,6 +13,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.511.0",
"matter-js": "^0.20.0",
"next": "15.3.3",
"next-themes": "^0.4.6",
"react": "^18.3.1",
@ -2025,6 +2026,12 @@
"@jridgewell/sourcemap-codec": "^1.5.0"
}
},
"node_modules/matter-js": {
"version": "0.20.0",
"resolved": "https://registry.npmjs.org/matter-js/-/matter-js-0.20.0.tgz",
"integrity": "sha512-iC9fYR7zVT3HppNnsFsp9XOoQdQN2tUyfaKg4CHLH8bN+j6GT4Gw7IH2rP0tflAebrHFw730RR3DkVSZRX8hwA==",
"license": "MIT"
},
"node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",

View file

@ -14,6 +14,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.511.0",
"matter-js": "^0.20.0",
"next": "15.3.3",
"next-themes": "^0.4.6",
"react": "^18.3.1",

View file

@ -1,4 +1,4 @@
export default function Home() {
export default function Blog() {
return (
<main className="flex items-center justify-center h-screen">
This is blog list page

View file

@ -127,4 +127,15 @@
white-space: nowrap;
box-sizing: border-box;
}
.text-pill {
background: #e53e3e;
border-radius: 9999px;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.875rem;
font-weight: 500;
color: white;
pointer-events: none;
}
}

View file

@ -42,12 +42,11 @@ export default function RootLayout({
enableSystem
disableTransitionOnChange
>
<div className="min-h-screen">
<NavigationMenu />
{children}
<footer className=""></footer>
</div>
<div className="min-h-screen">
<NavigationMenu />
{children}
<footer className="flex"></footer>
</div>
</ThemeProvider>
</body>
</html>

View file

@ -1,8 +1,11 @@
import { NameComponent } from "@/components/NameComponent";
import { World } from "@/components/PhysicsSimulation";
export default function Home() {
return (
<main className="flex items-center justify-center h-screen">
<main className="flex flex-col items-center justify-start pt-15 h-screen">
<World />
<NameComponent />
</main>
);

View file

@ -1,4 +1,4 @@
export default function Home() {
export default function Portfolio() {
return (
<main className="flex items-center justify-center h-screen">
This is portfolio

View file

@ -0,0 +1,7 @@
export default function Talk() {
return (
<main className="flex items-center justify-center h-screen">
This is talk
</main>
);
}

View file

@ -14,6 +14,9 @@ export function NavigationMenu() {
<Button variant="ghost">
<Link href="/portfolio">Portfolio</Link>
</Button>
<Button variant="ghost">
<Link href="/talk">Talk</Link>
</Button>
<ModeToggle />
</div>
);

View file

@ -0,0 +1,164 @@
"use client";
import { useEffect, useRef } from "react";
import { useTheme } from "next-themes";
import Matter from "matter-js";
export function World() {
const containerRef = useRef(null);
const { resolvedTheme } = useTheme();
const getRandomXY = (width: number, height: number, radius: number) => {
const randomX = Math.floor(Math.random() * (width - 2 * radius)) + radius;
const randomY = Math.floor(Math.random() * (height - 2 * radius)) + radius;
return [randomX, randomY];
};
const getBgColor = () => {
if (typeof window !== "undefined") {
return (
getComputedStyle(document.documentElement)
.getPropertyValue("--color-background")
.trim() || "#f0f0f0"
);
}
return "#f0f0f0";
};
useEffect(() => {
const container = containerRef.current;
const width = container.offsetWidth;
const height = container.offsetHeight;
const bgColor = getBgColor();
const {
Engine,
Render,
Bodies,
Composite,
Runner,
Mouse,
MouseConstraint,
} = Matter;
const engine = Engine.create();
engine.gravity.y = 0.3;
engine.enableSleeping = false;
const render = Render.create({
element: container,
engine,
options: {
width,
height,
wireframes: false,
background: bgColor,
},
});
// Bottom wall (ground)
const ground = Bodies.rectangle(width / 2, height - 10, width, 20, {
isStatic: true,
render: { fillStyle: bgColor },
});
// Left wall
const leftWall = Bodies.rectangle(-10, height / 2, 20, height + 40, {
isStatic: true,
render: { fillStyle: bgColor },
});
// Right wall
const rightWall = Bodies.rectangle(
width + 10,
height / 2,
20,
height + 40,
{
isStatic: true,
render: { fillStyle: bgColor },
},
);
// Top wall
const topWall = Bodies.rectangle(width / 2, -10, width, 20, {
isStatic: true,
render: { fillStyle: bgColor },
});
// Random ball position
const radius = 15;
let [randomX, randomY] = getRandomXY(width, height, radius);
const ballRed = Bodies.circle(randomX, randomY, radius, {
restitution: 0.8,
render: { fillStyle: "red" },
});
[randomX, randomY] = getRandomXY(width, height, radius);
const ballBlue = Bodies.circle(randomX, randomY, radius, {
restitution: 0.8,
render: { fillStyle: "blue" },
});
[randomX, randomY] = getRandomXY(width, height, radius);
const ballGreen = Bodies.circle(randomX, randomY, radius, {
restitution: 0.8,
render: { fillStyle: "green" },
});
const pillHeight = 50;
const pill = Matter.Bodies.rectangle(randomX, randomY, 200, pillHeight, {
chamfer: { radius: pillHeight / 2 },
isStatic: false,
density: 0.001,
friction: 0.05,
frictionAir: 0.01,
render: {
fillStyle: "rgba(255, 255, 255, 0)", // transparent fill
strokeStyle: "#000000", // black border
lineWidth: 2,
},
});
// Mouse interaction
const mouse = Mouse.create(render.canvas);
const mouseConstraint = MouseConstraint.create(engine, {
mouse,
constraint: {
stiffness: 1,
angularStiffness: 0,
render: { visible: false },
},
});
// Add all elements to the world
Composite.add(engine.world, [
ground,
leftWall,
rightWall,
topWall,
ballGreen,
ballBlue,
ballRed,
pill,
mouseConstraint,
]);
Render.run(render);
const runner = Runner.create();
Runner.run(runner, engine);
return () => {
Render.stop(render);
Runner.stop(runner);
Composite.clear(engine.world);
Engine.clear(engine);
render.canvas.remove();
};
}, [resolvedTheme]);
return (
<div
ref={containerRef}
className="w-[95vw] h-[40vh] mx-auto relative overflow-hidden"
/>
);
}