From d64bb10fa80c6559494642b5dcce668d25511f4e Mon Sep 17 00:00:00 2001 From: oimwiodev Date: Sat, 16 May 2026 15:00:39 +0100 Subject: [PATCH] Simplify mobile menu animation --- CHANGELOG.md | 2 +- components/Navbar.tsx | 105 +++++++++++------------------------------- 2 files changed, 29 insertions(+), 78 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82289d8..c07ebff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to the New Optic website will be documented in this file. ### Changed - Removed the desktop liquid glass WebGL layer from navbar and CTA controls so text remains readable and glass surfaces do not show dark rendering artifacts while scrolling. -- Made the mobile hamburger menu open with springy jelly motion and added a draggable corner grip that stretches the menu before snapping back. +- Replaced the mobile hamburger dropdown with a fast, solid menu animation without bounce or stretch effects. ## [1.0.0] - 2026-05-16 diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 14ac74f..74f6dc2 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -1,7 +1,7 @@ "use client"; -import { AnimatePresence, motion, useMotionValue, useSpring, useTransform } from "framer-motion"; -import { Grip, Menu, X } from "lucide-react"; +import { AnimatePresence, motion } from "framer-motion"; +import { Menu, X } from "lucide-react"; import Image from "next/image"; import { type MouseEvent, useState } from "react"; import { business, type Locale } from "@/config/business"; @@ -11,22 +11,6 @@ import PhysicsButton from "./PhysicsButton"; export default function Navbar({ locale, onLocaleChange, t, whatsappUrl }: { locale: Locale; onLocaleChange: (locale: Locale) => void; t: Messages; whatsappUrl: string }) { const [open, setOpen] = useState(false); - const stretchX = useMotionValue(0); - const stretchY = useMotionValue(0); - const springX = useSpring(stretchX, { stiffness: 260, damping: 13, mass: 0.34 }); - const springY = useSpring(stretchY, { stiffness: 260, damping: 13, mass: 0.34 }); - const menuScaleX = useTransform(springX, [-70, 0, 96], [0.9, 1, 1.22]); - const menuScaleY = useTransform(springY, [-54, 0, 104], [0.88, 1, 1.18]); - const menuSkewX = useTransform(springX, [-70, 0, 96], [-5.5, 0, 7]); - const menuRadius = useTransform(springY, [-54, 0, 104], ["2.65rem", "2rem", "2.9rem"]); - const sheenX = useTransform(springX, [-70, 0, 96], ["-18%", "0%", "20%"]); - const cornerX = useSpring(stretchX, { stiffness: 520, damping: 20, mass: 0.24 }); - const cornerY = useSpring(stretchY, { stiffness: 520, damping: 20, mass: 0.24 }); - - function releaseMenuStretch() { - stretchX.set(0); - stretchY.set(0); - } function scrollToSection(event: MouseEvent, href: string) { if (!href.startsWith("#")) return; @@ -70,8 +54,8 @@ export default function Navbar({ locale, onLocaleChange, t, whatsappUrl }: { loc setOpen((value) => !value)} - whileTap={{ scaleX: 1.22, scaleY: 0.82 }} - transition={{ type: "spring", stiffness: 520, damping: 14, mass: 0.32 }} + whileTap={{ scale: 0.94 }} + transition={{ duration: 0.08 }} className="grid size-11 place-items-center rounded-full bg-white/70 text-ink outline-none transition focus-visible:ring-2 focus-visible:ring-optical/45 focus-visible:ring-offset-2" aria-label={t.nav.menu} aria-expanded={open} @@ -84,64 +68,31 @@ export default function Navbar({ locale, onLocaleChange, t, whatsappUrl }: { loc {open ? ( - - - -
- {t.nav.links.map((link) => ( - scrollToSection(event, link.href)} - initial={{ opacity: 0, x: locale === "ar" ? -28 : 28, scaleX: 0.86 }} - animate={{ opacity: 1, x: 0, scaleX: 1 }} - transition={{ type: "spring", stiffness: 680, damping: 22, mass: 0.26 }} - whileTap={{ scaleX: 1.12, scaleY: 0.86 }} - className="rounded-2xl px-4 py-3 text-sm font-semibold text-ink/72 hover:bg-white" - > - {link.label} - - ))} -
-
- -
- { - stretchX.set(Math.max(-70, Math.min(96, info.offset.x))); - stretchY.set(Math.max(-54, Math.min(104, info.offset.y))); - }} - onDragEnd={releaseMenuStretch} - onPointerUp={releaseMenuStretch} - style={{ x: cornerX, y: cornerY }} - className="absolute bottom-3 right-3 z-[3] grid size-9 touch-none cursor-grab place-items-center rounded-full border border-ink/10 bg-white/80 text-ink/55 shadow-sm outline-none transition focus-visible:ring-2 focus-visible:ring-optical/35 active:cursor-grabbing rtl:left-3 rtl:right-auto" - > - - -
+
+ {t.nav.links.map((link) => ( + scrollToSection(event, link.href)} + initial={{ opacity: 0, x: locale === "ar" ? -8 : 8 }} + animate={{ opacity: 1, x: 0 }} + transition={{ duration: 0.1, ease: "easeOut" }} + whileTap={{ scale: 0.98 }} + className="rounded-2xl px-4 py-3 text-sm font-semibold text-ink/72 hover:bg-smoke" + > + {link.label} + + ))} +
+
+ +
) : null}