replace homepage with gallery
This commit is contained in:
parent
b0f51b7ef5
commit
31e47353e6
@ -43,7 +43,7 @@ const Nav = ({ isClient, internalLinks, className }: NavProps) => {
|
|||||||
: "border border-white"
|
: "border border-white"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<ul className="inline-flex flex-wrap justify-center">
|
{/* <ul className="inline-flex flex-wrap justify-center">
|
||||||
{internalLinks &&
|
{internalLinks &&
|
||||||
internalLinks.map(({ href, label }) => (
|
internalLinks.map(({ href, label }) => (
|
||||||
<li key={href}>
|
<li key={href}>
|
||||||
@ -57,7 +57,7 @@ const Nav = ({ isClient, internalLinks, className }: NavProps) => {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
{internalLinks && currentBreakpoint !== "XS" && <>|</>}
|
{internalLinks && currentBreakpoint !== "XS" && <>|</>} */}
|
||||||
{currentBreakpoint === "XS" && (
|
{currentBreakpoint === "XS" && (
|
||||||
<button
|
<button
|
||||||
className="mx-2 hover:underline inline-flex align-middle"
|
className="mx-2 hover:underline inline-flex align-middle"
|
||||||
@ -84,11 +84,11 @@ const Nav = ({ isClient, internalLinks, className }: NavProps) => {
|
|||||||
: "bg-black border border-white")
|
: "bg-black border border-white")
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{/* <li>
|
<li>
|
||||||
<a className={navClasses} href="https://buzzwords.gg">
|
<a className={navClasses} href="https://buzzwords.gg">
|
||||||
Buzzwords
|
Buzzwords
|
||||||
</a>
|
</a>
|
||||||
</li> */}
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a className={navClasses} href="https://twitter.com/chuckletmilk">
|
<a className={navClasses} href="https://twitter.com/chuckletmilk">
|
||||||
Twitter
|
Twitter
|
||||||
|
5
src/gatsby-types.d.ts
vendored
5
src/gatsby-types.d.ts
vendored
@ -4518,11 +4518,6 @@ type GatsbyImageSharpFluid_withWebp_tracedSVGFragment = { readonly tracedSVG: st
|
|||||||
|
|
||||||
type GatsbyImageSharpFluidLimitPresentationSizeFragment = { readonly maxHeight: number, readonly maxWidth: number };
|
type GatsbyImageSharpFluidLimitPresentationSizeFragment = { readonly maxHeight: number, readonly maxWidth: number };
|
||||||
|
|
||||||
type IndexPageQueryVariables = Exact<{ [key: string]: never; }>;
|
|
||||||
|
|
||||||
|
|
||||||
type IndexPageQuery = { readonly allFile: { readonly nodes: ReadonlyArray<{ readonly relativePath: string, readonly base: string, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly vibrant: { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null } | null } | null } | null }> } };
|
|
||||||
|
|
||||||
type VibrantColorsFragment = { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null };
|
type VibrantColorsFragment = { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null };
|
||||||
|
|
||||||
type GalleryImagesNodeQueryVariables = Exact<{ [key: string]: never; }>;
|
type GalleryImagesNodeQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
@ -1,290 +1,244 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import * as R from "ramda";
|
||||||
import { graphql, PageProps } from "gatsby";
|
import { graphql, PageProps } from "gatsby";
|
||||||
import { GatsbyImage, getImage } from "gatsby-plugin-image";
|
|
||||||
import { Helmet } from "react-helmet";
|
import { Helmet } from "react-helmet";
|
||||||
import { take } from "ramda";
|
import { Picker, Item } from "@adobe/react-spectrum";
|
||||||
import classnames from "classnames";
|
|
||||||
|
|
||||||
import "../styles/index.css";
|
import MasonryGallery from "../components/MasonryGallery";
|
||||||
|
import KeywordsPicker from "../components/KeywordsPicker";
|
||||||
import { getHelmetSafeBodyStyle, getVibrant, getAspectRatio } from "../utils";
|
import { getGalleryPageUrl } from "../utils";
|
||||||
import Nav from "../components/Nav";
|
import Nav from "../components/Nav";
|
||||||
import ActionButtons from "../components/index/ActionButtons";
|
|
||||||
import { use100vh } from "react-div-100vh";
|
|
||||||
import { useMediaQuery } from "../useMediaQuery";
|
|
||||||
|
|
||||||
const env =
|
const SORT_KEYS = {
|
||||||
process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || "development";
|
hue: ["fields", "imageMeta", "vibrantHue"],
|
||||||
|
rating: ["fields", "imageMeta", "meta", "Rating"],
|
||||||
|
hue_debug: ["fields", "imageMeta", "dominantHue", 0],
|
||||||
|
date: [],
|
||||||
|
} as const;
|
||||||
|
|
||||||
export type HomepageImage = Queries.IndexPageQuery["allFile"]["nodes"][number];
|
export type GalleryImage =
|
||||||
|
Queries.GalleryPageQueryQuery["allFile"]["nodes"][number];
|
||||||
|
|
||||||
const getDifferentRand = (
|
const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => {
|
||||||
range: number,
|
const hash =
|
||||||
lastNs: number[],
|
typeof window !== "undefined" ? window.location.hash.replace("#", "") : "";
|
||||||
iterations = 0
|
|
||||||
): number => {
|
|
||||||
const n = Math.floor(Math.random() * range);
|
|
||||||
if (lastNs.findIndex((x) => x === n) > -1 && iterations < 5) {
|
|
||||||
console.log("got dupe, trying again", n);
|
|
||||||
return getDifferentRand(range, lastNs, iterations + 1);
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
};
|
|
||||||
|
|
||||||
const IndexPage = ({
|
const [hashCleared, setHashCleared] = React.useState(false); // eslint-disable-line no-unused-vars
|
||||||
data: {
|
// ^ used just to force a re-render with the cleared hash value (I know, it's a smell for sure)
|
||||||
allFile: { nodes: images },
|
const [filterKeyword, _setKeyword] = React.useState(null as string | null);
|
||||||
},
|
const [sortKey, _setSortKey] = React.useState("rating" as string);
|
||||||
}: PageProps<Queries.IndexPageQuery>) => {
|
const showDebug =
|
||||||
const [isClient, setIsClient] = React.useState(false);
|
typeof window !== "undefined" &&
|
||||||
const [imageIndex, setImageIndex] = React.useState(0);
|
window.location.search.includes("debug=true");
|
||||||
const image = React.useMemo(() => {
|
|
||||||
return images[imageIndex];
|
|
||||||
}, [images, imageIndex]);
|
|
||||||
|
|
||||||
const shuffleImage = React.useCallback(
|
const setKeyword = React.useCallback(
|
||||||
(currentImage?: typeof images[number]) => {
|
(newKeyword: string | null) => {
|
||||||
const lastThreeImages =
|
if (newKeyword) {
|
||||||
JSON.parse(localStorage.getItem("lastHeros") ?? "[]") || [];
|
|
||||||
if (env === "production") {
|
|
||||||
try {
|
try {
|
||||||
window.plausible("Shuffle", {
|
window.plausible("Filter Keyword", {
|
||||||
props: { currentImage: currentImage?.base },
|
props: { keyword: newKeyword },
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
/* do nothing */
|
// do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const index = getDifferentRand(images.length, lastThreeImages);
|
_setKeyword(newKeyword);
|
||||||
localStorage.setItem(
|
window.history.replaceState(
|
||||||
"lastHeros",
|
null,
|
||||||
JSON.stringify(take(3, [index, ...lastThreeImages]))
|
"",
|
||||||
|
getGalleryPageUrl({ keyword: newKeyword, sortKey }, hash)
|
||||||
);
|
);
|
||||||
setImageIndex(index);
|
|
||||||
},
|
},
|
||||||
[images.length]
|
[_setKeyword, sortKey, hash]
|
||||||
);
|
);
|
||||||
|
|
||||||
// pick random image on page hydration
|
const setSortKey = React.useCallback(
|
||||||
React.useEffect(() => {
|
(newSortKey: string) => {
|
||||||
if (!isClient) {
|
try {
|
||||||
setIsClient(true);
|
window.plausible("Sort Gallery", {
|
||||||
shuffleImage(image);
|
props: { key: newSortKey },
|
||||||
}
|
});
|
||||||
}, [isClient, imageIndex, image, shuffleImage]);
|
} catch (e) {
|
||||||
|
// do nothing
|
||||||
React.useEffect(() => {
|
|
||||||
const keyListener = (e: KeyboardEvent) => {
|
|
||||||
switch (e.code) {
|
|
||||||
case "Space": {
|
|
||||||
shuffleImage(image);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case "ArrowRight": {
|
|
||||||
if (imageIndex === images.length - 1) {
|
|
||||||
setImageIndex(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setImageIndex(imageIndex + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "ArrowLeft": {
|
|
||||||
if (imageIndex === 0) {
|
|
||||||
setImageIndex(images.length - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setImageIndex(imageIndex - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
_setSortKey(newSortKey);
|
||||||
document.addEventListener("keydown", keyListener);
|
window.history.replaceState(
|
||||||
return () => {
|
null,
|
||||||
document.removeEventListener("keydown", keyListener);
|
"",
|
||||||
};
|
getGalleryPageUrl({ sortKey: newSortKey, keyword: filterKeyword }, hash)
|
||||||
}, [imageIndex, images.length, image, shuffleImage]);
|
);
|
||||||
|
},
|
||||||
|
[_setSortKey, filterKeyword, hash]
|
||||||
|
);
|
||||||
|
|
||||||
const browserIsLandscape = useMediaQuery("(orientation: landscape)");
|
const removeHash = React.useCallback(() => {
|
||||||
|
const url = new URL(
|
||||||
|
typeof window !== "undefined"
|
||||||
|
? window.location.href.toString()
|
||||||
|
: "https://chuckdries.com/photogallery/"
|
||||||
|
);
|
||||||
|
|
||||||
const vibrant = getVibrant(image);
|
url.hash = "";
|
||||||
const ar = getAspectRatio(image);
|
window.history.replaceState(null, "", url.href.toString());
|
||||||
|
window.removeEventListener("wheel", removeHash);
|
||||||
|
setHashCleared(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const screenHeight = use100vh();
|
const scrollIntoView = React.useCallback(() => {
|
||||||
|
if (!hash) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const el = document.getElementById(hash);
|
||||||
|
if (!el) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
el.scrollIntoView({
|
||||||
|
block: "center",
|
||||||
|
});
|
||||||
|
window.addEventListener("wheel", removeHash);
|
||||||
|
}, [hash, removeHash]);
|
||||||
|
|
||||||
const imageIsLandscape = isClient ? ar > 1 : true;
|
React.useEffect(() => {
|
||||||
|
const url = new URL(window.location.toString());
|
||||||
|
|
||||||
|
const sortKeyFromUrl = url.searchParams.get("sort");
|
||||||
|
if (sortKeyFromUrl) {
|
||||||
|
_setSortKey(sortKeyFromUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
const filterKeyFromUrl = url.searchParams.get("filter");
|
||||||
|
if (filterKeyFromUrl) {
|
||||||
|
_setKeyword(filterKeyFromUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hacky but it works for now
|
||||||
|
setTimeout(() => {
|
||||||
|
// don't scroll into view if user got here with back button
|
||||||
|
scrollIntoView();
|
||||||
|
}, 100);
|
||||||
|
}, [setSortKey, setKeyword, scrollIntoView]);
|
||||||
|
|
||||||
|
const images: GalleryImage[] = React.useMemo(() => {
|
||||||
|
const sort =
|
||||||
|
sortKey === "date"
|
||||||
|
? R.sort((node1: typeof data["allFile"]["nodes"][number], node2) => {
|
||||||
|
const date1 = new Date(
|
||||||
|
R.pathOr("", ["fields", "imageMeta", "dateTaken"], node1)
|
||||||
|
);
|
||||||
|
const date2 = new Date(
|
||||||
|
R.pathOr("", ["fields", "imageMeta", "dateTaken"], node2)
|
||||||
|
);
|
||||||
|
return -1 * (date1.getTime() - date2.getTime());
|
||||||
|
})
|
||||||
|
: R.sort(
|
||||||
|
// @ts-ignore
|
||||||
|
R.descend(R.path<GalleryImage>(SORT_KEYS[sortKey]))
|
||||||
|
);
|
||||||
|
|
||||||
|
const filter = filterKeyword
|
||||||
|
? R.filter((image) =>
|
||||||
|
R.includes(
|
||||||
|
filterKeyword,
|
||||||
|
R.pathOr([], ["fields", "imageMeta", "meta", "Keywords"], image)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
: R.identity;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ret = R.pipe(
|
||||||
|
// @ts-ignore
|
||||||
|
sort,
|
||||||
|
filter
|
||||||
|
)(data.allFile.nodes) as any;
|
||||||
|
return ret;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("caught images!", e);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}, [data, sortKey, filterKeyword]);
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
const img = getImage(image);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>Chuck Dries</title>
|
<title>Photo Gallery | Chuck Dries</title>
|
||||||
<body
|
<body className="bg-black text-white" />
|
||||||
className={classnames(isClient ? "bg-muted-dark" : "bg-gray-800")}
|
|
||||||
// @ts-ignore
|
|
||||||
style={getHelmetSafeBodyStyle(vibrant!, screenHeight)}
|
|
||||||
/>
|
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<main
|
<div className="sm:sticky top-0 pt-1 z-10 bg-black">
|
||||||
className={classnames(
|
<Nav
|
||||||
"font-serif",
|
className="mb-4"
|
||||||
imageIsLandscape
|
internalLinks={[
|
||||||
? "landscape:grid portrait:h-actual-screen portrait:flex flex-col justify-around"
|
{ href: "/", label: "Home" },
|
||||||
: "portrait:grid landscape:flex flex-row"
|
{ href: "/photogallery/", label: "Gallery" },
|
||||||
)}
|
]}
|
||||||
>
|
></Nav>
|
||||||
<div
|
<div className="flex flex-col lg:flex-row lg:items-end justify-between">
|
||||||
className={classnames(
|
<div className="flex flex-col mx-5 font-serif">
|
||||||
"landscape:flex-auto flex flex-col items-center",
|
|
||||||
imageIsLandscape
|
<h1 className="text-5xl mt-0 font-black z-10">
|
||||||
? "portrait:items-center landscape:w-screen justify-between"
|
Chuck Dries
|
||||||
: "landscape:justify-center portrait:w-screen"
|
</h1>
|
||||||
)}
|
<h2 className="">Full Stack Software Engineer & Photographer</h2>
|
||||||
style={{ gridArea: "1/1" }}
|
|
||||||
>
|
|
||||||
<Nav
|
|
||||||
internalLinks={[
|
|
||||||
{ href: "/", label: "Home" },
|
|
||||||
{ href: "/photogallery/", label: "Gallery" },
|
|
||||||
]}
|
|
||||||
isClient={isClient}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={classnames(
|
|
||||||
"flex flex-col",
|
|
||||||
!imageIsLandscape && "portrait:flex-auto "
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={classnames(
|
|
||||||
"rounded-[50px] p-3 md:p-5 ml-2 mr-4 md:ml-3 md:mr-5 flex flex-col items-center z-10 mb-3",
|
|
||||||
isClient
|
|
||||||
? imageIsLandscape
|
|
||||||
? "text-vibrant-light landscape:text-vibrant-dark landscape:cool-border-big landscape:border-r-[20px] landscape:border-b-[20px]"
|
|
||||||
: "text-vibrant-light portrait:text-vibrant-dark portrait:cool-border-big portrait:border-r-[20px] portrait:border-b-[20px]"
|
|
||||||
: "bg-gray-50 border-r-[20px] border-b-[20px]",
|
|
||||||
isClient && ""
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<h1
|
|
||||||
className={classnames(
|
|
||||||
"mb-0 mt-0 text-center font-black z-20 text-5xl sm:text-7xl md:text-8xl lg:text-9xl"
|
|
||||||
)}
|
|
||||||
style={{ lineHeight: "85%" }}
|
|
||||||
>
|
|
||||||
Chuck Dries
|
|
||||||
</h1>
|
|
||||||
<h2
|
|
||||||
className={classnames(
|
|
||||||
"p-3 text-center z-20 font-bold text-lg md:text-2xl lg:text-3xl"
|
|
||||||
)}
|
|
||||||
style={{ lineHeight: "110%" }}
|
|
||||||
>
|
|
||||||
Full Stack Software Engineer & Photographer
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<KeywordsPicker
|
||||||
className={classnames(
|
keywords={[
|
||||||
imageIsLandscape ? "block portrait:hidden" : ""
|
"night",
|
||||||
)}
|
"coast",
|
||||||
>
|
// "city",
|
||||||
<ActionButtons
|
"landscape",
|
||||||
image={image}
|
"flowers",
|
||||||
isClient={isClient}
|
"product",
|
||||||
shuffleImage={shuffleImage}
|
"waterfall",
|
||||||
/>
|
"fireworks",
|
||||||
|
"panoramic",
|
||||||
|
"Portland Japanese Garden",
|
||||||
|
"shoot the light",
|
||||||
|
// "sunset",
|
||||||
|
]}
|
||||||
|
onChange={setKeyword}
|
||||||
|
value={filterKeyword}
|
||||||
|
/>
|
||||||
|
<div className="m-2">
|
||||||
|
<Picker
|
||||||
|
label="Sort by..."
|
||||||
|
// @ts-ignore
|
||||||
|
onSelectionChange={setSortKey}
|
||||||
|
selectedKey={sortKey}
|
||||||
|
>
|
||||||
|
<Item key="rating">Curated</Item>
|
||||||
|
<Item key="date">Date</Item>
|
||||||
|
<Item key="hue">Hue</Item>
|
||||||
|
</Picker>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{isClient && img ? (
|
</div>
|
||||||
<GatsbyImage
|
<MasonryGallery
|
||||||
alt=""
|
aspectsByBreakpoint={{
|
||||||
className={classnames(
|
xs: 2,
|
||||||
imageIsLandscape
|
sm: 3,
|
||||||
? "landscape:h-actual-screen portrait:h-two-thirds-vw"
|
md: 4,
|
||||||
: "h-actual-screen portrait:w-full"
|
lg: 4,
|
||||||
)}
|
xl: 5,
|
||||||
image={img}
|
"2xl": 6.1,
|
||||||
loading="eager"
|
"3xl": 7.5,
|
||||||
style={{
|
}}
|
||||||
gridArea: "1/1",
|
debugHue={sortKey === "hue_debug"}
|
||||||
width:
|
debugRating={sortKey === "rating" && showDebug}
|
||||||
browserIsLandscape && !imageIsLandscape
|
images={images}
|
||||||
? `${ar * 100}vh`
|
linkState={{
|
||||||
: "100%",
|
sortKey,
|
||||||
}}
|
filterKeyword,
|
||||||
/>
|
}}
|
||||||
) : (
|
/>
|
||||||
<div
|
|
||||||
className="landscape:h-actual-screen portrait:h-two-thirds-vw w-full"
|
|
||||||
style={{ gridArea: "1/1" }}
|
|
||||||
></div>
|
|
||||||
)}
|
|
||||||
{imageIsLandscape && (
|
|
||||||
<div className="hidden portrait:flex justify-center sm:my-2">
|
|
||||||
<ActionButtons
|
|
||||||
image={image}
|
|
||||||
isClient={isClient}
|
|
||||||
shuffleImage={shuffleImage}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</main>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query IndexPage {
|
query GalleryPageQuery {
|
||||||
allFile(
|
allFile(
|
||||||
filter: {
|
filter: { sourceInstanceName: { eq: "gallery" } }
|
||||||
sourceInstanceName: { eq: "gallery" }
|
sort: { fields: fields___imageMeta___dateTaken, order: DESC }
|
||||||
base: {
|
|
||||||
in: [
|
|
||||||
"DSC06616.jpg" # B&W abstract ## KEEP ON TOP
|
|
||||||
# "20160530-DSC09108.jpg" # portrait red flowers
|
|
||||||
# # "DSC00201.jpg" # duck
|
|
||||||
# "DSC04905.jpg" # purple layers
|
|
||||||
"DSC05761.jpg" # monument valley
|
|
||||||
"DSC05851.jpg" # utahn highway sunset
|
|
||||||
# "DSC06245.jpg" # snowy milky way
|
|
||||||
# # "DSC08521.jpg" # firepit bloom j&e
|
|
||||||
# "DSC07490.jpg" # house on prairie
|
|
||||||
# "DSC02538.jpg" # portrait pink cactus bloom
|
|
||||||
# "20190624-DSC00771.jpg" # glacier forest fog
|
|
||||||
# # "DSC00237.jpg" # cotton candy clouds
|
|
||||||
"_DSC6062.jpg" # field of wildflowers
|
|
||||||
# "_DSC6060.jpg" # edge of the world
|
|
||||||
"_DSC6219.jpg" # whihte/yellow rosebush
|
|
||||||
# "_DSC6243.jpg" # bright rose in darkness
|
|
||||||
# "_DSC6400-2.jpg" # Horsetail falls
|
|
||||||
# "_DSC6798.jpg" # Japanese zen garden
|
|
||||||
# "_DSC6481.jpg" # Mt Hood from Powell Butte
|
|
||||||
# "_DSC5916.jpg" # blue dart stinger
|
|
||||||
# "_DSC0286.jpg" # god rays
|
|
||||||
# "_DSC8998.jpg" # forest road
|
|
||||||
# "DSC01169.jpg" # ferris wheel reflection
|
|
||||||
"DSC01800.jpg" # cherry blossom landscape sunny sky
|
|
||||||
"DSC01772.jpg" # cherry blossom portrait sunny sky
|
|
||||||
# "DSC06201.jpg" # Wheatland snowy hills
|
|
||||||
"DSC01924.jpg" # cherry blossom sea
|
|
||||||
# "DSC03157.jpg" # constellation of flowers
|
|
||||||
"DSC02610.jpg" # peter iredale portrait
|
|
||||||
"DSC02615.jpg" # rori iredale beach field camera
|
|
||||||
"DSC06490.jpg" # Japanese garden steps
|
|
||||||
"DSC06687.jpg" # Multnomah Falls long exposure
|
|
||||||
"DSC09932.jpg" # milky way
|
|
||||||
"DSC09944.jpg" # milky way rori
|
|
||||||
"DSC03725.jpg" # oregon coast lighthouse
|
|
||||||
"DSC03750.jpg"
|
|
||||||
"DSC03804.jpg"
|
|
||||||
"DSC04122.jpg" # shoot the light wheel hallway
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort: { order: DESC, fields: fields___imageMeta___dateTaken }
|
|
||||||
) {
|
) {
|
||||||
nodes {
|
nodes {
|
||||||
relativePath
|
relativePath
|
||||||
@ -294,15 +248,23 @@ export const query = graphql`
|
|||||||
aspectRatio
|
aspectRatio
|
||||||
}
|
}
|
||||||
gatsbyImageData(
|
gatsbyImageData(
|
||||||
layout: FULL_WIDTH
|
layout: CONSTRAINED
|
||||||
placeholder: NONE
|
height: 550
|
||||||
breakpoints: [750, 1080, 1366, 1920, 2560, 3840]
|
placeholder: DOMINANT_COLOR
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fields {
|
fields {
|
||||||
imageMeta {
|
imageMeta {
|
||||||
|
vibrantHue
|
||||||
|
dominantHue
|
||||||
|
dateTaken
|
||||||
|
meta {
|
||||||
|
Keywords
|
||||||
|
Rating
|
||||||
|
ObjectName
|
||||||
|
}
|
||||||
vibrant {
|
vibrant {
|
||||||
...VibrantColors
|
Vibrant
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,4 +273,4 @@ export const query = graphql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default IndexPage;
|
export default GalleryPage;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user