framer-motion#useAnimation JavaScript Examples
The following examples show how to use
framer-motion#useAnimation.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: useAnimatedNavToggler.js From cucoders with Apache License 2.0 | 6 votes |
//Below logic is for toggling the navbar when toggleNavbar is called. It is used on mobile toggling of navbar.
export default function useAnimatedNavToggler() {
const [showNavLinks, setShowNavLinks] = useState(false);
const [x, cycleX] = useCycle("0%", "150%");
const animation = useAnimation();
const toggleNavbar = () => {
setShowNavLinks(!showNavLinks);
animation.start({ x: x, display: "block" });
cycleX();
};
return {showNavLinks,animation, toggleNavbar }
}
Example #2
Source File: IntroScreen.js From webappdevtest with MIT License | 6 votes |
export function IntroScreen(props) {
const {selectedCity} = props;
const controls = useAnimation();
const contentControls = useAnimation();
const close = {height: 0, transition: {ease: "easeInOut", duration: 1}}
useEffect(()=>{
contentControls.start({y: 0, opacity: 1, transition: {ease: 'easeInOut'}})
},[])
return (
<motion.div
className="introScreenContainer"
animate={controls}
>
<motion.div
className="introScreenContent"
initial = {{y: 10, opacity: 0}}
animate={contentControls}
>
<h1>Hey! Whats this?</h1>
<p> Looks like points on a map!
</p>
<motion.button
className="primary_btn"
whileHover={{scale: 1.02}}
whileTap={{scale:0.9}}
onClick = {()=> {
selectedCity ? PageView(selectedCity) : PageView('Homepage')
controls.start(close)
contentControls.start({opacity: 0, transition: {duration: 0.1}})
}}
>View the map
</motion.button>
</motion.div>
</motion.div>
)
}
Example #3
Source File: HomeContent.js From ar-episode2 with MIT License | 6 votes |
HomeContent = () => {
const animation = useAnimation()
const [contentRef, inView] = useInView({
triggerOnce: true,
rootMargin: "-300px",
})
useEffect(() => {
if (inView) {
animation.start("visible")
}
}, [animation, inView])
return (
<HomeContentSection
ref={contentRef}
animate={animation}
initial="hidden"
variants={{
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8, ease: [0.6, 0.05, -0.01, 0.9] },
},
hidden: { opacity: 0, y: 72 },
}}
>
<Container>
<Content>
Great stories don’t just happen— <br /> they need to be uncovered. And
we dig deep to discover the great stories that lie just below the
surface. Dirt under our fingernails and all.
</Content>
</Container>
</HomeContentSection>
)
}
Example #4
Source File: cookieBar.js From gatsby-starter-portfolio-minimal with MIT License | 6 votes |
CookieBar = () => {
const location = useLocation()
const controls = useAnimation()
const { isIntroDone } = useContext(Context).state
// Display cookie bar after the splashScreen sequence is done
useEffect(() => {
if (isIntroDone) {
controls.start({
opacity: 1,
y: 0,
transition: { delay: 1 },
})
}
}, [isIntroDone])
if (!isIntroDone) return null
return (
<StyledCookieBar initial={{ opacity: 0, y: 20 }} animate={controls}>
<CookieConsent
cookieName="gatsby-gdpr-google-analytics"
buttonId="confirm"
buttonText="Accept"
declineButtonId="decline"
declineButtonText="Decline"
enableDeclineButton={true}
disableStyles={true}
onAccept={() => initializeAndTrack(location)}
>
<p className="cookieMessage">This website uses cookies ? </p>
</CookieConsent>
</StyledCookieBar>
)
}
Example #5
Source File: homeAbout.js From ar-episode2 with MIT License | 5 votes |
HomeAbout = ({ onCursor }) => {
//Default state, using number for our id. Which ever the number/id is in the state. That will be opened.
const [expanded, setExpanded] = useState(0)
const animation = useAnimation()
const [aboutRef, inView] = useInView({
triggerOnce: true,
// Giving our scrollwheel additional 300px before executing animation
rootMargin: "-300px",
})
useEffect(() => {
if (inView) {
animation.start("visible")
}
}, [animation, inView])
return (
<HomeAboutSection
ref={aboutRef}
animate={animation}
initial="hidden"
variants={{
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8, ease: [0.6, 0.05, -0.01, 0.9] },
},
hidden: { opacity: 0, y: 72 },
}}
>
<Container>
<Flex alignTop>
<About>
<h2>
Furrow is an integrated, full-service creative studio offering
video production, creative development, and post-production
services.
</h2>
<p>
Everybody’s got a story. And we don’t stop until we’ve uncovered
what makes yours worth telling. Whether it’s working directly with
you, an agency partner, or putting the finishing touches on
something special, we’re ready to dig in and get our hands
dirty—are you?
</p>
</About>
<Services>
<h3>Services</h3>
{accordionIds.map((details, index) => (
<Accordion
key={index}
details={details}
expanded={expanded}
setExpanded={setExpanded}
onCursor={onCursor}
/>
))}
</Services>
</Flex>
</Container>
</HomeAboutSection>
)
}
Example #6
Source File: burgerNav.js From open-jobboard with Apache License 2.0 | 5 votes |
BurgerNav = () => {
const [open, setOpen] = useState(false)
const [windowWidth, setWindowWidth] = useState(0)
useEffect(() => {
let handleWindowSizeChange
// if (isSSR) is necessary to prevent error during the gatsby build
if (!isSSR) {
handleWindowSizeChange = () => setWindowWidth(window.innerWidth)
// set initial innerWidth when component mounts
setWindowWidth(window.innerWidth)
}
// Add event listener to update windowWidth in state
window.addEventListener("resize", handleWindowSizeChange)
return () => window.removeEventListener("resize", handleWindowSizeChange)
}, [windowWidth])
// Required for animation - start after the splashScreen sequence is done
const controls = useAnimation()
let navigation
if (detectMobileAndTablet(windowWidth)) {
navigation = (
<>
<StyledBurger
aria-controls="sidebar"
open={open}
onClick={() => setOpen(!open)}
>
<div />
<div />
<div />
</StyledBurger>
<Sidebar id="sidebar" open={open} setOpen={setOpen} />
</>
)
} else {
navigation = <Navbar />
}
return (
<StyledHeader>
{/* add blur class to body when sidebar is opened */}
<Helmet bodyAttributes={{ class: open ? "blur" : "" }} />
<StyledContentWrapper>
<Link to="/" aria-label="home">
<Logo color="primary" size="2rem" />
</Link>
{navigation}
</StyledContentWrapper>
</StyledHeader>
)
}
Example #7
Source File: IndexHeroFeaturedIn.jsx From pooltogether-landing-site with MIT License | 5 votes |
IndexHeroFeaturedIn = () => {
const controls = useAnimation()
const [ref, inView] = useInView()
useEffect(() => {
if (inView) {
controls.start('visible')
}
}, [controls, inView])
const containerVariants = {
visible: {
transition: {
staggerChildren: 0.12
}
},
hidden: {}
}
return (
<div id='featured-in' className='text-center pt-10'>
<div className='pool-container mx-auto'>
<h5 className='my-0 sm:mt-4 leading-tight'>Featured in:</h5>
<motion.div
className={classnames(
'flex flex-col xs:flex-row xs:flex-wrap justify-start items-start',
'mt-2 mb-4 px-4 xs:px-8 rounded-xl -mx-4 sm:-mx-12 lg:-mx-16'
)}
ref={ref}
animate={controls}
initial='hidden'
variants={containerVariants}
>
<GridItemSupportedBy
altBg
title={'Binance Academy'}
img={BinanceAcademySvg}
url='https://academy.binance.com/en/articles/how-pool-together-turns-saving-money-into-a-game'
/>
<GridItemSupportedBy
altBg
title={'Zapper'}
img={ZapperFiSvg}
url='https://learn.zapper.fi/articles/how-to-tranfer-eth-from-coinbase-to-defi'
/>
<GridItemSupportedBy
altBg
title={'Ethereum.org'}
img={EthereumPng}
url='https://ethereum.org/en/dapps/'
/>
<GridItemSupportedBy
altBg
title={'Bankless'}
img={BanklessPng}
url='https://shows.banklesshq.com/p/early-access-meet-the-nation-pooltogether'
/>
<GridItemSupportedBy
altBg
title={'CoinDesk'}
img={CoinDeskPng}
url='https://www.coindesk.com/tag/pooltogether'
/>
</motion.div>
</div>
</div>
)
}
Example #8
Source File: splashScreen.js From gatsby-starter-portfolio-minimal with MIT License | 5 votes |
SplashScreen = () => {
const { state, setState } = useContext(Context)
const backgroundControls = useAnimation()
const backdropControls = useAnimation()
useEffect(() => {
const sequence = async () => {
await backgroundControls.start({ opacity: 1 })
await backdropControls.start({ height: "0%", transition: { delay: 0.8 } })
await backgroundControls.start({ opacity: 0, transition: { delay: 0.6 } })
setState({ ...state, isIntroDone: true })
}
sequence()
}, [backgroundControls, backdropControls, setState, state])
return (
<StyledSplashScreen
initial={{ opacity: 0 }}
animate={backgroundControls}
darkMode={state.darkMode}
>
{/* Add splashScreen class to body (prevents scrolling during splashScreen) */}
<Helmet
bodyAttributes={{ class: !state.isIntroDone ? "splashScreen" : "" }}
/>
<div className="logo-wrapper">
<motion.div
className="backdrop"
initial={{ height: "100%" }}
animate={backdropControls}
/>
<Logo
size="3rem"
color={
state.darkMode
? darkTheme.colors.primary
: lightTheme.colors.background
}
/>
</div>
</StyledSplashScreen>
)
}
Example #9
Source File: interests.js From gatsby-starter-portfolio-minimal with MIT License | 5 votes |
Interests = ({ content }) => {
const { exports, frontmatter } = content[0].node
const { shownItems, interests } = exports
const [shownInterests, setShownInterests] = useState(shownItems)
const ref = useRef()
const onScreen = useOnScreen(ref)
const iControls = useAnimation()
const bControls = useAnimation()
useEffect(() => {
// If mobile or tablet, show all interests initially
// Otherwise interests.mdx will determine how many interests are shown
// (isSSR) is used to prevent error during gatsby build
if (!isSSR && detectMobileAndTablet(window.innerWidth)) {
setShownInterests(interests.length)
}
}, [interests])
useEffect(() => {
const sequence = async () => {
if (onScreen) {
// i receives the value of the custom prop - can be used to stagger
// the animation of each "interest" element
await iControls.start(i => ({
opacity: 1,
scaleY: 1,
transition: { delay: i * 0.1 },
}))
await bControls.start({ opacity: 1, scaleY: 1 })
}
}
sequence()
}, [onScreen, shownInterests, iControls, bControls])
const showMoreItems = () => setShownInterests(shownInterests + 4)
return (
<StyledSection id="interests">
<StyledContentWrapper>
<h3 className="section-title">{frontmatter.title}</h3>
<StyledInterests itemCount={interests.length} ref={ref}>
{interests.slice(0, shownInterests).map(({ name, icon }, key) => (
<motion.div
className="interest"
key={key}
custom={key}
initial={{ opacity: 0, scaleY: 0 }}
animate={iControls}
>
<Img className="icon" fixed={icon.childImageSharp.fixed} /> {name}
</motion.div>
))}
{shownInterests < interests.length && (
<motion.div initial={{ opacity: 0, scaleY: 0 }} animate={bControls}>
<Button
onClick={() => showMoreItems()}
type="button"
textAlign="left"
>
+ Load more
</Button>
</motion.div>
)}
</StyledInterests>
</StyledContentWrapper>
</StyledSection>
)
}
Example #10
Source File: hero.js From gatsby-starter-portfolio-minimal with MIT License | 5 votes |
Hero = ({ content }) => {
const { frontmatter, body } = content[0].node
const { isIntroDone, darkMode } = useContext(Context).state
// Controls to orchestrate animations of greetings, emoji, social profiles, underlining
const gControls = useAnimation()
const eControls = useAnimation()
const sControls = useAnimation()
const uControls = useAnimation()
// Start Animations after the splashScreen sequence is done
useEffect(() => {
const pageLoadSequence = async () => {
if (isIntroDone) {
eControls.start({
rotate: [0, -10, 12, -10, 9, 0, 0, 0, 0, 0, 0],
transition: { duration: 2.5, loop: 3, repeatDelay: 1 },
})
await gControls.start({
opacity: 1,
y: 0,
transition: { delay: 0.4 },
})
await sControls.start({
opacity: 1,
x: 0,
})
// Animate underlining to hover state
await uControls.start({
boxShadow: `inset 0 -2rem 0 ${
darkMode ? darkTheme.colors.secondary : lightTheme.colors.secondary
}`,
transition: { delay: 0.4, ease: "circOut" },
})
}
}
pageLoadSequence()
}, [isIntroDone, darkMode, eControls, gControls, sControls, uControls])
return (
<StyledSection id="hero">
<StyledContentWrapper>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={gControls}
data-testid="animated-heading"
>
<h1 className="title">
<div className="greetings">
{frontmatter.greetings}
<motion.div
animate={eControls}
style={{ originX: 0.7, originY: 0.7 }}
>
<Img
className="emoji"
fluid={frontmatter.icon.childImageSharp.fluid}
/>
</motion.div>
</div>
{frontmatter.title}
</h1>
<h2 className="subtitle">
{frontmatter.subtitlePrefix}{" "}
<AnimatedUnderlining animate={uControls} big>
{frontmatter.subtitle}
</AnimatedUnderlining>
</h2>
<div className="description">
<MDXRenderer>{body}</MDXRenderer>
</div>
</motion.div>
<motion.div initial={{ opacity: 0, x: 20 }} animate={sControls}>
<Social fontSize=".95rem" padding=".3rem 1.25rem" width="auto" />
</motion.div>
</StyledContentWrapper>
</StyledSection>
)
}
Example #11
Source File: about.js From gatsby-starter-portfolio-minimal with MIT License | 5 votes |
About = ({ content }) => {
const { frontmatter, body } = content[0].node
const { isIntroDone } = useContext(Context).state
const tControls = useAnimation()
const iControls = useAnimation()
// Required for animating the text content
const tRef = useRef()
const tOnScreen = useOnScreen(tRef)
// Required for animating the image
const iRef = useRef()
const iOnScreen = useOnScreen(iRef)
// Only trigger animations if the intro is done or disabled
useEffect(() => {
if (isIntroDone) {
if (tOnScreen) tControls.start({ opacity: 1, y: 0 })
if (iOnScreen) iControls.start({ opacity: 1, x: 0 })
}
}, [isIntroDone, tControls, iControls, tOnScreen, iOnScreen])
return (
<StyledSection id="about">
<StyledContentWrapper>
<motion.div
className="inner-wrapper"
ref={tRef}
initial={{ opacity: 0, y: 20 }}
animate={tControls}
>
<h3 className="section-title">{frontmatter.title}</h3>
<div className="text-content">
<MDXRenderer>{body}</MDXRenderer>
</div>
</motion.div>
<motion.div
className="image-content"
ref={iRef}
initial={{ opacity: 0, x: 20 }}
animate={iControls}
>
<Img
className="about-author"
fluid={frontmatter.image.childImageSharp.fluid}
/>
</motion.div>
</StyledContentWrapper>
</StyledSection>
)
}
Example #12
Source File: header.js From gatsby-starter-portfolio-minimal with MIT License | 5 votes |
Header = () => {
const { isIntroDone } = useContext(Context).state
const [open, setOpen] = useState(false)
const [windowWidth, setWindowWidth] = useState(0)
useEffect(() => {
let handleWindowSizeChange
// if (isSSR) is necessary to prevent error during the gatsby build
if (!isSSR) {
handleWindowSizeChange = () => setWindowWidth(window.innerWidth)
// set initial innerWidth when component mounts
setWindowWidth(window.innerWidth)
}
// Add event listener to update windowWidth in state
window.addEventListener("resize", handleWindowSizeChange)
return () => window.removeEventListener("resize", handleWindowSizeChange)
}, [windowWidth])
// Required for animation - start after the splashScreen sequence is done
const controls = useAnimation()
useEffect(() => {
if (isIntroDone)
controls.start({ opacity: 1, y: 0, transition: { delay: 0.2 } })
}, [isIntroDone, controls])
let navigation
if (detectMobileAndTablet(windowWidth)) {
navigation = (
<>
<StyledBurger
aria-controls="sidebar"
open={open}
onClick={() => setOpen(!open)}
>
<div />
<div />
<div />
</StyledBurger>
<Sidebar id="sidebar" open={open} setOpen={setOpen} />
</>
)
} else {
navigation = <Navbar />
}
return (
<StyledHeader initial={{ opacity: 0, y: -10 }} animate={controls}>
{/* add blur class to body when sidebar is opened */}
<Helmet bodyAttributes={{ class: open ? "blur" : "" }} />
<StyledContentWrapper>
<Link to="/" aria-label="home">
<Logo color="primary" size="2rem" />
</Link>
{navigation}
</StyledContentWrapper>
</StyledHeader>
)
}
Example #13
Source File: articles.js From gatsby-starter-portfolio-minimal with MIT License | 4 votes |
Articles = () => {
const MAX_ARTICLES = shownArticles
const { isIntroDone, darkMode } = useContext(Context).state
const [articles, setArticles] = useState()
const articlesControls = useAnimation()
// Load and display articles after the splashScreen sequence is done
useEffect(() => {
const loadArticles = async () => {
if (isIntroDone) {
await articlesControls.start({
opacity: 1,
y: 0,
transition: { delay: 1 },
})
fetch(mediumRssFeed, { headers: { Accept: "application/json" } })
// fetch(rssFeed, { headers: { Accept: "application/json" } })
.then(res => res.json())
// Feed also contains comments, therefore we filter for articles only
.then(data => data.items.filter(item => item.categories.length > 0))
// .then(data => data.items.filter(item => item.title.length > 0))
.then(newArticles => newArticles.slice(0, MAX_ARTICLES))
.then(articles => setArticles(articles))
.catch(error => console.log(error))
}
}
loadArticles()
}, [isIntroDone, articlesControls, MAX_ARTICLES])
return (
<StyledSection
id="articles"
initial={{ opacity: 0, y: 20 }}
animate={articlesControls}
>
<StyledContentWrapper>
<h3 className="section-title">Latest Articles</h3>
<div className="articles">
{articles
? articles.map(item => (
<a
href={item.link}
target="_blank"
rel="nofollow noopener noreferrer"
title={item.title}
aria-label={item.link}
key={item.link}
>
<div className="card">
<span className="category">
<Underlining color="tertiary" hoverColor="secondary">
{item.categories[2]}
</Underlining>
</span>
<h4 className="title">{item.title}</h4>
<span className="date">{parseDate(item.pubDate)}</span>
</div>
</a>
))
: [...Array(MAX_ARTICLES <= 3 ? MAX_ARTICLES : 3)].map((i, key) => (
<div className="card" key={key}>
<SkeletonLoader
height="1.5rem"
style={{ marginBottom: ".5rem" }}
background={
darkMode
? darkTheme.colors.tertiary
: lightTheme.colors.tertiary
}
/>
<SkeletonLoader
height="4rem"
background={
darkMode
? darkTheme.colors.tertiary
: lightTheme.colors.tertiary
}
/>
<SkeletonLoader
height=".75rem"
width="50%"
style={{ marginTop: ".5rem" }}
background={
darkMode
? darkTheme.colors.tertiary
: lightTheme.colors.tertiary
}
/>
</div>
))}
</div>
</StyledContentWrapper>
</StyledSection>
)
}
Example #14
Source File: BrandAssetsPage.jsx From pooltogether-landing-site with MIT License | 4 votes |
BrandAssetsPage = (props) => {
const controls = useAnimation()
const [ref, inView] = useInView()
useEffect(() => {
if (inView) {
controls.start('visible')
}
}, [controls, inView])
return <>
<div
className='pool-container mx-auto flex flex-col text-base h-full z-10 relative mb-20'
>
<h4
className='my-0'
>
Brand Assets
</h4>
<h2
className='mb-6'
>
PoolTogether Logos & Usage
</h2>
<p>
Here is a handy zipped-up package of all the latest logos, wordmarks, and symbols to assist you in building PoolTogether integrations or linking to us:
</p>
<BoxLinkWithIcon
isExternal
href='https://github.com/pooltogether/pooltogether--brand-assets/blob/141936c859553a2a42ac96ed807551b85a4d56d9/pooltogether-brand-assets-v1.2.0.zip?raw=true'
title='Download brand assets zip package'
icon={'download'}
>
pooltogether-brand-assets-v1.2.0.zip
</BoxLinkWithIcon>
<br/>
<h4
className='my-5'
>
By Style
</h4>
<p>
If you would rather download one or two specific styles you can find them on the <a href='https://github.com/pooltogether/pooltogether--brand-assets'>GitHub brand assets repository</a>.
</p>
<div className='my-5'>
<p className='text-base my-0 text-accent-1'>
Examples:
</p>
<motion.div
className={classnames(
'flex flex-col xs:flex-row xs:flex-wrap justify-start items-start',
'mt-2 mb-4 px-4 xs:px-8 rounded-xl -mx-4 lg:-mx-8',
)}
ref={ref}
animate={controls}
initial='hidden'
variants={{
visible: {
transition: {
staggerChildren: 0.2
}
},
hidden: {
},
}}
>
<GridItemBrandAssets
title={`Purple Wordmark`}
img={PoolTogetherPurpleWordmarkImg}
/>
<GridItemBrandAssets
title={`White Mark`}
img={PoolTogetherWhiteMarkImg}
/>
<GridItemBrandAssets
title={`Trophy`}
img={PoolTogetherTrophyImg}
/>
</motion.div>
</div>
<h4
className='my-5'
>Usage</h4>
<p>
We would like you to use any of the the assets 'as is'. If you need a modified version of any of the logos feel free to <a
href='mailto:[email protected]'
>reach out to us</a> and we'll be happy to help.
</p>
<p>
Please do not use any of the PoolTogether assets as the logo or in your logo for your app or brand. Thanks!
</p>
</div>
</>
}
Example #15
Source File: IndexIntegrations.jsx From pooltogether-landing-site with MIT License | 4 votes |
IndexIntegrations = () => {
const controls = useAnimation()
const [ref, inView] = useInView()
useEffect(() => {
if (inView) {
controls.start('visible')
}
}, [controls, inView])
const containerVariants = {
visible: {
transition: {
staggerChildren: 0.2
}
},
hidden: {}
}
return (
<>
<div className='bg-secondary'>
<div className='pool-container mx-auto pt-12 pb-6 sm:pt-20 sm:pb-16'>
<div className='lg:px-20'>
<div className='flex items-center justify-between'>
<h1 className='leading-10 sm:leading-tight'>
<div className='text-flashy'>Protocol</div>{' '}
<div className='block -mt-2'>Integrations</div>
</h1>
</div>
<div className='flex flex-col py-4'>
<p className='text-sm xs:text-xl sm:text-xl lg:text-3xl lg:max-w-3xl'>
Try community-built interfaces and get inspired by what you can build on the
PoolTogether protocol.
</p>
<motion.div
className={classnames(
'flex flex-col sm:flex-row sm:flex-wrap',
'mt-8 mb-4 rounded-xl text-base lg:text-lg -mx-4 sm:-mx-4 lg:-mx-8'
)}
ref={ref}
animate={controls}
initial='hidden'
variants={containerVariants}
>
{/* <GridItem
title={'Argent'}
description={`Use the Argent app to join the pool.`}
img={ArgentSvg}
url='https://www.argent.xyz/'
/> */}
<GridItem
altBg
title={'Dharma'}
description={`Deposit into PoolTogether from your US bank.`}
img={DharmaSvg}
url='https://www.dharma.io/'
/>
<GridItem
altBg
title={'ZapperFi'}
description={`Join PoolTogether using this portal to DeFi.`}
img={ZapperFiSvg}
url='https://www.zapper.fi/#/dashboard'
/>
<GridItem
altBg
title={'Zerion'}
description={`Access DeFi & view your PoolTogether deposits.`}
img={ZerionSvg}
url='https://zerion.io/'
/>
<GridItem
altBg
title={'Twitter Bot'}
description={`Updates each time someone joins or wins!`}
img={BotSvg}
url='https://twitter.com/PoolTogetherBot'
attribution={`bot icon by Sophia Bai from the Noun Project`}
/>
{/*
<GridItem
title={'EBO'}
description={`EBO Finance is a wallet app for joining the pool.`}
img={EBOSvg}
url='https://ebo.io/'
/> */}
</motion.div>
</div>
</div>
<div className='bg-card rounded-xl mx-auto text-center p-4 xs:p-12 sm:pt-12 sm:pb-12 sm:mt-10'>
<div className='flex flex-col items-center'>
<h2 className='mt-4 mb-8 text-center'>Check out our developer documentation</h2>
<p className='text-sm xs:text-lg sm:text-xl max-w-lg text-center'>
Learn about the PoolTogether protocol and emerging use cases
</p>
<ButtonLink
secondary
textSize='2xl'
href='https://docs.pooltogether.com'
as='https://docs.pooltogether.com'
className='my-8 w-3/4 sm:w-1/2'
>
Go to docs
</ButtonLink>
</div>
</div>
</div>
</div>
</>
)
}
Example #16
Source File: IndexSupportedBy.jsx From pooltogether-landing-site with MIT License | 4 votes |
IndexSupportedBy = () => {
const controls = useAnimation()
const [ref, inView] = useInView()
useEffect(() => {
if (inView) {
controls.start('visible')
}
}, [controls, inView])
const containerVariants = {
visible: {
transition: {
staggerChildren: 0.12
}
},
hidden: {}
}
return (
<div id='backed-by' className='bg-darkened text-center pt-12 pb-6 sm:pt-20 sm:pb-16'>
<div className='pool-container mx-auto'>
<h3 className='text-sm xs:text-lg sm:text-xl my-0 sm:mb-12 leading-tight'>
Protocol supported by
</h3>
<motion.div
className={classnames(
'flex flex-col xs:flex-row xs:flex-wrap justify-start items-start',
'mt-2 mb-4 px-4 xs:px-8 rounded-xl -mx-4 sm:-mx-12 lg:-mx-16'
)}
ref={ref}
animate={controls}
initial='hidden'
variants={containerVariants}
>
<GridItemSupportedBy
title={'ConsenSys'}
img={ConsensysSvg}
url='https://www.consensys.com'
/>
<GridItemSupportedBy
title={'IDEO'}
img={IdeoSvg}
url='https://www.ideo.com'
maxHeight={30}
/>
<GridItemSupportedBy
title={'DTC Capital'}
img={DTCCapitalSvg}
url='https://www.dtc.capital'
/>
<GridItemSupportedBy title={'ParaFi'} img={ParaFiSvg} url='https://www.parafi.capital/' />
<GridItemSupportedBy
title={'MetaCartel Ventures'}
img={MetaCartelSvg}
url='https://metacartel.org'
/>
<GridItemSupportedBy title={'The LAO'} img={TheLaoSvg} url='https://thelao.io' />
<GridItemSupportedBy
title={'Robot Ventures'}
img={RobotVenturesSvg}
url='https://twitter.com/robotventures'
/>
</motion.div>
{/* <div className='flex justify-center items-center sm:-mx-2'>
<a
href='https://makerdao.com'
title='View the Maker site'
target='_blank'
rel='noopener noreferrer'
>
<img
src={MakerDaoSvg}
className='mt-4'
/>
</a>
</div> */}
</div>
</div>
)
}
Example #17
Source File: footer.js From ar-episode2 with MIT License | 4 votes |
Footer = ({ setHamburgerPosition, onCursor }) => {
const instagramRef = useRef(null)
const instagramPosition = useElementPosition(instagramRef)
const facebookRef = useRef(null)
const facebookPosition = useElementPosition(facebookRef)
const vimeoRef = useRef(null)
const vimeoPosition = useElementPosition(vimeoRef)
const animation = useAnimation()
const [footerRef, inView] = useInView({
triggerOnce: true,
rootMargin: "-100px",
})
useEffect(() => {
if (inView) {
animation.start("visible")
}
}, [animation, inView])
const menuHover = x => {
onCursor("locked")
setHamburgerPosition({ x: x })
}
return (
<FooterNav
ref={footerRef}
animate={animation}
initial="hidden"
variants={{
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8, ease: [0.6, 0.05, -0.01, 0.9] },
},
hidden: { opacity: 0, y: 72 },
}}
>
<Container>
<Flex spaceBetween>
<FooterContent>
<p>902.315.1279</p>
<p>[email protected]</p>
</FooterContent>
<FooterContent wider>
<p>15 Camburhill Ct Unit C</p>
<p>Charlottetown, PE C1E 0E2</p>
</FooterContent>
<FooterSocial>
<a
onMouseEnter={() => menuHover(instagramPosition.x)}
onMouseLeave={onCursor}
ref={instagramRef}
href="/"
target="_blank"
>
<Instagram />
</a>
<a
onMouseEnter={() => menuHover(facebookPosition.x)}
onMouseLeave={onCursor}
ref={facebookRef}
href="/"
target="_blank"
>
<Facebook />
</a>
<a
onMouseEnter={() => menuHover(vimeoPosition.x)}
onMouseLeave={onCursor}
ref={vimeoRef}
href="/"
target="_blank"
>
<Vimeo />
</a>
</FooterSocial>
</Flex>
</Container>
</FooterNav>
)
}
Example #18
Source File: SubmitForm.js From webappdevtest with MIT License | 4 votes |
export function SubmitForm(props) {
const {desktopSize, selectedCity, onNewLinkSubmit} = props
const [isOpen, setIsOpen] = useState(window.innerWidth > desktopSize);
const [isThankYou, setIsThankYou] = useState(false);
const linkEl = useRef(null);
const cityEl = useRef(null);
const containerControls = useAnimation();
const closeButtonControls = useAnimation();
const chevronControls = useAnimation();
const toggleButtonLabelControls = useAnimation();
const container_variants = {"open": {height: 470, top: `calc(var(--vh, 1vh) * 100 - 470px)`},"close": {height: 50, top: `calc(var(--vh, 1vh) * 100 - 50px)`}}
const closeButton_variants = {"open": {backgroundColor: '#1f2532'},"close": {backgroundColor: (window.innerWidth < desktopSize ? '#2d3142' : '#FF5853')}}
const chevron_variants = {"open": {rotate: 0}, "close": {rotate: 180}}
const toggleButton_variants = {"open": {opacity: 0}, "close": {opacity: 1}}
useEffect(()=>{
if(isOpen) {
setIsOpen(selectedCity === null)
}
}, [selectedCity])
containerControls.start(container_variants[isOpen ? "open": "close"])
closeButtonControls.start(closeButton_variants[isOpen ? "open": "close"])
chevronControls.start(chevron_variants[isOpen ? "open": "close"])
toggleButtonLabelControls.start(toggleButton_variants[isOpen ? "open": "close"])
const handleCloseToggle = () => {
setIsOpen(!isOpen)
!isOpen && Event("UserAction", "Opened submit link form", window.innerWidth > desktopSize ? "DESKTOP": "MOBILE")
!isOpen && setIsThankYou(false)
chevronControls.start({scale: 1})
}
return(
<motion.div
className="submitFormContainer"
variants = {container_variants}
initial = {isOpen? "open" : "close"}
animate = {containerControls}
transition = {{
type: 'spring',
damping: 16
}}
drag="y"
dragConstraints={{top: 0, bottom:0}}
dragMomentum={false}
onDragEnd={(e, info) => {if((info.point.y > 10 && isOpen) || (info.point.y < -10 && !isOpen)) {handleCloseToggle()}}}
>
<motion.button
className="toggleCloseButton"
variants = {closeButton_variants}
initial = {isOpen? "open" : "close"}
animate = {closeButtonControls}
onHoverStart = {() => chevronControls.start({scale: 1.3})}
onHoverEnd = {() => chevronControls.start({scale: 1})}
onClick={() => {
handleCloseToggle();
}}
>
<motion.img
src={isOpen ? chevron_primary : chevron_white}
alt="toggle submit form button"
variants = {chevron_variants}
initial = {isOpen? "open" : "close"}
animate={chevronControls}
/>
<motion.p
variants= {toggleButton_variants}
initial = {isOpen ? "open" : "close"}
animate={toggleButtonLabelControls}
>Add to the map!p</motion.p>
</motion.button>
{!isThankYou &&
<motion.div
className="submitFormBody"
>
<h2>Add more to the map</h2>
<p>
What does this form do?
</p>
<form
onSubmit={(e) => {
e.preventDefault()
onNewLinkSubmit({
"link": linkEl.current.value,
"city": cityEl.current.value
})
linkEl.current.value = '';
cityEl.current.value = '';
setIsThankYou(true);
window.scrollTo(0, 0);
}}
>
<label htmlFor="form_link" className="field">
<span className="form_label">Link:</span>
<input required id="form_link" type="url" ref={linkEl} placeholder="https://..."/>
</label>
<label htmlFor="form_city" className="field">
<span className="form_label">City:</span>
<input required id="form_city" type="text" ref={cityEl} placeholder="Where did the protest happen?"/>
</label>
<motion.button
type= "submit"
className = "primary_btn submitButton"
whileHover = {{scale: 1.02}}
whileTap = {{scale: 0.98}}
>
Submit for review
</motion.button>
</form>
{/* <p className="sendVideoMessage">Want to send us the video instead, our WhatApp is open at +91-xxx-xxx-xxxx</p> */}
</motion.div>
}
{isThankYou &&
<div className="thankYouBody">
<h1>You are a rockstar!</h1>
<p>We appreciate your contribution. We will review the link you submitted and add it to the map as soon as we can</p>
<motion.button
onClick={() => handleCloseToggle()}
whileHover = {{scale: 1.02}}
whileTap = {{scale: 0.98}}
className= "primary_btn doneButton"
>OK
</motion.button>
<motion.img
src={fist}
initial = {{y:0}}
animate = {{y:10}}
transition = {{
yoyo: 'Infinity',
ease: 'easeInOut'
}}
/>
</div>
}
</motion.div>
)
}
Example #19
Source File: HomeFeatured.js From ar-episode2 with MIT License | 4 votes |
HomeFeatured = ({ onCursor }) => {
const [hovered, setHovered] = useState(false)
const animation = useAnimation()
const [featured, inView] = useInView({
triggerOnce: true,
rootMargin: "-300px",
})
useEffect(() => {
if (inView) {
animation.start("visible")
}
}, [animation, inView])
return (
<HomeFeaturedSection
ref={featured}
animate={animation}
initial="hidden"
variants={{
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8, ease: [0.6, 0.05, -0.01, 0.9] },
},
hidden: { opacity: 0, y: 72 },
}}
>
<Container>
<Link to="/">
<FeaturedContent
onHoverStart={() => setHovered(!hovered)}
onHoverEnd={() => setHovered(!hovered)}
onMouseEnter={() => onCursor("hovered")}
onMouseLeave={onCursor}
>
<Flex spaceBetween>
<h3>Featured Project</h3>
<motion.div
animate={{ opacity: hovered ? 1 : 0 }}
transition={{ duration: 0.6, ease: [0.6, 0.05, -0.01, 0.9] }}
className="meta"
>
<h4>PEI Seafood</h4>
<h4>2019</h4>
</motion.div>
</Flex>
<h2 className="featured-title">
NOT <br /> HUMBLE
<span className="arrow">
<motion.svg
animate={{ x: hovered ? 48 : 0 }}
transition={{ duration: 0.6, ease: [0.6, 0.05, -0.01, 0.9] }}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 101 57"
>
<path
d="M33 34H0V24h81.429L66 7.884 73.548 0l19.877 20.763.027-.029L101 28.618 73.829 57l-7.548-7.884L80.753 34H33z"
fill="#FFF"
fillRule="evenodd"
></path>
</motion.svg>
</span>
</h2>
</FeaturedContent>
<FeaturedVideo>
<video
loop
autoPlay
src={require("../../assets/video/featured-video.mp4")}
></video>
</FeaturedVideo>
</Link>
</Container>
<Container>
<FeaturedProjects>
<Flex flexEnd>
<button>
<span>All Projects</span>
</button>
</Flex>
</FeaturedProjects>
</Container>
</HomeFeaturedSection>
)
}
Example #20
Source File: CityDetailView.js From webappdevtest with MIT License | 4 votes |
export function CityDetailView(props) {
const {selectedCity, videoData, onCityDetailClose, desktopSize } = props;
let currentScrollValue = useMotionValue(0);
let touchStart = 0;
let touchEnd = 0;
const cityDetailViewEl = useRef(null)
// let prevScrollValue = useMotionValue(0);
const containerAnimControls = useAnimation();
const headerAnimControls = useAnimation();
const bodyAnimControls = useAnimation();
const closeTransition = {ease: 'easeOut', duration: 0.2}
const openTransition = {type: 'spring', damping: 16}
const variants = {
open: (window.innerWidth > desktopSize) ? {width: '30em', top: 0, transition: openTransition}:{width: 'calc(var(--vw, 1vw) * 100)', top: 'calc(var(--vh, 1vh) * 20)', transition: openTransition},
close: (window.innerWidth > desktopSize) ? {width: 0, top: 0, y: 0, transition: closeTransition} : {width: 'calc(var(--vw, 1vw) * 100)', top: 'calc(var(--vh, 1vh) * 100)', y: 0, transition: closeTransition}
}
const childVariants = {
open: {opacity: 1, y: 0, transition: {ease: 'easeOut'}}, close: {opacity: 0, y: 10, transition: {ease: 'linear'}}
}
const scrollToTop = {top: 0, transition:{ease:'linear', duration: 0.2}}
const handleInOutAnimation = async () => {
if(selectedCity) {
containerAnimControls.start(variants.open)
await headerAnimControls.start(childVariants.open)
bodyAnimControls.start(childVariants.open)
}
else {
await headerAnimControls.start(childVariants.close)
await bodyAnimControls.start(childVariants.close)
containerAnimControls.start(variants.close)
}
}
useEffect(()=> {
cityDetailViewEl.current.scrollTo(0,0);
handleInOutAnimation();
cityDetailViewEl.current.addEventListener('touchstart', function(e){touchStart=e.changedTouches[0].clientY})
cityDetailViewEl.current.addEventListener('touchend', function(e) {
touchEnd = e.changedTouches[0].clientY;
if(currentScrollValue.get() <= 0 && touchEnd > touchStart) {
onCityDetailClose();
touchStart = 0;
touchEnd = 0;
}
});
// window.addEventListener('wheel', function() {
// setTimeout(()=> {
// if(currentScrollValue.get() === prevScrollValue.get()) {
// onCityDetailClose();
// prevScrollValue.set(0)
// }
// else {
// prevScrollValue.set(currentScrollValue.get())
// }
// }, 500)
// })
}, [selectedCity])
return (
<AnimatePresence>
<motion.div
className="cityDetailView"
ref = {cityDetailViewEl}
variants={variants}
initial="close"
exit="close"
animate = {containerAnimControls}
onScroll = {(e) => {
currentScrollValue.set(e.nativeEvent.target.scrollTop);
if(currentScrollValue.get() > 0) {
containerAnimControls.start(scrollToTop)
}
}}
style={{height: 'calc(var(--vh, 1vh) * 100)', overflow: 'scroll', scrollBehavior: 'smooth', overscrollBehaviorY: 'none'}}
>
<motion.div
className="cityDetailView_Header"
variants={childVariants}
initial="close"
animate = {headerAnimControls}
>
<h1>{selectedCity}</h1>
<button className="close_btn" onClick={(e) => onCityDetailClose(e)}>
<img src={close} alt="close icon" />
</button>
</motion.div>
<motion.div
className="cityDetailView_videoList"
variants={childVariants}
initial="close"
animate={bodyAnimControls}
>
{videoData[selectedCity].blocks.slice(0).reverse().map((videoObj, index) => {
if(videoObj.link.indexOf('twitter.com') !== -1) {
let id = videoObj.link.split(/\/?\//)[4].split('?')[0];
return (
<div className="linkCard" key={id + index}>
<p>{videoObj.date}</p>
<h2>{videoObj.caption}</h2>
<TwitterVideoEmbed id={id}
onLoad={e => {if(e){e.style.display = "inline-block"}}}
/>
</div>
)
}
else if(videoObj.link.indexOf('instagram.com') !== -1) {
return (
<div className="linkCard" key={videoObj.link+ index}>
<p>{videoObj.date}</p>
<h2>{videoObj.caption}</h2>
<InstagramEmbed url={videoObj.link}
onLoad={e => {if(e){e.style.display = "inline-block"}}}
/>
</div>
)
}
else {
return (
<div className="linkCard" key={index}>
<p>{videoObj.date}</p>
<h2>{videoObj.caption}</h2>
<a href={videoObj.link} target="_blank" className='rawLink'>{videoObj.link} </a>
</div>
)
}
})}
</motion.div>
</motion.div>
</AnimatePresence>
)
}