index black and white in SSR and fades to color
This commit is contained in:
parent
6a787f6c08
commit
932535840f
@ -5,10 +5,11 @@ export const HeroA = ({
|
|||||||
href,
|
href,
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
|
isClient,
|
||||||
...linkProps
|
...linkProps
|
||||||
}) => (
|
}) => (
|
||||||
<a
|
<a
|
||||||
className={classnames('text-muted-light mx-1 hover:text-vibrant-light underline', className)}
|
className={classnames('mx-1 underline', isClient && 'text-muted-light hover:text-vibrant-light', className)}
|
||||||
href={href}
|
href={href}
|
||||||
{...linkProps}
|
{...linkProps}
|
||||||
>{children}</a>
|
>{children}</a>
|
||||||
|
@ -4,16 +4,28 @@ import { GatsbyImage, getImage } from 'gatsby-plugin-image';
|
|||||||
import { getVibrantToHelmetSafeBodyStyle, getVibrant } from '../utils';
|
import { getVibrantToHelmetSafeBodyStyle, getVibrant } from '../utils';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import { HeroA } from '../components/IndexComponents';
|
import { HeroA } from '../components/IndexComponents';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
const IndexPage = ({ data }) => {
|
const IndexPage = ({ data: { allFile: { edges } } }) => {
|
||||||
const images = data.allFile.edges.map((edge) => edge.node);
|
const [isClient, setIsClient] = React.useState(false);
|
||||||
const image = React.useRef(images[Math.floor(Math.random() * images.length)]).current;
|
const images = React.useMemo(() => edges.map((edge) => edge.node), [edges]);
|
||||||
const vibrant = getVibrant(image);
|
const image = React.useMemo(() => {
|
||||||
console.log('image', image);
|
if (!isClient) {
|
||||||
|
return images[0];
|
||||||
|
}
|
||||||
|
return images[Math.floor(Math.random() * images.length)];
|
||||||
|
}, [images, isClient]);
|
||||||
|
const vibrant = getVibrant(image, isClient);
|
||||||
|
console.log('vibrant', vibrant);
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!isClient) {
|
||||||
|
setIsClient(true);
|
||||||
|
}
|
||||||
|
}, [isClient]);
|
||||||
return (<>
|
return (<>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<body
|
<body
|
||||||
className="bg-vibrant-dark"
|
className={classnames(isClient ? 'bg-vibrant-dark' : '')}
|
||||||
style={getVibrantToHelmetSafeBodyStyle(vibrant)}
|
style={getVibrantToHelmetSafeBodyStyle(vibrant)}
|
||||||
/>
|
/>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
@ -22,34 +34,46 @@ const IndexPage = ({ data }) => {
|
|||||||
>
|
>
|
||||||
<GatsbyImage
|
<GatsbyImage
|
||||||
alt=""
|
alt=""
|
||||||
className="sm:h-auto lg:h-screen hero-img"
|
className={classnames(
|
||||||
|
'lg:h-screen hero-img sm:h-auto',
|
||||||
|
// isClient ? 'sm:h-auto' : 'sm:h-2'
|
||||||
|
)}
|
||||||
image={getImage(image)}
|
image={getImage(image)}
|
||||||
key={image.base}
|
key={image.base}
|
||||||
loading="eager"
|
loading="eager"
|
||||||
style={{
|
style={{
|
||||||
gridArea: '1/1',
|
gridArea: '1/1',
|
||||||
|
// hide for SSR pass so it doesn't flash in then get replaced when we pick a new random one
|
||||||
|
// TODO: replace image with empty div for SSR so we don't always load duck image
|
||||||
|
// TODO: hardcode height on mobile for empty div
|
||||||
|
visibility: isClient ? 'visible' : 'hidden',
|
||||||
}} />
|
}} />
|
||||||
<div className="relative grid place-items-center" style={{gridArea: '1/1'}}>
|
<div className="relative grid place-items-center" style={{gridArea: '1/1'}}>
|
||||||
<div className="m-2 flex flex-col items-end">
|
<div className="m-2 flex flex-col items-end">
|
||||||
<section className="rounded-xl py-6 bg-vibrant-dark-75">
|
<section className={classnames('rounded-xl py-6', isClient && ' bg-vibrant-dark-75')}>
|
||||||
<div className="mx-auto px-6">
|
<div className="mx-auto px-6">
|
||||||
<h1 className="text-vibrant-light font-black text-6xl">Chuck Dries</h1>
|
<h1 className={classnames('font-black text-6xl', isClient && 'text-vibrant-light')}>Chuck Dries</h1>
|
||||||
<h2 className="text-vibrant italic text-2xl" >Full stack software engineer & hobbyist photographer</h2>
|
<h2 className={classnames('italic text-2xl', isClient && 'text-vibrant')}>Full stack software engineer & hobbyist photographer</h2>
|
||||||
<ul className="text-muted-light">
|
<ul className={classnames(isClient && 'text-muted-light')}>
|
||||||
<li>Software Developer, <span className="italic">Axosoft</span></li>
|
<li>Software Developer, <span className="italic">Axosoft</span></li>
|
||||||
<li><HeroA className="ml-0" href="mailto:chuck@chuckdries.com">chuck@chuckdries.com</HeroA>/<span className="ml-1">602.618.0414</span></li>
|
<li><HeroA className="ml-0" href="mailto:chuck@chuckdries.com" isClient={isClient}>chuck@chuckdries.com</HeroA>/<span className="ml-1">602.618.0414</span></li>
|
||||||
<li>
|
<li>
|
||||||
<HeroA className="ml-0" href="http://github.com/chuckdries">Github</HeroA>/
|
<HeroA className="ml-0" href="http://github.com/chuckdries" isClient={isClient}>Github</HeroA>/
|
||||||
<HeroA href="https://www.linkedin.com/in/chuckdries/">LinkedIn</HeroA>/
|
<HeroA href="https://www.linkedin.com/in/chuckdries/" isClient={isClient}>LinkedIn</HeroA>/
|
||||||
<HeroA href="https://devpost.com/chuckdries">Devpost</HeroA>/
|
<HeroA href="https://devpost.com/chuckdries" isClient={isClient}>Devpost</HeroA>/
|
||||||
<HeroA href="CharlesDriesResumeCurrent.pdf">Resume [pdf]</HeroA>/
|
<HeroA href="CharlesDriesResumeCurrent.pdf" isClient={isClient}>Resume [pdf]</HeroA>/
|
||||||
<HeroA href="https://medium.com/@chuckdries">Medium (blog)</HeroA>
|
<HeroA href="https://medium.com/@chuckdries" isClient={isClient}>Medium (blog)</HeroA>
|
||||||
{/* <a href="https://pgp.mit.edu/pks/lookup?op=get&search=0x2BD9D0871DB5A518">Public Key</a> */}
|
{/* <a href="https://pgp.mit.edu/pks/lookup?op=get&search=0x2BD9D0871DB5A518">Public Key</a> */}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<Link className="text-muted-dark bg-muted-light border-muted-light hover:underline font-sans inline-block p-3 my-2 rounded-md border-2 arrow-after font-bold" to="/photogallery">
|
<Link
|
||||||
|
className={classnames(
|
||||||
|
'hover:underline font-sans inline-block p-3 my-2 rounded-md border-2 arrow-after font-bold',
|
||||||
|
isClient && 'text-muted-dark bg-muted-light border-muted-light')}
|
||||||
|
to="/photogallery"
|
||||||
|
>
|
||||||
Photography</Link>
|
Photography</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -63,7 +87,7 @@ export const query = graphql`
|
|||||||
allFile(
|
allFile(
|
||||||
filter: {
|
filter: {
|
||||||
sourceInstanceName: {eq: "gallery"},
|
sourceInstanceName: {eq: "gallery"},
|
||||||
base: {nin: ["DSC01699.jpg", "DSC02981.jpg", "_DSC4155.jpg"]}
|
base: {nin: ["DSC01699.jpg", "DSC02981.jpg", "_DSC4155.jpg", "DSC02538.jpg", "DSC05851.jpg"]}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
edges {
|
edges {
|
||||||
@ -74,8 +98,8 @@ export const query = graphql`
|
|||||||
gatsbyImageData(
|
gatsbyImageData(
|
||||||
layout: FULL_WIDTH
|
layout: FULL_WIDTH
|
||||||
# placeholder: BLURRED
|
# placeholder: BLURRED
|
||||||
placeholder: TRACED_SVG
|
# placeholder: TRACED_SVG
|
||||||
# placeholder: NONE
|
placeholder: NONE
|
||||||
# blurredOptions: {width: 50}
|
# blurredOptions: {width: 50}
|
||||||
breakpoints: [750, 1080, 1366, 1920, 2560]
|
breakpoints: [750, 1080, 1366, 1920, 2560]
|
||||||
)
|
)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
transition: color .2s, background .2s;
|
||||||
}
|
}
|
||||||
@layer utilities {
|
@layer utilities {
|
||||||
.scroll-snap-none {
|
.scroll-snap-none {
|
||||||
|
@ -4,7 +4,15 @@ export const getMeta = (image) => image.childImageSharp.fields.imageMeta;
|
|||||||
|
|
||||||
export const getName = (image) => getMeta(image)?.iptc.object_name || image.base;
|
export const getName = (image) => getMeta(image)?.iptc.object_name || image.base;
|
||||||
|
|
||||||
export const getVibrant = (image) => getMeta(image)?.vibrant;
|
// some pleasing default colors for SSR and initial hydration
|
||||||
|
export const getVibrant = (image, isClient) => isClient ? getMeta(image)?.vibrant : {
|
||||||
|
'DarkMuted': [ 63, 64, 73 ],
|
||||||
|
'DarkVibrant': [ 52, 75, 116 ],
|
||||||
|
'LightMuted': [ 211, 194, 181 ],
|
||||||
|
'LightVibrant': [ 224, 183, 140 ],
|
||||||
|
'Muted': [ 155, 123, 114 ],
|
||||||
|
'Vibrant': [ 226, 116, 81 ],
|
||||||
|
};
|
||||||
|
|
||||||
export const hasName = (image) => Boolean(getMeta(image)?.iptc.object_name);
|
export const hasName = (image) => Boolean(getMeta(image)?.iptc.object_name);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user