From ba82aa78cfb950c33dda26dbcbb282fed49b7a50 Mon Sep 17 00:00:00 2001 From: Chuck Dries Date: Sat, 7 Jan 2023 12:51:26 -0800 Subject: [PATCH] lightly tint background with accent color --- package.json | 2 +- src/components/GalleryImage/GalleryImage.js | 133 ++++++++++++++------ src/components/MasonryGallery.tsx | 21 +++- src/components/Switch.tsx | 60 +++++++++ src/gatsby-types.d.ts | 2 +- src/pages/index.tsx | 6 +- src/pages/photogallery.tsx | 78 +++++++----- src/utils.ts | 4 +- yarn.lock | 4 +- 9 files changed, 226 insertions(+), 84 deletions(-) create mode 100644 src/components/Switch.tsx diff --git a/package.json b/package.json index 3761590..55dd6d6 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "react-cool-dimensions": "^2.0.7", "react-div-100vh": "^0.7.0", "react-dom": "^18.2.0", - "react-helmet": "^6.1.0", + "react-helmet": "latest", "react-stately": "^3.19.0", "react-tiny-popover": "^7.2.0", "sass": "^1.34.0", diff --git a/src/components/GalleryImage/GalleryImage.js b/src/components/GalleryImage/GalleryImage.js index 1c35782..b5e9e88 100644 --- a/src/components/GalleryImage/GalleryImage.js +++ b/src/components/GalleryImage/GalleryImage.js @@ -3,6 +3,7 @@ import { graphql, navigate, Link } from "gatsby"; import { GatsbyImage, getImage } from "gatsby-plugin-image"; import { Helmet } from "react-helmet"; import classnames from "classnames"; +import chroma, { Color } from "chroma-js"; import ChevronLeft from "@spectrum-icons/workflow/ChevronLeft"; import ChevronRight from "@spectrum-icons/workflow/ChevronRight"; @@ -25,6 +26,7 @@ import { hasName, getCanonicalSize, getGalleryPageUrl, + getVibrantStyle, } from "../../utils"; import MetadataItem from "./MetadataItem"; import Nav from "../Nav"; @@ -41,9 +43,9 @@ const logKeyShortcut = (keyCode) => { }; const IconStyle = { - width: '24px', - margin: '0 4px' -} + width: "24px", + margin: "0 4px", +}; const ArrowLinkClasses = `hover:underline text-black lg:px-4 self-stretch flex items-center hover:bg-black/50 max-h-screen sticky top-0 @@ -133,6 +135,9 @@ const GalleryImage = ({ data, location: { state } }) => { locationString = location.join(", "); } const vibrant = getVibrant(image, true); + const darkAccent = chroma + .mix(vibrant.Vibrant, "hsla(216, 12%, 90%, 1)", 0.7) + .hex(); const canonicalSize = getCanonicalSize(image); const orientationClasses = @@ -142,7 +147,10 @@ const GalleryImage = ({ data, location: { state } }) => { const verticalPad = ar > 1 ? "250px" : "100px"; const shutterSpeed = React.useMemo( - () => meta.ExposureTime ? getShutterFractionFromExposureTime(meta.ExposureTime) : null, + () => + meta.ExposureTime + ? getShutterFractionFromExposureTime(meta.ExposureTime) + : null, [meta] ); const dateTaken = React.useMemo(() => new Date(dt), [dt]); @@ -151,8 +159,11 @@ const GalleryImage = ({ data, location: { state } }) => { {name} - Gallery | Chuck Dries
@@ -167,7 +178,13 @@ const GalleryImage = ({ data, location: { state } }) => { ), label: ( <> - Gallery esc + Gallery{" "} + + esc + ), }, @@ -186,7 +203,12 @@ const GalleryImage = ({ data, location: { state } }) => { }} to={`/photogallery/${prevImage}/`} > - + @@ -232,39 +254,69 @@ const GalleryImage = ({ data, location: { state } }) => { : "flex-row landscape:container portrait:pt-5 portrait:flex-col portrait:text-right portrait:items-end" )} > -
-

- {image.base} -

+
+

{image.base}

{hasName(image) && (

{name}

)}

{meta.Caption}

-
-
-
-
-
-
-
-
- { - try { - window.plausible("Download Wallpaper", { - props: { image: image.base }, - }); - } catch { - // do nothing - } - }} +
+
+
+
+
+
+
+
+
+ { + try { + window.plausible("Download Wallpaper", { + props: { image: image.base }, + }); + } catch { + // do nothing + } + }} + style={{ + background: darkAccent, + }} + > + Download wallpaper + +
+
+
{
{ )} {(meta.LensModel || meta.FocalLength) && ( } title="lens" /> @@ -334,7 +386,12 @@ const GalleryImage = ({ data, location: { state } }) => { }} to={`/photogallery/${nextImage}/`} > - + diff --git a/src/components/MasonryGallery.tsx b/src/components/MasonryGallery.tsx index df6e45f..3718a29 100644 --- a/src/components/MasonryGallery.tsx +++ b/src/components/MasonryGallery.tsx @@ -25,6 +25,7 @@ interface MasonryGalleryProps { debugHue?: boolean; debugRating?: boolean; linkState?: object; + showPalette?: boolean; } const MasonryGallery = ({ @@ -33,6 +34,7 @@ const MasonryGallery = ({ debugHue, debugRating, linkState, + showPalette, }: MasonryGalleryProps) => { const [isClient, setIsClient] = React.useState(false); React.useEffect(() => { @@ -124,7 +126,7 @@ const MasonryGallery = ({ const rowAspectRatioSum = currentRow.aspect; const ar = getAspectRatio(image); let width; - let height = `calc(${galleryWidth} / ${rowAspectRatioSum} + 10px)`; + let height = `calc(${galleryWidth} / ${rowAspectRatioSum} ${showPalette ? "+ 10px" : "- 10px"})`; if (rowAspectRatioSum < targetAspect * 0.66) { // incomplete row, render stuff at "ideal" sizes instead of filling width width = `calc(calc(100vw - 160px) / ${targetAspect / ar})`; @@ -137,9 +139,7 @@ const MasonryGallery = ({ const img = getImage(image); return ( )} {img && ( +
- + { showPalette &&
+
+
+
+
+
+
+
} +
)} ); diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx new file mode 100644 index 0000000..fee6096 --- /dev/null +++ b/src/components/Switch.tsx @@ -0,0 +1,60 @@ +import * as React from "react"; +import { useToggleState } from "react-stately"; +import { + AriaSwitchProps, + useFocusRing, + useSwitch, + VisuallyHidden, +} from "react-aria"; + +export function Switch(props: AriaSwitchProps) { + let state = useToggleState(props); + let ref = React.useRef(null); + let { inputProps } = useSwitch(props, state, ref); + let { isFocusVisible, focusProps } = useFocusRing(); + + return ( + + ); +} diff --git a/src/gatsby-types.d.ts b/src/gatsby-types.d.ts index 976b775..70ff0fc 100644 --- a/src/gatsby-types.d.ts +++ b/src/gatsby-types.d.ts @@ -2550,7 +2550,7 @@ type GalleryImageQuery = { readonly file: { readonly base: string, readonly publ type GalleryPageQueryQueryVariables = Exact<{ [key: string]: never; }>; -type GalleryPageQueryQuery = { 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 vibrantHue: number | null, readonly dominantHue: ReadonlyArray | null, readonly dateTaken: string | null, readonly meta: { readonly Keywords: ReadonlyArray | null, readonly Rating: number | null, readonly ObjectName: string | null } | null, readonly vibrant: { readonly Vibrant: ReadonlyArray | null } | null } | null } | null }> } }; +type GalleryPageQueryQuery = { 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 vibrantHue: number | null, readonly dominantHue: ReadonlyArray | null, readonly dateTaken: string | null, readonly meta: { readonly Keywords: ReadonlyArray | null, readonly Rating: number | null, readonly ObjectName: string | null } | null, readonly vibrant: { readonly DarkMuted: ReadonlyArray | null, readonly DarkVibrant: ReadonlyArray | null, readonly LightMuted: ReadonlyArray | null, readonly LightVibrant: ReadonlyArray | null, readonly Vibrant: ReadonlyArray | null, readonly Muted: ReadonlyArray | null } | null } | null } | null }> } }; type GatsbyImageSharpFixedFragment = { readonly base64: string | null, readonly width: number, readonly height: number, readonly src: string, readonly srcSet: string }; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 9eafd77..2614594 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -5,7 +5,7 @@ import { Helmet } from "react-helmet"; // import { take } from "ramda"; import classnames from "classnames"; -import { getHelmetSafeBodyStyle, getAspectRatio } from "../utils"; +import { getHelmetSafeBodyStyle, getAspectRatio, getVibrantStyle } from "../utils"; import Nav from "../components/Nav"; // import ActionButtons from "../components/index/ActionButtons"; import { use100vh } from "react-div-100vh"; @@ -73,14 +73,14 @@ const IndexPage = ({
diff --git a/src/pages/photogallery.tsx b/src/pages/photogallery.tsx index f651aa1..16837a4 100644 --- a/src/pages/photogallery.tsx +++ b/src/pages/photogallery.tsx @@ -6,9 +6,10 @@ import { Helmet } from "react-helmet"; import MasonryGallery from "../components/MasonryGallery"; import KeywordsPicker from "../components/KeywordsPicker"; -import { getGalleryPageUrl, getHelmetSafeBodyStyle } from "../utils"; +import { getGalleryPageUrl, getHelmetSafeBodyStyle, getVibrantStyle } from "../utils"; import Nav from "../components/Nav"; import { Item, Select } from "../components/Select"; +import { Switch } from "../components/Switch"; const SORT_KEYS = { hue: ["fields", "imageMeta", "vibrantHue"], @@ -31,6 +32,7 @@ const GalleryPage = ({ data }: PageProps) => { const showDebug = typeof window !== "undefined" && window.location.search.includes("debug=true"); + const [showPalette, setShowPalette] = React.useState(false); const setKeyword = React.useCallback( (newKeyword: string | null) => { @@ -166,14 +168,14 @@ const GalleryPage = ({ data }: PageProps) => {
@@ -186,7 +188,7 @@ const GalleryPage = ({ data }: PageProps) => { ]} />
-
+
) => { onChange={setKeyword} value={filterKeyword} /> -
+
+ setShowPalette(val)} + > + Show palettes +