Skip to content

Commit

Permalink
feat: Add transition animation to the home page. (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
shamimbinnur authored May 17, 2023
1 parent ba304f8 commit 9524fa0
Show file tree
Hide file tree
Showing 10 changed files with 210 additions and 44 deletions.
8 changes: 6 additions & 2 deletions components/common/ContainerWithLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ const ContainerWithLine: React.FC = ({ children }) => {
return (
<div className="flex w-full">
<div className="relative w-[1.5px] mx-1 largeTablet:mx-6">
<div className="absolute inset-0 bg-[#F87216] blur-sm "></div>
<div className="bg-[#F87216] h-full relative"></div>
<div
className="absolute inset-0 bg-[#F87216] blur-sm ">
</div>
<div
className="bg-[#F87216] h-full relative">
</div>
</div>

<div className="w-full">
Expand Down
16 changes: 14 additions & 2 deletions components/common/EndingLine.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import React from 'react'

import { motion } from 'framer-motion'
import { useInView } from 'react-intersection-observer'

const EndingLine = () => {
const { ref, inView } = useInView()

return (
<div className="w-full flex px-1 largeTablet:px-6 mb-10">
<div className="relative flex-1 bg-gradient-to-b border-b-0 border-l-0 border-r-[#F87216] border-t-[#F87216] border h-[200px] w-full to-gray-800">
<img className="absolute -right-[28px] -top-[28px]" src="/icons/quote.svg" alt="Endling line" />
<div ref={ref} className="relative flex-1 bg-gradient-to-b border-b-0 border-l-0 border-r-[#F87216] border-t-[#F87216] border h-[200px] w-full to-gray-800">
<motion.img
initial={{ opacity: 0, scale: .2 }}
animate={{ opacity: inView ? 1 : 0, scale: inView ? 1 : 0.5 }}
transition={{ duration: 0.5, delay: 0.1, ease: 'easeInOut' }}
className="absolute -right-[28px] -top-[28px]"
src="/icons/quote.svg"
alt="Ending line"
/>
</div>
<div className="flex-1"></div>
</div>
Expand Down
1 change: 0 additions & 1 deletion components/sections/home-page/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Heading, Typography } from '../../common/text'
import { Button } from '../../common'
import DecoratedText from '../../common/text/utils/DecoratedText'
import Link from 'next/link'

interface HeroProps {
data: SanityHomePage['hero']
}
Expand Down
50 changes: 31 additions & 19 deletions components/sections/home-page/blogs/Blogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,46 @@ import { Button } from '../../../common'
import SectionWrapper from '../../../common/layout/SectionWrapper'
import { Heading, Typography } from '../../../common/text'
import Blog from './Blog'
import { useInView } from 'react-intersection-observer'

import { motion } from 'framer-motion'

interface BlogsProps {
blogs: SanityBlog[]
data: SanityHomePage['blogSection']
}

const Blogs: FC<BlogsProps> = ({ blogs, data }): ReactElement => {
return (
<SectionWrapper pb={320}>
<Typography variant="preHeading" alignSmall="center">
{data?.title}
</Typography>
const [ refCard, cardInView ] = useInView()

<Heading alignSmall="center">
{data?.heading}
</Heading>
<div className="w-full max-w-3xl mt-4 mb-14 largeTablet:mt-10 largeTablet:mb-24">
<Typography variant="subheading" alignSmall="center">
{data?.description}
return (
<motion.div
ref={refCard}
initial={{ opacity: 0, y: 100 }}
animate={{ opacity: cardInView ? 1 : 0 , y: cardInView ? 0 : 100 }}
transition={{ duration: 0.5, delay: 0.2, ease: 'easeInOut', type: 'spring', stiffness: 50}}
>
<SectionWrapper pb={320}>
<Typography variant="preHeading" alignSmall="center">
{data?.title}
</Typography>
</div>
<div className="w-full grid grid-cols-1 gap-10 mb-12 largeTablet:grid-cols-2 largeTablet:mb-24">
{blogs.map((item) => (
<Blog key={item._id} data={item} />
))}
</div>
<Button href="/blog">Load More</Button>
</SectionWrapper>

<Heading alignSmall="center">
{data?.heading}
</Heading>
<div className="w-full max-w-3xl mt-4 mb-14 largeTablet:mt-10 largeTablet:mb-24">
<Typography variant="subheading" alignSmall="center">
{data?.description}
</Typography>
</div>
<div className="w-full grid grid-cols-1 gap-10 mb-12 largeTablet:grid-cols-2 largeTablet:mb-24">
{blogs.map((item) => (
<Blog key={item._id} data={item} />
))}
</div>
<Button href="/blog">Load More</Button>
</SectionWrapper>
</motion.div>
)
}

Expand Down
69 changes: 53 additions & 16 deletions components/sections/home-page/features/Feature.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { FeatureProps } from './Features'
import { Heading, Typography } from '../../../common/text'
import ContainerWithLine from '../../../common/ContainerWithLine'

import { motion } from 'framer-motion'
import { useInView } from 'react-intersection-observer'

interface Props {
feature: FeatureProps
index: number
Expand All @@ -18,34 +21,68 @@ const Feature: FC<Props> = ({
}) => {
const hide = smallImage ? 'hidden' : ''

const [ refIcon, iconInView ] = useInView()
const [ refImage, imageInView ] = useInView()

// text animation
const initPosY = 5
const posY = iconInView ? 0 : initPosY

return (
<ContainerWithLine>
<div className="pb-14 largeTablet:mb-32">
<div className="flex gap-y-24 py-10 flex-col-reverse largeTablet:flex-col">
<div className=" flex flex-col px-6 gap-y-8">
<div ref={refIcon} className=" flex flex-col px-6 gap-y-8">
<div className="relative largeTablet:max-w-[500px]">
<img className="absolute -left-[56px] largeTablet:-left-[77px] -top-[8px] largeTablet:-top-[4px]" src={icon} alt="" />
<Heading component="h2" alignLarge="left">
{title}
</Heading>
<motion.img
initial={{ opacity: 0, scale: 0.2 }}
animate={{ opacity: iconInView ? 1 : 0, scale: iconInView ? 1 : 0.5 }}
transition={{ duration: 0.5, delay: 0.1, ease: 'easeInOut' }}
className="absolute -left-[56px] largeTablet:-left-[77px] -top-[8px] largeTablet:-top-[4px]"
src={icon}
alt="Find"
/>

<motion.div
initial={{ opacity: 0, y: initPosY, x: -10 }}
animate={{ opacity: iconInView ? 1 : 0, y: posY, x: iconInView ? 0 : -10 }}
transition={{ duration: 0.7, delay: 0.2, ease: 'easeInOut' }}
>
<Heading component="h2" alignLarge="left">
{title}
</Heading>
</motion.div>
</div>

<div className="largeTablet:max-w-[500px]">
<Typography variant="subheading" alignLarge="left">
{description}
</Typography>
<motion.div
initial={{ opacity: 0, y: initPosY, x: 10 }}
animate={{ opacity: iconInView ? 1 : 0, y: posY, x: iconInView ? 0 : 10 }}
transition={{ duration: 0.7, delay: 0.2, ease: 'easeInOut' }}
>
<Typography variant="subheading" alignLarge="left">
{description}
</Typography>
</motion.div>
</div>
</div>

<div className={`relative largeTablet:flex justify-center largeTablet:min-h-[350px] ${hide}`}>
<img className={`relative ${className.lg}`} src={image} alt="Feature"/>
</div>
<motion.div
ref={refImage}
initial={{ opacity: 0, x: -10}}
animate={{ opacity: imageInView ? 1 : 0, x: imageInView ? 0 : -10 }}
transition={{ duration: 0.5, delay: 0.2, ease: 'easeInOut' }}
>
<div className={`relative largeTablet:flex justify-center largeTablet:min-h-[350px] ${hide}`}>
<img className={`relative ${className.lg}`} src={image} alt="Feature"/>
</div>

{ smallImage && (
<div className="relative flex largeTablet:hidden justify-center largeTablet:min-h-[350px]">
<img className={`relative ${className.sm}`} src={smallImage} alt="Feature"/>
</div>)
}
{ smallImage && (
<div className="relative flex largeTablet:hidden justify-center largeTablet:min-h-[350px]">
<img className={`relative ${className.sm}`} src={smallImage} alt="Feature"/>
</div>)
}
</motion.div>
</div>
</div>
</ContainerWithLine>
Expand Down
14 changes: 12 additions & 2 deletions components/sections/home-page/testimonials/Testimonial.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import React, { FC } from 'react'
import { SanityTestimonial } from '../../../../types/schema'
import GradientBorderWrapper from '../../../common/GradientBorderWrapper'

import { motion } from 'framer-motion'
import { useInView } from 'react-intersection-observer'

interface TestimonialProps {
testimonial: SanityTestimonial
}
Expand All @@ -16,8 +19,15 @@ const Testimonial: FC<TestimonialProps> = ({
tweetLink,
},
}) => {
const [ refCard, cardInView ] = useInView()

return (
<div>
<motion.div
ref={refCard}
initial={{ opacity: 0, y: cardInView ? 100 : 0 }}
animate={{ opacity: cardInView ? 1 : 0 , y: cardInView ? 0 : 100 }}
transition={{ duration: 0.5, delay: 0.2, ease: 'easeInOut', type: 'spring', stiffness: 50}}
>
<GradientBorderWrapper style={{ borderRadius: '8px', width: '100%' }}>
<div className="h-fit min-h-[320px] w-full p-10 bg-[#211E1C] rounded-lg flex flex-col largeTablet:min-h-[300px]">
<div className="flex-grow">
Expand Down Expand Up @@ -56,7 +66,7 @@ const Testimonial: FC<TestimonialProps> = ({
</div>
</div>
</GradientBorderWrapper>
</div>
</motion.div>
)
}

Expand Down
2 changes: 1 addition & 1 deletion components/sections/navigation/DesktopNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const DesktopNavigation: FC<DesktopNavigationProps> = ({
<div className="items-center w-full justify-between hidden largeTablet:flex">
<div className="h-[26px] w-[150px] cursor-pointer">
<Link href="/" passHref>
<Image src={logo} layout="responsive" alt="Logo image" />
<Image src={logo} alt="Open Sauced" />
</Link>
</div>

Expand Down
2 changes: 1 addition & 1 deletion components/sections/navigation/MobileNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const MobileNavigation: FC<MobileNavigationProps> = ({
<div className="flex justify-between items-center w-full">
<div className="h-[26px] w-[150px] largeTablet:hidden cursor-pointer">
<Link href="/" passHref>
<Image src={logo} layout="responsive" alt="" />
<Image src={logo} alt="Open Sauced" />
</Link>
</div>

Expand Down
Loading

0 comments on commit 9524fa0

Please sign in to comment.