index black and white in SSR and fades to color

This commit is contained in:
Chuck Dries 2021-06-16 21:23:22 -07:00
parent 6a787f6c08
commit 932535840f
4 changed files with 57 additions and 23 deletions

View File

@ -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>

View File

@ -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 &amp; hobbyist photographer</h2> <h2 className={classnames('italic text-2xl', isClient && 'text-vibrant')}>Full stack software engineer &amp; 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]
) )

View File

@ -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 {

View File

@ -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);