Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(www): add 'lead' animation to the Ecosystem horizontal scrollers #9606

Merged
merged 8 commits into from
Nov 7, 2018
152 changes: 111 additions & 41 deletions www/src/components/ecosystem/ecosystem-board.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
import styled from "react-emotion"

Expand All @@ -20,46 +20,116 @@ const EcosystemBoardRoot = styled(`div`)`
}
`

const EcosystemBoard = ({
icons: { plugins: PluginsIcon, starters: StartersIcon },
starters,
plugins,
}) => (
<EcosystemBoardRoot>
<EcosystemSection
title="Plugins"
description="Plugins are packages that extend Gatsby sites. They can source content, transform data, and more!"
subTitle="Featured Plugins"
icon={PluginsIcon}
links={[
{ label: `Browse Plugins`, to: `/plugins/` },
{
label: `Plugin Authoring`,
to: `/docs/plugin-authoring/`,
secondary: true,
},
{ label: `Plugin Docs`, to: `/docs/plugins/`, secondary: true },
]}
featuredItems={plugins}
/>
<EcosystemSection
title="Starters"
description="Starters are Gatsby sites that are preconfigured for different use cases to give you a head start for your project."
subTitle="Featured Starters"
icon={StartersIcon}
links={[
{ label: `Browse Starters`, to: `/starters/` },
{ label: `Starter Docs`, to: `/docs/starters/`, secondary: true },
]}
featuredItems={starters}
/>
<EcosystemSection
title="External Resources"
description="A curated list of interesting Gatsby community projects and learning resources like podcasts and tutorials."
links={[{ label: `Browse Resources`, to: `/docs/awesome-gatsby/` }]}
/>
</EcosystemBoardRoot>
)
class EcosystemBoard extends Component {
observer
observerTargets = []

componentDidMount() {
if (typeof window.IntersectionObserver !== `undefined`) {
this.setupObserver()
}
}

componentWillUnmount() {
if (typeof window.IntersectionObserver !== `undefined`) {
this.observerTargets.forEach(target => this.observer.unobserve(target))
}
}

setupObserver = () => {
const options = { rootMargin: `0px`, threshold: [1] }
this.observer = new IntersectionObserver(this.handleIntersect, options)
jlengstorf marked this conversation as resolved.
Show resolved Hide resolved
this.observerTargets = Array.from(
document.querySelectorAll(`.featuredItems`)
)

this.observerTargets.forEach(target => this.observer.observe(target))
}

handleIntersect = (entries, observer) => {
entries.forEach(entry => {
const target = entry.target

if (entry.intersectionRatio > 0) {
setTimeout(
() => this.turnOnLeadScroll({ target, duration: 1000, distance: 20 }),
250
)
this.observer.unobserve(target)
}
})
}

turnOnLeadScroll = ({ target, duration, distance }) => {
let startTime = null

function animation(currentTime) {
if (startTime === null) {
startTime = currentTime
}

const timeElapsed = currentTime - startTime
const getDistanceToScroll = ease(timeElapsed, 0, distance, duration)

target.scroll({ top: 0, left: getDistanceToScroll })

if (timeElapsed < duration) {
requestAnimationFrame(animation)
}
}

function ease(t, b, c, d) {
return -c * (t /= d) * (t - 2) + b
}

requestAnimationFrame(animation)
}

render() {
const {
icons: { plugins: PluginsIcon, starters: StartersIcon },
starters,
plugins,
} = this.props

return (
<EcosystemBoardRoot>
<EcosystemSection
title="Plugins"
description="Plugins are packages that extend Gatsby sites. They can source content, transform data, and more!"
subTitle="Featured Plugins"
icon={PluginsIcon}
links={[
{ label: `Browse Plugins`, to: `/plugins/` },
{
label: `Plugin Authoring`,
to: `/docs/plugin-authoring/`,
secondary: true,
},
{ label: `Plugin Docs`, to: `/docs/plugins/`, secondary: true },
]}
featuredItems={plugins}
/>
<EcosystemSection
title="Starters"
description="Starters are Gatsby sites that are preconfigured for different use cases to give you a head start for your project."
subTitle="Featured Starters"
icon={StartersIcon}
links={[
{ label: `Browse Starters`, to: `/starters/` },
{ label: `Starter Docs`, to: `/docs/starters/`, secondary: true },
]}
featuredItems={starters}
/>
<EcosystemSection
title="External Resources"
description="A curated list of interesting Gatsby community projects and learning resources like podcasts and tutorials."
links={[{ label: `Browse Resources`, to: `/docs/awesome-gatsby/` }]}
/>
</EcosystemBoardRoot>
)
}
}

EcosystemBoard.propTypes = {
icons: PropTypes.object,
Expand Down
3 changes: 2 additions & 1 deletion www/src/components/ecosystem/ecosystem-featured-items.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { scrollbarStyles } from "../../utils/styles"
const EcosystemFeaturedItemsRoot = styled(`div`)`
overflow-x: scroll;
margin: ${rhythm(0.1)} -${rhythm(options.blockMarginBottom)};
-webkit-overflow-scrolling: touch;

${presets.Tablet} {
border-top: 1px solid ${colors.gray.superLight};
Expand All @@ -37,7 +38,7 @@ const List = styled(`ul`)`
`

const EcosystemFeaturedItems = ({ items }) => (
<EcosystemFeaturedItemsRoot>
<EcosystemFeaturedItemsRoot className="featuredItems">
<List numberOfItems={items.length}>
{items.map(item => {
const { slug } = item
Expand Down