pick colors from images at build time, query and use for tailwind classes in react

This commit is contained in:
Chuck Dries
2021-06-16 18:42:45 -07:00
parent 2cea7d737a
commit d2943105f8
15 changed files with 410 additions and 53 deletions

View File

@@ -26,21 +26,21 @@ const GalleryImage = ({ data }) => {
</Helmet>
<div className="min-h-screen flex flex-col justify-center">
{/* TODO: change layout by amount of empty space on side of page, not aspect ratio? */}
<div style={{ margin: '0 5vw' }} className={classnames('flex mx-auto', ar > 1 ? 'flex-col' : 'flex-row-reverse')}>
<div className='flex-grow-0'>
<div className={classnames('flex mx-auto', ar > 1 ? 'flex-col' : 'flex-row-reverse')} style={{ margin: '0 5vw' }}>
<div className="flex-grow-0">
<GatsbyImage
alt={name}
className=""
loading='eager'
objectFit='contain'
image={getImage(image)}
key={image.base}
loading="eager"
objectFit="contain"
style={{
maxWidth: `calc(max(90vh, 500px) * ${ar})`,
// height: '90vh',
maxHeight: '90vh',
minHeight: '500px',
}}
key={image.base}
image={getImage(image)}
alt={name} />
}} />
</div>
<div className={classnames('flex-shrink-0 mr-4', ar <= 1 && 'pt-4 flex-auto text-right')}>
{hasName(image) && <h1 className="text-2xl mt-2">{name}</h1>}
@@ -57,7 +57,6 @@ export const query = graphql`
allFile(filter: {sourceInstanceName: {eq: "gallery"}, base: {eq: $imageFilename}}) {
edges {
node {
relativePath
base
childImageSharp{
fluid {

View File

@@ -0,0 +1,15 @@
import * as React from 'react';
import classnames from 'classnames';
export const HeroA = ({
href,
children,
className,
...linkProps
}) => (
<a
className={classnames('text-muted-light mx-1 hover:text-vibrant-light underline', className)}
href={href}
{...linkProps}
>{children}</a>
);

View File

@@ -32,7 +32,7 @@ const MasonryGallery = ({ images, itemsPerRow: itemsPerRowByBreakpoint }) => {
return (
<div
className='w-full'
className="w-full"
style={{
position: 'relative',
}}
@@ -53,20 +53,20 @@ const MasonryGallery = ({ images, itemsPerRow: itemsPerRowByBreakpoint }) => {
}
return (
<Link
className="inline-block"
key={`${image.base}`}
className='inline-block'
state={{modal: true}}
style={{
width,
// marginLeft: '8px',
}}
state={{modal: true}} to={`/photogallery/${image.base}`}
}} to={`/photogallery/${image.base}`}
>
<GatsbyImage
className='w-full'
objectFit='cover'
alt={getName(image)}
className="w-full"
// style={{ width }}
image={getImage(image)}
alt={getName(image)}
objectFit="cover"
/>
</Link>
);

View File

@@ -32,7 +32,7 @@ const NotFoundPage = () => {
<h1 style={headingStyles}>Page not found</h1>
<p style={paragraphStyles}>
Sorry{' '}
<span role="img" aria-label="Pensive emoji">
<span aria-label="Pensive emoji" role="img">
😔
</span>{' '}
we couldnt find what you were looking for.

View File

@@ -1,50 +1,106 @@
import * as React from 'react';
import { Link } from 'gatsby';
import { StaticImage } from 'gatsby-plugin-image';
import { Link, graphql } from 'gatsby';
import { GatsbyImage, getImage } from 'gatsby-plugin-image';
import { getVibrantToHelmetSafeBodyStyle, getVibrant } from '../utils';
import { Helmet } from 'react-helmet';
import { HeroA } from '../components/IndexComponents';
const IndexPage = () => {
return (
<main className="font-serif sm:block lg:grid">
<StaticImage
const IndexPage = ({ data }) => {
const images = data.allFile.edges.map((edge) => edge.node);
const [palette, setPalette] = React.useState([
[0, 0, 0],
[254, 254, 254],
[200, 200, 200],
[200, 200, 200],
[180, 180, 180],
]);
const image = React.useRef(images[Math.floor(Math.random() * images.length)]).current;
const vibrant = getVibrant(image);
console.log('vibrant', getVibrant(image));
return (<>
<Helmet>
<body
className="bg-vibrant-dark"
style={getVibrantToHelmetSafeBodyStyle(vibrant)}
/>
</Helmet>
<main
className="font-serif sm:block lg:grid"
>
<GatsbyImage
alt=""
className="sm:h-auto lg:h-screen hero-img"
image={getImage(image)}
loading="eager"
style={{
gridArea: '1/1',
// maxHeight: '90vh',
// height: '100vh',
}}
className='sm:h-auto lg:h-screen'
layout='fullWidth'
alt=''
src='../../data/gallery/DSC4180.jpg'
/>
<div className='relative grid place-items-center' style={{gridArea: '1/1'}}>
<div
className="m-2 flex flex-col items-end"
>
{/* TODO: color thief and fonts */}
<section className='bg-green-200 bg-opacity-80 rounded-xl py-6'>
}} />
<div className="relative grid place-items-center" style={{gridArea: '1/1'}}>
<div className="m-2 flex flex-col items-end">
<section className="rounded-xl py-6 bg-vibrant-dark-75">
<div className="mx-auto px-6">
<h1 className="italic font-normal text-5xl ">Chuck Dries</h1>
<h2 className="italic text-blue-300 text-2xl">Full stack software engineer &amp; hobbyist photographer</h2>
<ul>
<li>Software Developer, <span className="text-gray-800 italic">Axosoft</span></li>
<li><a className="hover:text-pink-400 underline" href="mailto:chuck@chuckdries.com">chuck@chuckdries.com</a> / <span>602.618.0414</span></li>
<h1 className="text-vibrant-light font-black text-6xl">Chuck Dries</h1>
<h2 className="text-vibrant italic text-2xl" >Full stack software engineer &amp; hobbyist photographer</h2>
<ul className="text-muted-light">
<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>
<a className="mr-1 hover:text-pink-400 underline" href="http://github.com/chuckdries">Github</a>/
<a className="mx-1 hover:text-pink-400 underline" href="https://www.linkedin.com/in/chuckdries/">LinkedIn</a>/
<a className="mx-1 hover:text-pink-400 underline" href="https://devpost.com/chuckdries">Devpost</a>/
<a className="mx-1 hover:text-pink-400 underline" href="CharlesDriesResumeCurrent.pdf">Resume [pdf]</a>/
<a className="mx-1 hover:text-pink-400 underline" href="https://medium.com/@chuckdries">Medium (blog)</a>
<HeroA className="ml-0" href="http://github.com/chuckdries">Github</HeroA>/
<HeroA href="https://www.linkedin.com/in/chuckdries/">LinkedIn</HeroA>/
<HeroA href="https://devpost.com/chuckdries">Devpost</HeroA>/
<HeroA href="CharlesDriesResumeCurrent.pdf">Resume [pdf]</HeroA>/
<HeroA href="https://medium.com/@chuckdries">Medium (blog)</HeroA>
{/* <a href="https://pgp.mit.edu/pks/lookup?op=get&search=0x2BD9D0871DB5A518">Public Key</a> */}
</li>
</ul>
</div>
</section>
<Link className='text-black hover:underline font-sans inline-block p-3 my-2 rounded-md bg-gray-300 border-2 arrow-after font-bold border-gray-400' to='/photogallery'>
<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">
Photography</Link>
</div>
</div>
<div id="asdf" style={{ display: 'block'}}></div>
</main>
);
</>);
};
export const query = graphql`
{
allFile(
filter: {
sourceInstanceName: {eq: "gallery"},
base: {in: ["DSC00201.jpg", "DSC05851.jpg", "DSC4180.jpg", "DSC08521.jpg", "DSC06245.jpg", "_DSC4949.jpg"]}
}
) {
edges {
node {
relativePath
base
childImageSharp {
gatsbyImageData(
layout: FULL_WIDTH
# placeholder: BLURRED
placeholder: NONE
# blurredOptions: {width: 200}
breakpoints: [750, 1080, 1366, 1920, 2560, 3840]
)
fields {
imageMeta {
vibrant {
DarkMuted
DarkVibrant
LightMuted
LightVibrant
Muted
Vibrant
}
}
}
}
}
}
}
}
`;
export default IndexPage;

View File

@@ -1,4 +1,6 @@
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital@0;1&display=swap');
/* @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital@0;1&display=swap'); */
/* black, bold, regular */
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&display=swap');
@tailwind base;
@tailwind components;

View File

@@ -0,0 +1,3 @@
/* main.hero {
} */

View File

@@ -1,7 +1,28 @@
// import kebabCase from 'lodash/kebabCase';
export const getMeta = (image) => image.childImageSharp.fields.imageMeta;
export const getName = (image) => getMeta(image)?.iptc.object_name || image.base;
export const getVibrant = (image) => getMeta(image)?.vibrant;
export const hasName = (image) => Boolean(getMeta(image)?.iptc.object_name);
export const getAspectRatio = (image) => image.childImageSharp.fluid.aspectRatio;
export const getRgba = (palette, alpha) => `rgba(${palette[0]}, ${palette[1]}, ${palette[2]}, ${alpha || 1})`;
export const getVibrantToHelmetSafeBodyStyle = (vibrant) => {
const style = {
'--muted': vibrant.Muted,
'--dark-muted': vibrant.DarkMuted,
'--light-muted': vibrant.LightMuted,
'--vibrant': vibrant.Vibrant,
'--dark-vibrant': vibrant.DarkVibrant,
'--light-vibrant': vibrant.LightVibrant,
}
if (typeof window === 'undefined') {
return style;
}
return Object.keys(style).map(key => `${(key)}: ${style[key]}`).join(';');
};