pick colors from images at build time, query and use for tailwind classes in react
This commit is contained in:
@@ -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 {
|
||||
|
15
gatsby/src/components/IndexComponents.js
Normal file
15
gatsby/src/components/IndexComponents.js
Normal 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>
|
||||
);
|
@@ -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>
|
||||
);
|
||||
|
@@ -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 couldn’t find what you were looking for.
|
||||
|
@@ -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 & 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 & 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;
|
||||
|
@@ -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;
|
||||
|
3
gatsby/src/styles/index.css
Normal file
3
gatsby/src/styles/index.css
Normal file
@@ -0,0 +1,3 @@
|
||||
/* main.hero {
|
||||
|
||||
} */
|
@@ -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(';');
|
||||
};
|
||||
|
Reference in New Issue
Block a user