update info and oilinfo, added animation to the "click to see recipe" section, and added alt and title attributes to images for better SEO and accessibility

This commit is contained in:
2026-05-01 16:57:43 +08:00
parent c13cc437ae
commit efa37da996
2 changed files with 44 additions and 9 deletions

View File

@@ -5,6 +5,7 @@ import { motion } from 'framer-motion'
const MotionImage = motion.create(Image) const MotionImage = motion.create(Image)
const MotionFlex = motion.create(Flex) const MotionFlex = motion.create(Flex)
const MotionBox = motion.create(Box) const MotionBox = motion.create(Box)
const MotionDiv = motion.div
interface InfoData { interface InfoData {
id: number id: number
@@ -101,12 +102,20 @@ function Info() {
transition={{ duration: 0.8, delay: 0.2, ease: "easeOut" }} transition={{ duration: 0.8, delay: 0.2, ease: "easeOut" }}
> >
{infoData.map((info) => ( {infoData.map((info) => (
<Box <MotionDiv
key={info.id} key={info.id}
whileHover={{ scale: 1.07 }}
whileTap={{ scale: 0.95 }}
animate={selectedInfo !== info.id ? { opacity: [1, 0.45, 1] } : { opacity: 1 }}
transition={selectedInfo !== info.id ? {
opacity: { duration: 1.6, repeat: Infinity, ease: "easeInOut", delay: info.id * 0.2 }
} : { type: "spring", stiffness: 300, damping: 20 }}
style={{ cursor: 'pointer' }}
onClick={() => setSelectedInfo(info.id)}
>
<Box
w={{ base: '20vw', sm: '110px', md: '150px', lg: '150px', xl: '150px' }} w={{ base: '20vw', sm: '110px', md: '150px', lg: '150px', xl: '150px' }}
h={{ base: '15vw', sm: '70px', md: '90px', lg: '90px', xl: '90px' }} h={{ base: '15vw', sm: '70px', md: '90px', lg: '90px', xl: '90px' }}
cursor="pointer"
onClick={() => setSelectedInfo(info.id)}
bg={selectedInfo === info.id ? '#3D6741' : '#BCBCBC'} bg={selectedInfo === info.id ? '#3D6741' : '#BCBCBC'}
border={selectedInfo === info.id ? { base: "1px solid #99BF35", sm: "1px solid #99BF35", md: "4px solid #99BF35", lg: "4px solid #99BF35", xl: "4px solid #99BF35" } : "none"} border={selectedInfo === info.id ? { base: "1px solid #99BF35", sm: "1px solid #99BF35", md: "4px solid #99BF35", lg: "4px solid #99BF35", xl: "4px solid #99BF35" } : "none"}
borderRadius={{ base: '15px', sm: '15px', md: '18px', lg: '20px', xl: '20px' }} borderRadius={{ base: '15px', sm: '15px', md: '18px', lg: '20px', xl: '20px' }}
@@ -126,6 +135,7 @@ function Info() {
> >
{info.title} {info.title}
</Box> </Box>
</MotionDiv>
))} ))}
</MotionFlex> </MotionFlex>

View File

@@ -1,11 +1,13 @@
import { Box, Image, SimpleGrid } from '@chakra-ui/react' import { Box, Image, SimpleGrid, Text } from '@chakra-ui/react'
import { motion, useInView } from 'framer-motion' import { motion, useInView } from 'framer-motion'
import { useRef } from 'react' import { useRef } from 'react'
import {useRouterState } from '@tanstack/react-router' import { useRouterState } from '@tanstack/react-router'
const MotionImage = motion.create(Image) const MotionImage = motion.create(Image)
const MotionBox = motion.create(Box) const MotionBox = motion.create(Box)
const MotionText = motion.create(Text)
const MotionSimpleGrid = motion.create(SimpleGrid) const MotionSimpleGrid = motion.create(SimpleGrid)
const MotionDiv = motion.div
function OilInfo() { function OilInfo() {
const mainRef = useRef(null); const mainRef = useRef(null);
@@ -14,12 +16,12 @@ function OilInfo() {
const handleRecipeNavigation = () => { const handleRecipeNavigation = () => {
const isOnRecipePage = location.pathname === '/40plus/recipe'; const isOnRecipePage = location.pathname === '/40plus/recipe';
if (isOnRecipePage) { if (isOnRecipePage) {
// Already on recipe page // Already on recipe page
return; return;
} }
// Navigate from main page - force reload to ensure Instagram embeds work // Navigate from main page - force reload to ensure Instagram embeds work
window.location.href = '/40plus/recipe'; window.location.href = '/40plus/recipe';
}; };
@@ -75,21 +77,44 @@ function OilInfo() {
<MotionBox <MotionBox
display="flex" display="flex"
flexDirection="column"
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"
gap={3}
initial={{ opacity: 0, x: 50 }} initial={{ opacity: 0, x: 50 }}
animate={isMainInView ? { opacity: 1, x: 0 } : { opacity: 0, x: 50 }} animate={isMainInView ? { opacity: 1, x: 0 } : { opacity: 0, x: 50 }}
transition={{ duration: 0.6, delay: 0.8, ease: "easeOut" }} transition={{ duration: 0.6, delay: 0.8, ease: "easeOut" }}
cursor="pointer"
onClick={handleRecipeNavigation}
whileHover={{ scale: 1.04 }}
whileTap={{ scale: 0.97 }}
> >
<MotionDiv
animate={{ y: [0, 6, 0] }}
transition={{ duration: 1.4, repeat: Infinity, ease: "easeInOut", delay: 1.3 }}
style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}
>
<MotionText
fontSize={{ base: 'sm', md: 'md' }}
color="#5a8c3a"
fontWeight={700}
fontFamily="'MElleHK', sans-serif"
letterSpacing="0.05em"
userSelect="none"
>
</MotionText>
<Text fontSize="xl" color="#5a8c3a" lineHeight="1" userSelect="none"></Text>
</MotionDiv>
<MotionImage <MotionImage
src='/images/new/buttons.webp' src='/images/new/buttons.webp'
w={{ base: '100%', sm: '100%', md: '90%' }} w={{ base: '100%', sm: '100%', md: '90%' }}
initial={{ opacity: 0, scale: 0.8 }} initial={{ opacity: 0, scale: 0.8 }}
animate={isMainInView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.8 }} animate={isMainInView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.8 }}
transition={{ duration: 0.5, delay: 1.0, ease: "easeOut" }} transition={{ duration: 0.5, delay: 1.0, ease: "easeOut" }}
cursor="pointer" pointerEvents="none"
onClick={handleRecipeNavigation}
/> />
</MotionBox> </MotionBox>