From b1f81a6b627b02f327e252f343a91e5bc951d90e Mon Sep 17 00:00:00 2001 From: Ameya Shenoy Date: Sat, 7 Jun 2025 14:09:58 +0530 Subject: [PATCH] chore: pills desktop complete Signed-off-by: Ameya Shenoy --- frontend/src/app/layout.tsx | 10 +- frontend/src/components/Navbar.tsx | 3 + frontend/src/components/PhysicsSimulation.tsx | 96 ++++++++++++++----- 3 files changed, 84 insertions(+), 25 deletions(-) diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 47b3da4..5301dfc 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from "next"; import { ThemeProvider } from "@/components/theme-provider"; -import { Geist, Geist_Mono, Space_Grotesk } from "next/font/google"; +import { Geist, Geist_Mono, Space_Grotesk, Space_Mono } from "next/font/google"; import "./globals.css"; import { NavigationMenu } from "@/components/Navbar"; @@ -20,6 +20,12 @@ const spaceGroteskSans = Space_Grotesk({ subsets: ["latin"], }); +const spaceMono = Space_Mono({ + weight: ["400", "700"], + variable: "--font-space-mono", + subsets: ["latin"], +}); + export const metadata: Metadata = { title: "Ameya Shenoy", description: @@ -34,7 +40,7 @@ export default function RootLayout({ return ( Talk + ); diff --git a/frontend/src/components/PhysicsSimulation.tsx b/frontend/src/components/PhysicsSimulation.tsx index b60352a..f8e3c72 100644 --- a/frontend/src/components/PhysicsSimulation.tsx +++ b/frontend/src/components/PhysicsSimulation.tsx @@ -5,7 +5,7 @@ import { useTheme } from "next-themes"; import Matter from "matter-js"; export function World() { - const containerRef = useRef(null); + const containerRef = useRef(null); const { resolvedTheme } = useTheme(); const getRandomXY = (width: number, height: number, radius: number) => { @@ -15,23 +15,25 @@ export function World() { }; const getBgColor = () => { if (typeof window !== "undefined") { - return ( - getComputedStyle(document.documentElement) - .getPropertyValue("--color-background") - .trim() || "#f0f0f0" - ); + return getComputedStyle(document.documentElement) + .getPropertyValue("--color-background") + .trim(); } - return "#f0f0f0"; }; useEffect(() => { const container = containerRef.current; + if (!container) { + return; + } + const width = container.offsetWidth; const height = container.offsetHeight; const bgColor = getBgColor(); const { Engine, + Events, Render, Bodies, Composite, @@ -103,21 +105,6 @@ export function World() { 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, { @@ -129,6 +116,69 @@ export function World() { }, }); + let pills: Matter.Body[] = []; + const pillsToRender = [ + "ENGINEERING MANAGER", + "NIX", + "PRINCIPAL ENGINEER", + "AI", + ]; + + pillsToRender.forEach(function (pillText) { + const fontSize = 32; + + const ctx = render.canvas.getContext("2d"); + ctx.font = `${fontSize}px Arial`; + const textWidth = ctx.measureText(pillText).width; + + const pillHeight = fontSize * 2; + const pillWidth = textWidth + pillHeight; + [randomX, randomY] = getRandomXY(width, height, radius); + const pill = Matter.Bodies.rectangle( + randomX, + randomY, + pillWidth, + 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: 1, + }, + }, + ); + + pills.push(pill); + const text = document.createElement("div"); + Object.assign(text.style, { + position: "absolute", + width: `${pillWidth}px`, + height: `${pillHeight}px`, + display: "flex", + justifyContent: "center", + alignItems: "center", + fontFamily: "Space Mono", + fontSize: `${fontSize}px`, + color: "black", + pointerEvents: "none", + }); + text.innerText = pillText; + + render.canvas.getContext("2d").measure; + document.body.appendChild(text); + + Events.on(engine, "afterUpdate", () => { + text.style.left = `${pill.position.x - pillWidth / 2 + 60}px`; + text.style.top = `${pill.position.y + pillHeight / 2 - 4}px`; + text.style.transform = `rotate(${pill.angle}rad)`; + }); + }); + // Add all elements to the world Composite.add(engine.world, [ ground, @@ -138,7 +188,7 @@ export function World() { ballGreen, ballBlue, ballRed, - pill, + ...pills, mouseConstraint, ]);