Commit 94aa0dd1 authored by alain's avatar alain 🐙
Browse files

navigation styling and more layout stuff

parent 0e66e4de
......@@ -47,13 +47,13 @@ module.exports = {
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-starter-default`,
short_name: `starter`,
name: `Public Stack Site`,
short_name: `public-stack`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
background_color: `#FFFFFF`,
theme_color: `#2cbdbc`,
display: `minimal-ui`,
//icon: ``, // This path is relative to the root of the site.
icon: `src/images/icon.png`, // This path is relative to the root of the site.
},
},
// this (optional) plugin enables Progressive Web App + Offline functionality
......
......@@ -4,29 +4,25 @@
* See: https://www.gatsbyjs.org/docs/node-apis/
*/
// You can delete this file if you're not using it
const path = require(`path`);
const makeRequest = (graphql, request) => new Promise((resolve, reject) => {
// Query for nodes to use in creating pages.
resolve(
graphql(request).then(result => {
if (result.errors) {
reject(result.errors)
}
return result;
})
)
});
// Implement the Gatsby API “createPages”. This is called once the
// data layer is bootstrapped to let plugins create pages from data.
exports.createPages = ({ actions, graphql }) => {
const { createPage } = actions;
const getDomains = makeRequest(graphql, `
{
allStrapiDomain {
......@@ -37,9 +33,15 @@ exports.createPages = ({ actions, graphql }) => {
}
}
}
allStrapiUseCase {
edges {
node {
id
}
}
}
}
`).then(result => {
// Create pages for each article.
`).then(result => {
result.data.allStrapiDomain.edges.forEach(({ node }) => {
createPage({
path: `/domain/${node.slug}`,
......@@ -49,8 +51,18 @@ exports.createPages = ({ actions, graphql }) => {
},
})
})
result.data.allStrapiUseCase.edges.forEach(({ node }) => {
createPage({
path: `/use-case/${node.id}`,
component: path.resolve(`src/templates/use-case.js`),
context: {
id: node.id,
},
})
})
});
// Query for articles nodes to use in creating pages.
return getDomains;
};
\ No newline at end of file
import { Link, StaticQuery, graphql } from "gatsby"
import React, { useRef, useEffect, useState } from "react"
import PropTypes from "prop-types"
import React from "react"
const Header = ({ siteTitle }) => (
<StaticQuery query={graphql`
query MenuQuery {
strapiHeader {
title
subtitle
primary_navigation {
id
import { Link, StaticQuery, graphql } from "gatsby"
import gsap, { Power1 } from 'gsap';
//import { ScrollTrigger } from "gsap/ScrollTrigger";
const Header = () => {
const [nav, setNav] = useState(false);
let header = useRef(null)
useEffect(()=> {
const headerTimeline = gsap.timeline({
scrollTrigger: {
trigger: "body",
start: "100px top",
end: "bottom top",
toggleActions: "play pause reverse reset",
toggleClass: {
targets: header,
className: "scrolled"
},
//markers: true,
//scrub: 0.25
},
ease: Power1.easeInOut
});
headerTimeline.to(header, { opacity: 1 })
})
return (
<StaticQuery query={graphql`
query MenuQuery {
strapiHeader {
title
subtitle
link
}
secondary_navigation {
id
title
# subtitle
link
primary_navigation {
id
title
subtitle
link
}
secondary_navigation {
id
title
# subtitle
link
}
}
}
}
`} render={ data =>
<header>
<nav className="menu-container">
<input type="checkbox" aria-label="Toggle menu" />
<span className="hamburger-bar"></span>
<span className="hamburger-bar"></span>
<span className="hamburger-bar"></span>
`} render={ data =>
<header id="site-header" className={ nav ? "nav-active" : null } ref={el => header = el} >
<div id="site-header-bg"/>
<div id="site-titles">
<h1 id="site-title"><Link to="/" >{ data.strapiHeader.title }</Link></h1>
{/* <h2 id="site-subtitle">{ data.strapiHeader.subtitle }</h2> */}
</div>
<ul className="menu">
{ data.strapiHeader.primary_navigation.map(item => <li key={item.id} className="primary"><Link to={item.link}>
<span className="menu-item-title">{item.title}</span>
{item.subtitle && <span className="menu-item-subtitle">{item.subtitle}</span> }
</Link></li>) }
{ data.strapiHeader.secondary_navigation.map(item => <li key={item.id} className="secondary"><Link to={item.link}>
<span className="menu-item-title">{item.title}</span>
{item.subtitle && <span className="menu-item-subtitle">{item.subtitle}</span> }
</Link></li>) }
</ul>
</nav>
</header>
} />
)
<nav id="nav-container">
<input type="checkbox" aria-label="toggle menu" checked={nav} onChange={() => setNav(!nav)} />
<span className="hamburger-bar"></span>
<span className="hamburger-bar"></span>
<span className="hamburger-bar"></span>
<ul id="nav">
{ data.strapiHeader.primary_navigation.map(item => <li key={item.id} className="primary"><Link to={item.link}>
<div className="nav-item-title">{item.title}</div>
{item.subtitle && <div className="nav-item-subtitle">{item.subtitle}</div> }
</Link></li>) }
{ data.strapiHeader.secondary_navigation.map(item => <li key={item.id} className="secondary"><Link to={item.link}>
<div className="nav-item-title">{item.title}</div>
{item.subtitle && <div className="nav-item-subtitle">{item.subtitle}</div> }
</Link></li>) }
</ul>
</nav>
</header>
} />
)
}
Header.propTypes = {
siteTitle: PropTypes.string,
......
......@@ -8,7 +8,7 @@ import Header from "./header"
import Footer from "./footer"
import Blob from "../images/blob.svg"
const Layout = ({ children }) => {
const Layout = ({ children, id }) => {
const data = useStaticQuery(graphql`
query SiteTitleQuery {
site {
......@@ -20,7 +20,7 @@ const Layout = ({ children }) => {
`)
return (
<div id="page">
<div id={id} className="page">
<Blob id="blob" />
<Header siteTitle={data.site.siteMetadata.title} />
<main>{children}</main>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,7 @@ import SEO from "../components/seo"
const AboutPage = ({ data }) => (
<Layout>
<SEO title="About" />
<h1>{ data.strapiAbout.title }</h1>
<h1 className="page-title">{ data.strapiAbout.title }</h1>
<section>
{ data.strapiAbout.rows.map(row =>
<div key={row.id} className={ `row columns-${row.columns.length}` }>
......
......@@ -6,14 +6,14 @@ import Layout from "../components/layout"
import SEO from "../components/seo"
const AlternativesPage = ({ data }) => (
<Layout>
<Layout id="page-alternatives">
<SEO title="Alternatives" />
<h1>Alternatives</h1>
<h1 className="page-title">Alternatives</h1>
<div className="items">
{ data.allStrapiAlternative.nodes.map(node => (
<div key={node.id} className="item">
<h3>{ node.title }</h3>
{ node.logo && <Img fluid={ node.logo.childImageSharp.fluid } fadeIn={false} /> }
{ node.logo && <Img className="logo" fluid={ node.logo.childImageSharp.fluid } fadeIn={false} /> }
{ node.domains && <ul>{node.domains.map(domain => <li key={domain.id}>{ domain.title}</li>) }</ul> }
{/* <p>{ node.description }</p> */}
</div>
......
......@@ -7,12 +7,13 @@ import SEO from "../components/seo"
const DomainsPage = ({ data }) => (
<Layout>
<SEO title="Domains" />
<h1>Domains</h1>
<h1 className="page-title">Domains</h1>
<div className="items">
{ data.allStrapiDomain.nodes.map(node => (
<Link to={`/domain/${node.slug}`} key={node.id} className="item">
<h3>{ node.title }</h3>
<p dangerouslySetInnerHTML={{ __html: node.description }} />
{ node.order }
</Link>
)) }
</div>
......@@ -23,7 +24,7 @@ export default DomainsPage
export const pageQuery = graphql`
query DomainQuery {
allStrapiDomain {
allStrapiDomain(sort: {fields: order}) {
nodes {
id
slug
......
......@@ -7,25 +7,40 @@ import { ScrollTrigger } from "gsap/ScrollTrigger";
import Layout from "../components/layout"
import SEO from "../components/seo"
import VisualPhone from "../images/phone.js"
import Toaster from "../images/toaster.svg"
import Phone from "../images/phone.svg"
gsap.registerPlugin(MotionPathPlugin, ScrollTrigger);
const IndexPage = ({ data }) => {
let phone = useRef(null);
let phonePin = useRef(null);
let phoneTrigger = useRef(null);
//let toaster = useRef(null)
let phone = useRef(null)
let phoneTrigger = useRef(null)
useEffect(()=> {
const tl = gsap.timeline({
// TOASTER ANIMATION
// const tlToaster = gsap.timeline().repeat(-1)
// tlToaster.to(toaster.querySelectorAll("#toaster"), {
// motionPath: {
// path: "M3.05,15.07C14.5-13.25,24.6,4.94,52.92,16.39S107.48,20.74,96,49.06,70.7,98.47,42.39,87-8.4,43.38,3.05,15.07Z",
// curviness: 3
// },
// duration: 42,
// ease: "rough"
// })
// PHONE ANIMATION
const phoneTimeline = gsap.timeline({
scrollTrigger: {
trigger: phoneTrigger,
start: "0px top",
end: "bottom 75%",
start: "-66px top",
end: "bottom 87%",
toggleActions: "play pause reverse reset",
//markers: true,
scrub: 0.25,
pin: phonePin,
pin: phone,
},
ease: Power1.easeInOut
});
......@@ -35,68 +50,69 @@ const IndexPage = ({ data }) => {
2
]
tl.to(phone.querySelectorAll("#buttons"), { y: -300 }, keyframes[0])
.to(phone.querySelectorAll("#screen"), { y: -200 }, keyframes[0])
.to(phone.querySelectorAll("#front"), { y: -100 }, keyframes[0])
.to(phone.querySelectorAll("#capital"), { y: 150 }, keyframes[0])
.to(phone.querySelectorAll("#society"), { y: 400 }, keyframes[0])
phoneTimeline.to(phone.querySelectorAll("#buttons"), { y: -300 }, keyframes[0])
phoneTimeline.to(phone.querySelectorAll("#screen"), { y: -200 }, keyframes[0])
phoneTimeline.to(phone.querySelectorAll("#front"), { y: -100 }, keyframes[0])
phoneTimeline.to(phone.querySelectorAll("#capital"), { y: 150 }, keyframes[0])
phoneTimeline.to(phone.querySelectorAll("#society"), { y: 400 }, keyframes[0])
.to(phone.querySelectorAll("#digits-bg"), { opacity: 1 }, keyframes[0])
.to(phone.querySelectorAll("#capital-bg"), { opacity: 1 }, keyframes[0])
.to(phone.querySelectorAll("#society-bg"), { opacity: 1 }, keyframes[0])
phoneTimeline.to(phone.querySelectorAll("#digits-bg"), { opacity: 1 }, keyframes[0])
phoneTimeline.to(phone.querySelectorAll("#capital-bg"), { opacity: 1 }, keyframes[0])
phoneTimeline.to(phone.querySelectorAll("#society-bg"), { opacity: 1 }, keyframes[0])
phoneTimeline.to(phone.querySelectorAll("#digits-content"), { opacity: 1 }, keyframes[1])
phoneTimeline.to(phone.querySelectorAll("#capital-content"), { opacity: 1 }, keyframes[1])
phoneTimeline.to(phone.querySelectorAll("#society-content"), { opacity: 1 }, keyframes[1])
tl.to(phone.querySelectorAll("#digits-content"), { opacity: 1 }, keyframes[1])
.to(phone.querySelectorAll("#capital-content"), { opacity: 1 }, keyframes[1])
.to(phone.querySelectorAll("#society-content"), { opacity: 1 }, keyframes[1])
// motionPath: {
// path: [
// {x: 0, y: 0},
// {x: 100, y: 0},
// {x: 0, y: 0},
// ]
// },
})
return (
<Layout>
<SEO title="Home" />
<section>
<section id="front-introduction">
<div className="row columns-2">
<div className="column" dangerouslySetInnerHTML={{__html: data.strapiHome.introduction }} />
<div className="column">[broodrooster]</div>
<div className="column v-center" dangerouslySetInnerHTML={{__html: data.strapiHome.introduction }} />
<div className="column v-center">
{/* <div ref={el => toaster = el}> */}
<Toaster />
{/* </div> */}
</div>
</div>
</section>
<section style={{background: "#F8F8F8"}} >
<section id="front-layer-explanation" style={{background: "#F8F8F8"}} >
<div className="row columns-2">
<div className="column">
<div ref={el => phonePin = el}><div ref={el => phone = el}>
<VisualPhone />
</div></div>
<div className="column" ref={el => phone = el}>
<Phone />
</div>
<div className="column" ref={el => phoneTrigger = el}>
<div className="phone-part" dangerouslySetInnerHTML={{__html: data.strapiHome.layer_explanation_1 }}></div>
<div className="phone-part" dangerouslySetInnerHTML={{__html: data.strapiHome.layer_explanation_2 }}></div>
<div className="phone-part" dangerouslySetInnerHTML={{__html: data.strapiHome.layer_explanation_3 }}></div>
<div className="phone-part v-center" dangerouslySetInnerHTML={{__html: data.strapiHome.layer_explanation_1 }}></div>
<div className="phone-part v-center" dangerouslySetInnerHTML={{__html: data.strapiHome.layer_explanation_2 }}></div>
<div className="phone-part v-center" dangerouslySetInnerHTML={{__html: data.strapiHome.layer_explanation_3 }}></div>
</div>
</div>
</section>
<section>
<section id="front-introduction-2">
<div dangerouslySetInnerHTML={{__html: data.strapiHome.layer_explanation_4 }}></div>
</section>
<section>
<div dangerouslySetInnerHTML={{__html: data.strapiHome.three_stacks_1 }}></div>
<section id="front-stacks">
<div className="row columns-2">
<div className="columns" dangerouslySetInnerHTML={{__html: data.strapiHome.three_stacks_1 }}></div>
</div>
</section>
<section>
<div dangerouslySetInnerHTML={{__html: data.strapiHome.three_stacks_2 }}></div>
<div className="row columns-2">
<div className="columns" dangerouslySetInnerHTML={{__html: data.strapiHome.three_stacks_2 }}></div>
</div>
</section>
<section>
<div dangerouslySetInnerHTML={{__html: data.strapiHome.three_stacks_3 }}></div>
<div className="row columns-2">
<div className="columns" dangerouslySetInnerHTML={{__html: data.strapiHome.three_stacks_3 }}></div>
</div>
</section>
</Layout>
)
......
......@@ -7,7 +7,7 @@ import SEO from "../components/seo"
const UseCasesPage = ({ data }) => (
<Layout>
<SEO title="Use Cases" />
<h1>Use Cases</h1>
<h1 className="page-title">Use Cases</h1>
<div className="items">
{ data.allStrapiUseCase.nodes.map(node => (
<div key={node.id} className="item">
......
.menu-container {
position: relative;
#site-header {
position: fixed;
display: flex;
align-items: flex-end;
margin-bottom: 20px;
//background: #fff;
justify-content: space-between;
align-items: flex-start;
width: 100vw;
color: #000;
padding: 20px;
padding: 1rem;
z-index: 1;
-webkit-user-select: none;
user-select: none;
box-sizing: border-box;
font-weight: 500;
#site-header-bg {
position: absolute;
top: 0%;
left: 0;
width: 100%;
height: 100%;
background-color: #FFF;
z-index: -1;
transform: translateY(-111%);
box-shadow: 0 0 0.5rem 0 rgba(0, 0, 0, 0.2);
transition: all 100ms ease;
}
&.scrolled:not(.nav-active) #site-header-bg {
transform: translateY(0%);
}
a {
display: block;
text-decoration: none;
text-transform: lowercase;
color: #000;
}
}
#site-titles {
......@@ -19,159 +41,173 @@
font-family: waax;
font-weight: 400;
font-size: 44px;
margin: 10px 0;
white-space: nowrap;
}
#site-subtitle {
font-size: 20px;
max-width: 11em;
font-weight: 400;
margin: 0;
}
}
.menu-container a {
display: block;
text-decoration: none;
color: #000;
transition: color 0.1s ease;
text-transform: lowercase;
&:hover {
color: #2FB6BC;
}
line-height: 1em;
white-space: nowrap;
transition: all 100ms ease;
a:hover {
text-decoration: underline;
}
.scrolled & {
font-size: 32px;
}
.nav-active & {
opacity: 0;
}
}
// #site-subtitle {
// font-size: 20px;
// max-width: 11em;
// font-weight: 400;
// margin: 0;
// }
}
.menu-container input {
display: block;
width: 30px;
height: 30px;
right: 10px;
top: 10px;
margin: 0;
position: absolute;
cursor: pointer;
opacity: 0; /* hide this */
z-index: 2; /* and place it over the hamburger */
-webkit-touch-callout: none;
#nav {
margin: 0;;
}
.menu-container .hamburger-bar {
display: block;
width: 14px;
height: 2px;
margin-bottom: 2px;
#nav-container {
position: relative;
background: #000;
border-radius: 2px;
z-index: 1;
transform-origin: 3px 0px;
transition: all 0.1s ease;
}
.menu-container .hamburger-bar:first-child { transform-origin: 0% 0%; }
.menu-container .hamburger-bar:nth-child(3) { transform-origin: 0% 100%; }
input {
position: absolute;
top: -0.6rem;