finish hero1 and add hero2 to main.tsx

This commit is contained in:
2025-10-25 19:42:17 +08:00
parent b09f08849f
commit 4456427e78
7 changed files with 254 additions and 86 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

View File

@@ -3,12 +3,15 @@ import { useState, useEffect, CSSProperties } from 'react'
interface CyclingImageProps { interface CyclingImageProps {
src: string src: string
src2?: string // Optional second image to alternate with
position?: CSSProperties['position'] position?: CSSProperties['position']
w?: any w?: any
maxW?: any
left?: any left?: any
top?: any top?: any
right?: any right?: any
bottom?: any bottom?: any
display?: any
cycleDuration?: number // Duration of one complete cycle in seconds cycleDuration?: number // Duration of one complete cycle in seconds
intensity?: number // How dark/light it gets (0-1, where 1 is maximum) intensity?: number // How dark/light it gets (0-1, where 1 is maximum)
timingFunction?: string // CSS timing function timingFunction?: string // CSS timing function
@@ -19,12 +22,15 @@ interface CyclingImageProps {
const CyclingImage = ({ const CyclingImage = ({
src, src,
src2,
position = 'relative', position = 'relative',
w, w,
maxW,
left, left,
top, top,
right, right,
bottom, bottom,
display,
cycleDuration = 3, cycleDuration = 3,
intensity = 0.5, intensity = 0.5,
timingFunction = 'ease-in-out', timingFunction = 'ease-in-out',
@@ -35,11 +41,23 @@ const CyclingImage = ({
const [isPlaying, setIsPlaying] = useState(autoStart) const [isPlaying, setIsPlaying] = useState(autoStart)
const [speed, setSpeed] = useState(cycleDuration) const [speed, setSpeed] = useState(cycleDuration)
const [currentIntensity, setCurrentIntensity] = useState(intensity) const [currentIntensity, setCurrentIntensity] = useState(intensity)
const [currentImage, setCurrentImage] = useState(src)
useEffect(() => { useEffect(() => {
setSpeed(cycleDuration) setSpeed(cycleDuration)
}, [cycleDuration]) }, [cycleDuration])
// Handle image alternation if src2 is provided
useEffect(() => {
if (!src2 || !isPlaying) return
const interval = setInterval(() => {
setCurrentImage(prev => prev === src ? src2 : src)
}, speed * 1000)
return () => clearInterval(interval)
}, [src, src2, speed, isPlaying])
const togglePlayPause = () => { const togglePlayPause = () => {
setIsPlaying(!isPlaying) setIsPlaying(!isPlaying)
} }
@@ -57,13 +75,13 @@ const CyclingImage = ({
const animationStyle = ` const animationStyle = `
@keyframes ${animationName} { @keyframes ${animationName} {
0% { 0% {
filter: brightness(${1 + currentIntensity}); filter: brightness(${1 - currentIntensity * 1.5});
} }
50% { 50% {
filter: brightness(${1 - currentIntensity}); filter: brightness(1);
} }
100% { 100% {
filter: brightness(${1 + currentIntensity}) ; filter: brightness(${1 - currentIntensity * 1.5});
} }
} }
` `
@@ -72,16 +90,18 @@ const CyclingImage = ({
<> <>
<style>{animationStyle}</style> <style>{animationStyle}</style>
<Image <Image
src={src} src={currentImage}
position={position} position={position}
w={w} w={w}
maxW={maxW}
left={left} left={left}
top={top} top={top}
right={right} right={right}
bottom={bottom} bottom={bottom}
display={display}
style={{ style={{
...style, ...style,
animation: isPlaying ? `${animationName} ${speed}s ${timingFunction} infinite` : 'none', animation: isPlaying && !src2 ? `${animationName} ${speed}s ${timingFunction} infinite` : 'none',
willChange: 'filter', willChange: 'filter',
transition: 'filter 0.3s ease' transition: 'filter 0.3s ease'
}} }}

View File

@@ -1,9 +1,9 @@
import { Box, Image, Stack, } from '@chakra-ui/react' import { Box, Image, Stack } from '@chakra-ui/react'
import CyclingImage from './CyclingImage' import CyclingImage from './CyclingImage'
function Hero1() { function Hero1() {
const bigWarningSize = { base: "80px", sm: "100px", md: "120px", lg: "9vw", xl: "8vw" }; const bigWarningSize = { base: "17vw", sm: "15vw", md: "9vw", lg: "9vw", xl: "8vw" };
const smallWarningSize = { base: "40px", sm: "50px", md: "60px", lg: "6vw", xl: "5vw" };
return ( return (
<Box <Box
position="relative" position="relative"
@@ -12,100 +12,248 @@ function Hero1() {
justifyContent={"center"} justifyContent={"center"}
> >
{/* Global keyframes for all animations */}
<style>
{`
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes floatSlow {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-15px);
}
}
@keyframes floatMedium {
0%, 100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-12px) rotate(3deg);
}
}
@keyframes floatFast {
0%, 100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-8px) rotate(-3deg);
}
}
`}
</style>
<Stack gap={0}> <Stack gap={0}>
<Box <Box
position="relative" position="relative"
w="100%" w="100%"
minH={{ base: "100vh", sm: "100vh", md: "100vh", lg: "70vw", xl: "45vw" }} minH={{ base: "110vw", sm: "110vw", md: "70vw", lg: "70vw", xl: "45vw" }}
bgImage={"url('/images/new/confuse.webp')"} bgImage={{base:"url('/images/new/confuse_mobile.webp')",sm:"url('/images/new/confuse_mobile.webp')",md:"url('/images/new/confuse.webp')",lg:"url('/images/new/confuse.webp')",xl:"url('/images/new/confuse.webp')"}}
bgSize="cover" bgSize="cover"
backgroundPosition="center" backgroundPosition="center"
justifyItems={'center'} justifyItems={'center'}
bgRepeat="no-repeat" bgRepeat="no-repeat"
> >
{/* Hero 1 title */}
<Image src="/images/new/hero_text1x.webp" <Image src="/images/new/hero_text1x.webp"
position={'absolute'} position={'absolute'}
bottom={'100px'} bottom={{ base: '70px', sm: '100px', md: '100px', lg: '100px', xl: '100px' }}
maxW={{ base: "90%", sm: "80%", md: "60%", lg: "50vw", xl: "35vw" }} maxW={{ base: "70vw", sm: "70vw", md: "50vw", lg: "50vw", xl: "35vw" }}
alt='hero title'
css={{
animation: 'fadeInUp 1s ease-out',
'@keyframes fadeInUp': {
from: {
opacity: 0,
transform: 'translateY(30px)'
},
to: {
opacity: 1,
transform: 'translateY(0)'
}
}
}}
/> />
<Image src="/images/new/arrow_pc_1.webp" {/* Mobile arrow - shown on base and sm */}
<CyclingImage
src="/images/new/arrow_mobile_1.webp"
src2="/images/new/arrow_mobile_2.webp"
position={'absolute'} position={'absolute'}
maxW={{ base: "40px", sm: "50px", md: "60px", lg: "70%", xl: "70%" }} maxW={{ base: "70%", sm: "70%", md: "70%", lg: "70%", xl: "70%" }}
bottom={'10px'} /> bottom={'10px'}
display={{ base: "block", sm: "block", md: "none", lg: "none", xl: "none" }}
cycleDuration={0.3}
intensity={0}
/>
{/* Desktop arrow - shown on md, lg, xl */}
<CyclingImage
src="/images/new/arrow_pc_1.webp"
src2="/images/new/arrow_pc_2.webp"
position={'absolute'}
maxW={{ base: "70%", sm: "70%", md: "70%", lg: "70%", xl: "70%" }}
bottom={'10px'}
display={{ base: "none", sm: "none", md: "block", lg: "block", xl: "block" }}
cycleDuration={0.3}
intensity={0}
/>
{/* signs */} {/* signs */}
<CyclingImage <Box
src="/images/new/bigwarning.webp"
position={'absolute'} position={'absolute'}
w={bigWarningSize} w={bigWarningSize}
left={'20vw'} left={{ base: '14vw', sm: '14vw', md: '20vw', lg: '20vw', xl: '20vw' }}
top={'5vw'} top={{ base: '14vw', sm: '14vw', md: '5vw', lg: '5vw', xl: '5vw' }}
cycleDuration={3} css={{
intensity={0.1} animation: 'floatSlow 3s ease-in-out infinite',
/> animationDelay: '0s'
<CyclingImage }}
src="/images/new/bigwarning.webp" >
<CyclingImage
src="/images/new/bigwarning.webp"
position={'relative'}
w="100%"
cycleDuration={3}
intensity={0.1}
/>
</Box>
<Box
position={'absolute'} position={'absolute'}
w={smallWarningSize} w={{ base: "13vw", sm: "13vw", md: "6vw", lg: "6vw", xl: "5vw" }}
left={'25vw'} left={{ base: '6vw', sm: '6vw', md: '13vw', lg: '13vw', xl: '25vw' }}
bottom={'18vw'} bottom={{ base: '50vw', sm: '50vw', md: '27vw', lg: '27vw', xl: '18vw' }}
cycleDuration={3} css={{
intensity={0.1} animation: 'floatMedium 3.5s ease-in-out infinite',
/> animationDelay: '0.5s'
<CyclingImage }}
src="/images/new/bigwarning.webp" >
<CyclingImage
src="/images/new/bigwarning.webp"
position={'relative'}
w="100%"
cycleDuration={3}
intensity={0.1}
/>
</Box>
<Box
position={'absolute'}
w={{ base: "13vw", sm: "13vw", md: "6vw", lg: "6vw", xl: "5vw" }}
right={{ base: '7vw', sm: '7vw', md: '14vw', lg: '14vw', xl: '20vw' }}
top={{ base: '60vw', sm: '60vw', md: '40vw', lg: '40vw', xl: '25vw' }}
css={{
animation: 'floatFast 3.2s ease-in-out infinite',
animationDelay: '1s'
}}
>
<CyclingImage
src="/images/new/bigwarning.webp"
position={'relative'}
w="100%"
cycleDuration={3}
intensity={0.1}
/>
</Box>
<Box
position={'absolute'} position={'absolute'}
w={bigWarningSize} w={bigWarningSize}
right={'20vw'} right={{ base: '11vw', sm: '11vw', md: '18vw', lg: '18vw', xl: '18vw' }}
top={'25vw'} top={{ base: '12vw', sm: '12vw', md: '20vw', lg: '20vw', xl: '10vw' }}
cycleDuration={3} css={{
intensity={0.1} animation: 'floatSlow 3.3s ease-in-out infinite',
/> animationDelay: '1.5s'
<CyclingImage }}
src="/images/new/bigwarning.webp" >
position={'absolute'} <CyclingImage
w={bigWarningSize} src="/images/new/bigwarning.webp"
right={'18vw'} position={'relative'}
top={'10vw'} w="100%"
cycleDuration={3} cycleDuration={3}
intensity={0.1} intensity={0.1}
/> />
</Box>
{/* Warning Texts */} {/* Warning Texts */}
<CyclingImage <Box
src="/images/new/threehightext.webp"
position={'absolute'} position={'absolute'}
w={{ base: "100px", sm: "120px", md: "150px", lg: "11vw", xl: "10vw" }} w={{ base: "20vw", sm: "20vw", md: "11vw", lg: "11vw", xl: "10vw" }}
left={{ base: "20px", sm: "30px", md: "40px", lg: "30vw", xl: "37vw" }} left={{ base: "23vw", sm: "23vw", md: "30vw", lg: "30vw", xl: "37vw" }}
top={{ base: "3vw", sm: "3vw", md: "3vw", lg: "7vw", xl: "3vw" }} top={{ base: "9vw", sm: "9vw", md: "7vw", lg: "7vw", xl: "3vw" }}
cycleDuration={3} css={{
intensity={0.1} animation: 'floatMedium 3.2s ease-in-out infinite',
/> animationDelay: '0.2s'
<CyclingImage }}
src="/images/new/fattext.webp" >
<CyclingImage
src="/images/new/threehightext.webp"
position={'relative'}
w="100%"
cycleDuration={3}
intensity={0.1}
/>
</Box>
<Box
position={'absolute'} position={'absolute'}
w={{ base: "100px", sm: "120px", md: "150px", lg: "10vw", xl: "9vw" }} w={{ base: "20vw", sm: "20vw", md: "10vw", lg: "10vw", xl: "9vw" }}
left={{ base: "25vw", sm: "25vw", md: "25vw", lg: "18vw", xl: "25vw" }} left={{ base: "35vw", sm: "35vw", md: "18vw", lg: "18vw", xl: "25vw" }}
top={{ base: "14vw", sm: "14vw", md: "14vw", lg: "20vw", xl: "14vw" }} top={{ base: "25vw", sm: "25vw", md: "20vw", lg: "20vw", xl: "14vw" }}
cycleDuration={3} css={{
intensity={0.1} animation: 'floatFast 3.5s ease-in-out infinite',
/> animationDelay: '0.7s'
<CyclingImage }}
src="/images/new/centerfattext.webp" >
<CyclingImage
src="/images/new/fattext.webp"
position={'relative'}
w="100%"
cycleDuration={3}
intensity={0.1}
/>
</Box>
<Box
position={'absolute'} position={'absolute'}
w={{ base: "100px", sm: "120px", md: "150px", lg: "14vw", xl: "13vw" }} w={{ base: "29vw", sm: "29vw", md: "14vw", lg: "14vw", xl: "13vw" }}
right={{ base: "35vw", sm: "35vw", md: "35vw", lg: "34vw", xl: "35vw" }} right={{ base: "20vw", sm: "20vw", md: "34vw", lg: "34vw", xl: "35vw" }}
top={{ base: "5vw", sm: "5vw", md: "5vw", lg: "7vw", xl: "5vw" }} top={{ base: "10vw", sm: "10vw", md: "7vw", lg: "7vw", xl: "5vw" }}
cycleDuration={3} css={{
intensity={0.1} animation: 'floatSlow 3.8s ease-in-out infinite',
/> animationDelay: '0.4s'
<CyclingImage }}
src="/images/new/hairlosstext.webp" >
<CyclingImage
src="/images/new/centerfattext.webp"
position={'relative'}
w="100%"
cycleDuration={3}
intensity={0.1}
/>
</Box>
<Box
position={'absolute'} position={'absolute'}
w={{ base: "100px", sm: "120px", md: "150px", lg: "8vw", xl: "7vw" }} w={{ base: "13vw", sm: "13vw", md: "8vw", lg: "8vw", xl: "7vw" }}
right={{ base: "26vw", sm: "26vw", md: "26vw", lg: "26vw", xl: "26vw" }} right={{ base: "14vw", sm: "14vw", md: "26vw", lg: "26vw", xl: "26vw" }}
top={{ base: "12vw", sm: "12vw", md: "12vw", lg: "18vw", xl: "12vw" }} top={{ base: "35vw", sm: "35vw", md: "18vw", lg: "18vw", xl: "12vw" }}
cycleDuration={3} css={{
intensity={0.1} animation: 'floatFast 3.3s ease-in-out infinite',
/> animationDelay: '0.9s'
}}
>
<CyclingImage
src="/images/new/hairlosstext.webp"
position={'relative'}
w="100%"
cycleDuration={3}
intensity={0.1}
/>
</Box>
</Box> </Box>
</Stack> </Stack>
</Box> </Box>

View File

@@ -11,7 +11,7 @@ function Hero2() {
<Box <Box
position="relative" position="relative"
w="100%" w="100%"
minH={{ base: "100vh", sm: "100vh", md: "100vh", lg: "70vw", xl: "70vw" }} minH={{ base: "115vw", sm: "105vw", md: "90vw", lg: "73vw", xl: "65vw" }}
bgImage={"url('/images/new/hero2bg.webp')"} bgImage={"url('/images/new/hero2bg.webp')"}
bgSize="cover" bgSize="cover"
backgroundPosition="center" backgroundPosition="center"
@@ -22,24 +22,24 @@ function Hero2() {
<Image src="/images/new/hero2title.webp" <Image src="/images/new/hero2title.webp"
position={'absolute'} position={'absolute'}
top={"50px"} top={{ base: "10px", sm: "50px", md: "50px", lg: "50px", xl: "50px" }}
w={{ base: "80%", sm: "70%", md: "60%", lg: "50vw", xl: "40vw" }} w={{ base: "70vw", sm: "60vw", md: "50vw", lg: "35vw", xl: "35vw" }}
/> />
<Image src="/images/new/hero2subtitle.webp" <Image src="/images/new/hero2subtitle.webp"
position={'absolute'} position={'absolute'}
zIndex={1} zIndex={1}
top={"18vw"} top={{ base: "30vw", sm: "35vw", md: "24vw", lg: "20vw", xl: "18vw" }}
right={{ base: "10px", sm: "10px", md: "10px", lg: "3vw", xl: "27vw" }} right={{ base: "15vw", sm: "15vw", md: "20vw", lg: "28vw", xl: "30vw" }}
w={{ base: "80%", sm: "70%", md: "60%", lg: "50vw", xl: "20vw" }} w={{ base: "30vw", sm: "30vw", md: "25vw", lg: "18vw", xl: "18vw" }}
/> />
<Image src="/images/new/oil.webp" <Image src="/images/new/oil.webp"
zIndex={0} zIndex={0}
position={'absolute'} position={'absolute'}
bottom={-20} bottom={{ base: -10, sm: -20, md: -20, lg: -20, xl: -20 }}
w={{ base: "80%", sm: "70%", md: "60%", lg: "50vw", xl: "44vw" }} w={{ base: "80vw", sm: "70vw", md: "60vw", lg: "50vw", xl: "40vw" }}
/> />