Refine photo matte implementation
This commit is contained in:
parent
a76fa30331
commit
577371e28f
@ -96,7 +96,7 @@ Application behavior can be changed by configuring the following environment var
|
||||
- `NEXT_PUBLIC_PRO_MODE = 1` enables higher quality image storage (results in increased storage usage)
|
||||
- `NEXT_PUBLIC_STATICALLY_OPTIMIZE_PAGES = 1` enables static optimization for pages, i.e., renders pages at build time (results in increased project usage)—⚠️ _Experimental_
|
||||
- `NEXT_PUBLIC_STATICALLY_OPTIMIZE_OG_IMAGES = 1` enables static optimization for OG images, i.e., renders images at build time (results in increased project usage)—⚠️ _Experimental_
|
||||
- `NEXT_PUBLIC_MATTE_SETTING = light` constrains the size of each photo, and enables a surrounding border (can be set to `light` or `dark`)
|
||||
- `NEXT_PUBLIC_MATTE_PHOTOS = 1` constrains the size of each photo, and enables a surrounding border (potentially useful for photos with tall aspect ratios)
|
||||
- `NEXT_PUBLIC_BLUR_DISABLED = 1` prevents image blur data being stored and displayed (potentially useful for limiting Postgres usage)
|
||||
- `NEXT_PUBLIC_GEO_PRIVACY = 1` disables collection/display of location-based data
|
||||
- `NEXT_PUBLIC_IGNORE_PRIORITY_ORDER = 1` prevents `priority_order` field affecting photo order
|
||||
|
||||
@ -70,13 +70,13 @@ export default function CommandKClient({
|
||||
isUserSignedIn,
|
||||
setUserEmail,
|
||||
isCommandKOpen: isOpen,
|
||||
matteSetting,
|
||||
setMatteSetting,
|
||||
arePhotosMatted,
|
||||
shouldShowBaselineGrid,
|
||||
shouldDebugBlur,
|
||||
setIsCommandKOpen: setIsOpen,
|
||||
setShouldRespondToKeyboardCommands,
|
||||
setShouldShowBaselineGrid,
|
||||
setArePhotosMatted,
|
||||
setShouldDebugBlur,
|
||||
} = useAppState();
|
||||
|
||||
@ -199,15 +199,9 @@ export default function CommandKClient({
|
||||
heading: 'Debug Tools',
|
||||
accessory: <RiToolsFill size={16} className="translate-x-[-1px]" />,
|
||||
items: [{
|
||||
label: 'Toggle Matte Setting',
|
||||
action: () => setMatteSetting?.(prev => {
|
||||
if (!prev) {
|
||||
return 'light';
|
||||
} else if (prev === 'light') {
|
||||
return 'dark';
|
||||
}
|
||||
}),
|
||||
annotation: Boolean(matteSetting) ? <FaCheck size={12} /> : undefined,
|
||||
label: 'Toggle Photo Matting',
|
||||
action: () => setArePhotosMatted?.(prev => !prev),
|
||||
annotation: arePhotosMatted ? <FaCheck size={12} /> : undefined,
|
||||
}, {
|
||||
label: 'Toggle Blur Debug',
|
||||
action: () => setShouldDebugBlur?.(prev => !prev),
|
||||
|
||||
@ -75,8 +75,9 @@ export default function ImageBlurFallback(props: ImageProps & {
|
||||
<div className={clsx(
|
||||
'@container',
|
||||
'absolute inset-0',
|
||||
'bg-main overflow-hidden',
|
||||
'overflow-hidden',
|
||||
'transition-opacity duration-300 ease-in',
|
||||
!(BLUR_ENABLED && props.blurDataURL) && 'bg-main',
|
||||
(isLoading || shouldDebugBlur) ? 'opacity-100' : 'opacity-0',
|
||||
)}>
|
||||
{(BLUR_ENABLED && props.blurDataURL)
|
||||
|
||||
@ -69,7 +69,7 @@ export default function PhotoLarge({
|
||||
|
||||
useOnVisible(ref, onVisible);
|
||||
|
||||
const { matteSetting } = useAppState();
|
||||
const { arePhotosMatted } = useAppState();
|
||||
|
||||
return (
|
||||
<SiteGrid
|
||||
@ -79,28 +79,30 @@ export default function PhotoLarge({
|
||||
href={pathForPhoto(photo)}
|
||||
className={clsx(
|
||||
'active:brightness-75',
|
||||
Boolean(matteSetting) &&
|
||||
'flex items-center justify-center aspect-[3/2]',
|
||||
matteSetting === 'light' && 'bg-invert',
|
||||
matteSetting === 'dark' && 'bg-dim',
|
||||
arePhotosMatted &&
|
||||
'flex items-center aspect-[3/2] bg-gray-100',
|
||||
)}
|
||||
prefetch={prefetch}
|
||||
>
|
||||
<ImageLarge
|
||||
className={clsx(Boolean(matteSetting) &&
|
||||
'flex items-center justify-center h-full')}
|
||||
imgClassName={clsx(
|
||||
Boolean(matteSetting) && 'object-scale-down',
|
||||
Boolean(matteSetting) &&
|
||||
photo.aspectRatio >= 1 ? 'max-h-[80%]' : 'max-h-[90%]'
|
||||
)}
|
||||
alt={altTextForPhoto(photo)}
|
||||
src={photo.url}
|
||||
aspectRatio={photo.aspectRatio}
|
||||
blurData={photo.blurData}
|
||||
blurCompatibilityMode={doesPhotoNeedBlurCompatibility(photo)}
|
||||
priority={priority}
|
||||
/>
|
||||
<div className={clsx(
|
||||
arePhotosMatted &&
|
||||
'flex items-center justify-center w-full',
|
||||
arePhotosMatted && photo.aspectRatio >= 1
|
||||
? 'h-[80%]'
|
||||
: 'h-[90%]',
|
||||
)}>
|
||||
<ImageLarge
|
||||
className={clsx(arePhotosMatted && 'h-full')}
|
||||
imgClassName={clsx(arePhotosMatted &&
|
||||
'object-contain w-full h-full')}
|
||||
alt={altTextForPhoto(photo)}
|
||||
src={photo.url}
|
||||
aspectRatio={photo.aspectRatio}
|
||||
blurData={photo.blurData}
|
||||
blurCompatibilityMode={doesPhotoNeedBlurCompatibility(photo)}
|
||||
priority={priority}
|
||||
/>
|
||||
</div>
|
||||
</Link>}
|
||||
contentSide={
|
||||
<DivDebugBaselineGrid className={clsx(
|
||||
|
||||
@ -44,7 +44,7 @@ export default function SiteChecklistClient({
|
||||
isStaticallyOptimized,
|
||||
arePagesStaticallyOptimized,
|
||||
areOGImagesStaticallyOptimized,
|
||||
matteSetting,
|
||||
arePhotosMatted,
|
||||
isBlurEnabled,
|
||||
isGeoPrivacyEnabled,
|
||||
isPriorityOrderEnabled,
|
||||
@ -123,9 +123,9 @@ export default function SiteChecklistClient({
|
||||
>
|
||||
<span className="inline-flex items-center gap-1">
|
||||
<span className={clsx(
|
||||
'text-xs font-medium tracking-wide',
|
||||
'px-0.5 py-0.5',
|
||||
'rounded-sm',
|
||||
'text-[11px] font-medium tracking-wide',
|
||||
'px-0.5 py-[0.5px]',
|
||||
'rounded-[5px]',
|
||||
'bg-gray-100 dark:bg-gray-800',
|
||||
)}>
|
||||
`{variable}`
|
||||
@ -135,7 +135,7 @@ export default function SiteChecklistClient({
|
||||
</div>;
|
||||
|
||||
const renderEnvVars = (variables: string[]) =>
|
||||
<div className="py-1 space-y-1">
|
||||
<div className="py-0.5">
|
||||
{variables.map(envVar => renderEnvVar(envVar))}
|
||||
</div>;
|
||||
|
||||
@ -370,26 +370,24 @@ export default function SiteChecklistClient({
|
||||
{renderSubStatus(
|
||||
arePagesStaticallyOptimized ? 'checked' : 'optional',
|
||||
renderEnvVars(['NEXT_PUBLIC_STATICALLY_OPTIMIZE_PAGES']),
|
||||
'translate-y-[4.5px]',
|
||||
'translate-y-[3.5px]',
|
||||
)}
|
||||
{renderSubStatus(
|
||||
areOGImagesStaticallyOptimized ? 'checked' : 'optional',
|
||||
renderEnvVars(['NEXT_PUBLIC_STATICALLY_OPTIMIZE_OG_IMAGES']),
|
||||
'translate-y-[4.5px]',
|
||||
'translate-y-[3.5px]',
|
||||
)}
|
||||
</ChecklistRow>
|
||||
<ChecklistRow
|
||||
title={'Photo Matte' + (matteSetting
|
||||
? `: ${matteSetting?.toLocaleUpperCase()}`
|
||||
: '')}
|
||||
status={Boolean(matteSetting)}
|
||||
title="Photo Matting"
|
||||
status={arePhotosMatted}
|
||||
isPending={isPendingPage}
|
||||
optional
|
||||
>
|
||||
Set environment variable to {'"light"'} or {'"dark"'} to
|
||||
Set environment variable to {'"1"'} to constrain the size
|
||||
{' '}
|
||||
constrain the size of each photo, and enable a surrounding border:
|
||||
{renderEnvVars(['NEXT_PUBLIC_MATTE_SETTING'])}
|
||||
of each photo, and enable a surrounding border:
|
||||
{renderEnvVars(['NEXT_PUBLIC_MATTE_PHOTOS'])}
|
||||
</ChecklistRow>
|
||||
<ChecklistRow
|
||||
title="Image Blur"
|
||||
|
||||
@ -114,12 +114,8 @@ export const STATICALLY_OPTIMIZED_PAGES =
|
||||
process.env.NEXT_PUBLIC_STATICALLY_OPTIMIZE_PAGES === '1';
|
||||
export const STATICALLY_OPTIMIZED_OG_IMAGES =
|
||||
process.env.NEXT_PUBLIC_STATICALLY_OPTIMIZE_OG_IMAGES === '1';
|
||||
export const MATTE_SETTING =
|
||||
process.env.NEXT_PUBLIC_MATTE_SETTING === 'light'
|
||||
? 'light'
|
||||
: process.env.NEXT_PUBLIC_MATTE_SETTING === 'dark'
|
||||
? 'dark'
|
||||
: undefined;
|
||||
export const MATTE_PHOTOS =
|
||||
process.env.NEXT_PUBLIC_MATTE_PHOTOS === '1';
|
||||
export const BLUR_ENABLED =
|
||||
process.env.NEXT_PUBLIC_BLUR_DISABLED !== '1';
|
||||
export const GEO_PRIVACY_ENABLED =
|
||||
@ -183,7 +179,7 @@ export const CONFIG_CHECKLIST_STATUS = {
|
||||
),
|
||||
arePagesStaticallyOptimized: STATICALLY_OPTIMIZED_PAGES,
|
||||
areOGImagesStaticallyOptimized: STATICALLY_OPTIMIZED_OG_IMAGES,
|
||||
matteSetting: MATTE_SETTING,
|
||||
arePhotosMatted: MATTE_PHOTOS,
|
||||
isBlurEnabled: BLUR_ENABLED,
|
||||
isGeoPrivacyEnabled: GEO_PRIVACY_ENABLED,
|
||||
isAiTextGenerationEnabled: AI_TEXT_GENERATION_ENABLED,
|
||||
|
||||
@ -162,10 +162,6 @@
|
||||
@apply
|
||||
bg-gray-900 dark:bg-gray-100
|
||||
}
|
||||
.bg-dim {
|
||||
@apply
|
||||
bg-gray-200/40 dark:bg-gray-800/40
|
||||
}
|
||||
/* Utilities: Baseline Grid */
|
||||
.space-y-baseline {
|
||||
@apply
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
import { Dispatch, SetStateAction, createContext, useContext } from 'react';
|
||||
import { AnimationConfig } from '@/components/AnimateItems';
|
||||
|
||||
export type MatteSetting = 'light' | 'dark' | undefined;
|
||||
|
||||
export interface AppStateContext {
|
||||
previousPathname?: string
|
||||
hasLoaded?: boolean
|
||||
matteSetting?: MatteSetting
|
||||
setMatteSetting?: Dispatch<SetStateAction<MatteSetting>>
|
||||
arePhotosMatted?: boolean
|
||||
setArePhotosMatted?: Dispatch<SetStateAction<boolean>>
|
||||
swrTimestamp?: number
|
||||
invalidateSwr?: () => void
|
||||
userEmail?: string
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, ReactNode, useCallback } from 'react';
|
||||
import { AppStateContext, MatteSetting } from './AppState';
|
||||
import { AppStateContext } from './AppState';
|
||||
import { AnimationConfig } from '@/components/AnimateItems';
|
||||
import usePathnames from '@/utility/usePathnames';
|
||||
import { getAuthAction } from '@/auth/actions';
|
||||
import useSWR from 'swr';
|
||||
import { MATTE_SETTING } from '@/site/config';
|
||||
import { MATTE_PHOTOS } from '@/site/config';
|
||||
|
||||
export default function AppStateProvider({
|
||||
children,
|
||||
@ -17,8 +17,8 @@ export default function AppStateProvider({
|
||||
|
||||
const [hasLoaded, setHasLoaded] =
|
||||
useState(false);
|
||||
const [matteSetting, setMatteSetting] =
|
||||
useState<MatteSetting>(MATTE_SETTING);
|
||||
const [arePhotosMatted, setArePhotosMatted] =
|
||||
useState(MATTE_PHOTOS);
|
||||
const [swrTimestamp, setSwrTimestamp] =
|
||||
useState(Date.now());
|
||||
const [userEmail, setUserEmail] =
|
||||
@ -53,8 +53,8 @@ export default function AppStateProvider({
|
||||
value={{
|
||||
previousPathname,
|
||||
hasLoaded,
|
||||
matteSetting,
|
||||
setMatteSetting,
|
||||
arePhotosMatted,
|
||||
setArePhotosMatted,
|
||||
swrTimestamp,
|
||||
invalidateSwr,
|
||||
setHasLoaded,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user