From 3c39db54d280f0cc3ba32adf442f265666f32e75 Mon Sep 17 00:00:00 2001 From: philipcheung Date: Sun, 2 Nov 2025 19:16:32 +0800 Subject: [PATCH] header scroll down hide --- src/components/header.tsx | 29 ++++++++++++++++++++++++-- src/components/new_ui/hero1.tsx | 36 ++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/components/header.tsx b/src/components/header.tsx index 0da0a6b..c44f994 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -2,7 +2,7 @@ import { Box, Flex, Image, VStack, Text, Link } from '@chakra-ui/react'; import { GiHamburgerMenu } from "react-icons/gi"; import { IoCloseSharp } from "react-icons/io5"; import { colors } from '../colors'; -import { useState, useRef, useLayoutEffect } from 'react'; +import { useState, useRef, useLayoutEffect, useEffect } from 'react'; import { DrawerBody, DrawerContent, @@ -16,7 +16,9 @@ interface HeaderProps { function Header({ showMenu = false }: HeaderProps) { const [isDrawerOpen, setIsDrawerOpen] = useState(false); const [headerHeight, setHeaderHeight] = useState(0); + const [isVisible, setIsVisible] = useState(true); const headerRef = useRef(null); + const lastScrollY = useRef(0); useLayoutEffect(() => { const updateHeight = () => { @@ -47,6 +49,26 @@ function Header({ showMenu = false }: HeaderProps) { }; }, []); + useEffect(() => { + const handleScroll = () => { + const currentScrollY = window.scrollY; + + if (currentScrollY > lastScrollY.current && currentScrollY > 100) { + setIsVisible(false); + } else { + setIsVisible(true); + } + + lastScrollY.current = currentScrollY; + }; + + window.addEventListener('scroll', handleScroll, { passive: true }); + + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + const menuItems = [ { label: '40+常見健康問題', href: '#info' }, { label: '營萃護心油四大優勢', href: '#advantages' }, @@ -61,9 +83,12 @@ function Header({ showMenu = false }: HeaderProps) { bg={colors.topBarColor} py={4} w="full" - position="sticky" + position="fixed" top={0} zIndex={1000} + transform={isVisible ? "translateY(0)" : "translateY(-100%)"} + transition="transform 0.3s ease-in-out" + data-header="true" > Logo diff --git a/src/components/new_ui/hero1.tsx b/src/components/new_ui/hero1.tsx index 21e406e..0327d2f 100644 --- a/src/components/new_ui/hero1.tsx +++ b/src/components/new_ui/hero1.tsx @@ -1,16 +1,50 @@ import { Box, Image, Stack } from '@chakra-ui/react' import CyclingImage from './CyclingImage' +import { useEffect, useState } from 'react' function Hero1() { + const [headerHeight, setHeaderHeight] = useState(80); const bigWarningSize = { base: "17vw", sm: "15vw", md: "9vw", lg: "9vw", xl: "8vw" }; + useEffect(() => { + const updateHeaderHeight = () => { + const header = document.querySelector('[data-header="true"]'); + if (header) { + const height = header.getBoundingClientRect().height; + setHeaderHeight(height); + } + }; + + const delayedUpdate = () => { + setTimeout(updateHeaderHeight, 100); + }; + + delayedUpdate(); + + const resizeObserver = new ResizeObserver(() => { + setTimeout(updateHeaderHeight, 50); + }); + + const header = document.querySelector('[data-header="true"]'); + if (header) { + resizeObserver.observe(header); + } + + window.addEventListener('resize', delayedUpdate); + + return () => { + window.removeEventListener('resize', delayedUpdate); + resizeObserver.disconnect(); + }; + }, []); + return ( {/* Global keyframes for all animations */}