truth component added animation

This commit is contained in:
2025-11-02 16:28:57 +08:00
parent 5d7814f983
commit b190bf3357

View File

@@ -1,7 +1,13 @@
import { Box, HStack, Image, Stack, Text, Link, Flex } from '@chakra-ui/react' import { Box, HStack, Image, Stack, Text, Link, Flex } from '@chakra-ui/react'
import { motion, useInView } from 'framer-motion' import { motion, useInView } from 'framer-motion'
import { colors } from '../../colors';
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
const MotionBox = motion.create(Box)
const MotionStack = motion.create(Stack)
const MotionHStack = motion.create(HStack)
const MotionText = motion.create(Text)
const MotionImage = motion.create(Image)
const MotionFlex = motion.create(Flex)
const truthItems = [ const truthItems = [
{ {
@@ -59,7 +65,9 @@ function Truth() {
] ]
const fbContainerRef = useRef<HTMLDivElement>(null); const fbContainerRef = useRef<HTMLDivElement>(null);
const mainRef = useRef<HTMLDivElement>(null);
const titleRef = useRef<HTMLDivElement>(null); const titleRef = useRef<HTMLDivElement>(null);
const isMainInView = useInView(mainRef, { once: true });
const isTitleInView = useInView(titleRef, { once: true }); const isTitleInView = useInView(titleRef, { once: true });
@@ -99,25 +107,33 @@ function Truth() {
return ( return (
<Box <MotionBox
ref={mainRef}
position="relative" position="relative"
w="100%" w="100%"
bgColor="white" bgColor="white"
zIndex={3} zIndex={3}
overflow="hidden" overflow="hidden"
justifyItems={'center'} justifyItems={'center'}
initial={{ opacity: 0 }}
animate={isMainInView ? { opacity: 1 } : { opacity: 0 }}
transition={{ duration: 0.8, ease: "easeOut" }}
> >
<Text <MotionText
className='font-melle font-xbold' className='font-melle font-xbold'
color='#458B02' color='#458B02'
mt={{ base: 10, sm: 10, md: 10, lg: 10, xl: 10 }} mt={{ base: 10, sm: 10, md: 10, lg: 10, xl: 10 }}
fontSize={{ base: '2xl', sm: '3xl', md: '5xl', lg: '5xl', xl: '5xl' }} fontSize={{ base: '2xl', sm: '3xl', md: '5xl', lg: '5xl', xl: '5xl' }}
textAlign={'center'}> textAlign={'center'}
initial={{ opacity: 0, y: -30 }}
animate={isMainInView ? { opacity: 1, y: 0 } : { opacity: 0, y: -30 }}
transition={{ duration: 0.6, delay: 0.2, ease: "easeOut" }}
>
</Text> </MotionText>
<Stack <MotionStack
mt={{ base: 3, sm: -5, md: -5, lg: -5, xl: -5 }} mt={{ base: 3, sm: -5, md: -5, lg: -5, xl: -5 }}
columns={{ base: 1, sm: 1, md: 2 }} columns={{ base: 1, sm: 1, md: 2 }}
p={{ base: 5, sm: 12, md: 20 }} p={{ base: 5, sm: 12, md: 20 }}
@@ -126,98 +142,132 @@ function Truth() {
gap={{ base: 7, md: 7 }} gap={{ base: 7, md: 7 }}
justifyItems={'center'} justifyItems={'center'}
alignItems={'flex-start'} alignItems={'flex-start'}
initial={{ opacity: 0, y: 50 }}
animate={isMainInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }}
transition={{ duration: 0.8, delay: 0.4, ease: "easeOut" }}
> >
{truthItems.map((item) => ( {truthItems.map((item, index) => (
<HStack <MotionHStack
key={item.id}
gap={{ base: 4, md: 5 }} gap={{ base: 4, md: 5 }}
justifyItems={'flex-start'} justifyItems={'flex-start'}
alignItems={'flex-start'}> alignItems={'flex-start'}
<Image initial={{ opacity: 0, x: -30 }}
animate={isMainInView ? { opacity: 1, x: 0 } : { opacity: 0, x: -30 }}
transition={{ duration: 0.5, delay: 0.6 + index * 0.1, ease: "easeOut" }}
>
<MotionImage
src={item.image} src={item.image}
alt={`truth item ${item.id}`} alt={`truth item ${item.id}`}
w={{ base: '70px', sm: '70px', md: '70px', lg: '70px', xl: '70px' }} w={{ base: '70px', sm: '70px', md: '70px', lg: '70px', xl: '70px' }}
initial={{ opacity: 0, scale: 0.8 }}
animate={isMainInView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.8 }}
transition={{ duration: 0.4, delay: 0.8 + index * 0.1, ease: "easeOut" }}
/> />
<Text <MotionText
className="font-noto-sans font-regular" className="font-noto-sans font-regular"
color='#458B02' color='#458B02'
fontSize={{ base: 'lg', sm: 'lg', md: 'lg', lg: 'lg', xl: 'lg' }} fontSize={{ base: 'lg', sm: 'lg', md: 'lg', lg: 'lg', xl: 'lg' }}
initial={{ opacity: 0, y: 20 }}
animate={isMainInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
transition={{ duration: 0.5, delay: 1.0 + index * 0.1, ease: "easeOut" }}
> >
{renderDescription(item.desc)} {renderDescription(item.desc)}
</Text> </MotionText>
</HStack> </MotionHStack>
))} ))}
</Stack> </MotionStack>
<motion.div <motion.div
ref={titleRef} ref={titleRef}
initial={{ opacity: 0, y: 50 }} initial={{ opacity: 0, y: 50 }}
animate={isTitleInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }} animate={isTitleInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }}
transition={{ duration: 0.7 }} transition={{ duration: 0.7 }}
> >
<Stack <MotionStack
w='100%' w='100%'
justify={'center'} justify={'center'}
align={'center'} align={'center'}
initial={{ opacity: 0, scale: 0.9 }}
animate={isTitleInView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.9 }}
transition={{ duration: 0.5, delay: 0.3, ease: "easeOut" }}
> >
<Text <MotionText
className='font-melle font-xbold' className='font-melle font-xbold'
color={"#458B02"} color={"#458B02"}
fontSize={{ base: '2xl', sm: '3xl', md: '5xl', lg: '5xl', xl: '5xl' }} fontSize={{ base: '2xl', sm: '3xl', md: '5xl', lg: '5xl', xl: '5xl' }}
initial={{ opacity: 0 }}
animate={isTitleInView ? { opacity: 1 } : { opacity: 0 }}
transition={{ duration: 0.6, delay: 0.6, ease: "easeOut" }}
> >
</Text> </MotionText>
</Stack> </MotionStack>
</motion.div> </motion.div>
<Flex <MotionFlex
gap={12} gap={12}
direction={{ base: 'column', sm: 'column', md: 'row' }} direction={{ base: 'column', sm: 'column', md: 'row' }}
justify="center" justify="center"
mt={5} mt={5}
align={'flex-end'} align={'flex-end'}
initial={{ opacity: 0, y: 30 }}
animate={isTitleInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
transition={{ duration: 0.8, delay: 0.4, ease: "easeOut" }}
> >
{shopImages.map((image, index) => ( {shopImages.map((image, index) => (
<motion.div <motion.div
key={index} key={index}
initial={{ opacity: 0, y: 30 }} initial={{ opacity: 0, scale: 0.8 }}
whileInView={{ opacity: 1, y: 0 }} animate={isTitleInView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.8 }}
viewport={{ once: true }} transition={{ duration: 0.5, delay: 0.8 + index * 0.2, ease: "easeOut" }}
transition={{ duration: 0.5, delay: index * 0.2 }}
> >
<Stack <MotionStack
w='250px' w='250px'
justify={'flex-end'} justify={'flex-end'}
initial={{ opacity: 0, y: 20 }}
animate={isTitleInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
transition={{ duration: 0.4, delay: 1.0 + index * 0.2, ease: "easeOut" }}
> >
<Link href={image.link}> <Link href={image.link}>
<Image src={image.image} cursor="pointer" fit={'contain'} <MotionImage src={image.image} cursor="pointer" fit={'contain'}
loading="lazy" /> loading="lazy"
initial={{ opacity: 0, scale: 0.9 }}
animate={isTitleInView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.9 }}
transition={{ duration: 0.3, delay: 1.2 + index * 0.2, ease: "easeOut" }}
/>
</Link> </Link>
</Stack> </MotionStack>
</motion.div> </motion.div>
))} ))}
</Flex> </MotionFlex>
<Stack <MotionStack
my={15} my={15}
ml={2} ml={2}
mt={10} mt={10}
initial={{ opacity: 0, scale: 0.9 }}
animate={isTitleInView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.9 }}
transition={{ duration: 0.6, delay: 1.6, ease: "easeOut" }}
> >
<Link href={"https://www.facebook.com/profile.php?id=100064320806613"} <Link href={"https://www.facebook.com/profile.php?id=100064320806613"}
_focus={{ outline: 'none', boxShadow: 'none' }} _focus={{ outline: 'none', boxShadow: 'none' }}
_active={{ outline: 'none', boxShadow: 'none' }}> _active={{ outline: 'none', boxShadow: 'none' }}>
<Image <MotionImage
src={'/images/facebook.webp'} src={'/images/facebook.webp'}
alt="salespoint" alt="salespoint"
w={"400px"} w={"400px"}
loading='lazy' loading='lazy'
initial={{ opacity: 0, y: 20 }}
animate={isTitleInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
transition={{ duration: 0.5, delay: 1.8, ease: "easeOut" }}
/> />
</Link> </Link>
</Stack> </MotionStack>
</Box> </MotionBox>
) )