- {whiteBalanceFormatted.length <= 8 && 'AWB: '}
- {whiteBalanceFormatted}
- {hasCustomizedWhiteBalance && <>
- {' '}
-
+
+
+ DR{dynamicRange ?? 100}
+
+
+ {iso}
+
+
+ {exposure}
+
+
+
+ {renderDataSquare(
+ `R${addSign(whiteBalance?.red)} / B${addSign(whiteBalance?.blue)}`,
+ whiteBalanceFormatted,
+ )}
{renderDataSquare('Highlight', highlight || random.highlight)}
@@ -118,31 +131,24 @@ export default function PhotoRecipeFrostLight({
{renderDataSquare('Color Chrome', colorChromeEffect)}
{renderDataSquare('FX Blue', colorChromeFXBlue)}
-
- {highISONoiseReduction !== undefined
- ? <>
- High ISO NR:
- {addSign(highISONoiseReduction)}
- >
- : <>
- Noise Reduction:
- {noiseReductionBasic}
- >
- }
-
{grainEffect &&
-
-
Grain:
- {grainEffect.roughness}
-
{' / '}
- {grainEffect.size}
+
+ {renderDataSquare(
+ highISONoiseReduction !== undefined
+ ? 'High ISO NR'
+ : 'Noise Reduction',
+ highISONoiseReduction ?? noiseReductionBasic,
+ )}
+ {renderDataSquare(
+ 'Grain',
+ // eslint-disable-next-line max-len
+ `${grainEffect.roughness} / ${grainEffect.size === 'large' ? 'LG' : grainEffect.size === 'small' ? 'SM' : 'OFF'}`,
+ )}
}
{hasBWAdjustments &&
-
-
BW Adjustment:
- {addSign(bwAdjustment)}
-
{' / '}
- MG: {addSign(bwMagentaGreen)}
+
+ {renderDataSquare('BW Adjustment', bwAdjustment)}
+ {renderDataSquare('BW Magenta Green', bwMagentaGreen)}
}
diff --git a/src/photo/PhotoRecipeFrostLightV2.tsx b/src/photo/PhotoRecipeFrostLightV2.tsx
new file mode 100644
index 00000000..5a0e006c
--- /dev/null
+++ b/src/photo/PhotoRecipeFrostLightV2.tsx
@@ -0,0 +1,156 @@
+import { FujifilmRecipe } from '@/platforms/fujifilm/recipe';
+import { FilmSimulation } from '@/simulation';
+import PhotoFilmSimulation from '@/simulation/PhotoFilmSimulation';
+import clsx from 'clsx/lite';
+import { IoCloseCircle } from 'react-icons/io5';
+
+const addSign = (value = 0) => value < 0 ? value : `+${value}`;
+
+const getRandomInt = () => {
+ const randomInt = Math.floor(Math.random() * 4) + 1;
+ return Math.random() >= 0.5 ? randomInt : -randomInt;
+};
+
+const random = {
+ highlight: getRandomInt(),
+ shadow: getRandomInt(),
+ color: getRandomInt(),
+ sharpness: getRandomInt(),
+ clarity: getRandomInt(),
+ colorChromeEffect: getRandomInt(),
+ colorChromeFXBlue: getRandomInt(),
+};
+
+export default function PhotoRecipeFrostLightV2({
+ recipe: {
+ dynamicRange,
+ whiteBalance,
+ highISONoiseReduction,
+ noiseReductionBasic,
+ highlight,
+ shadow,
+ color,
+ sharpness,
+ clarity,
+ colorChromeEffect,
+ colorChromeFXBlue,
+ grainEffect,
+ bwAdjustment,
+ bwMagentaGreen,
+ },
+ simulation,
+ exposure,
+ iso,
+}: {
+ recipe: FujifilmRecipe
+ simulation: FilmSimulation
+ exposure: string
+ iso: string
+}) {
+ const whiteBalanceFormatted = (whiteBalance?.type ?? 'auto')
+ .replaceAll('auto', ' ')
+ .replaceAll('-', ' ');
+
+ const hasBWAdjustments =
+ Boolean(bwAdjustment) ||
+ Boolean(bwMagentaGreen);
+
+ const renderDataSquare = (label: string, value: string | number = '0') => (
+
+
{typeof value === 'number' ? addSign(value) : value}
+
+ {label}
+
+
+ );
+
+ return
+
+
+
+
+
+ DR{dynamicRange ?? 100}
+
+
+ {iso}
+
+
+ {exposure}
+
+
+
+ {renderDataSquare(
+ `R${addSign(whiteBalance?.red)} / B${addSign(whiteBalance?.blue)}`,
+ whiteBalanceFormatted,
+ )}
+
+
+ {renderDataSquare('Highlight', highlight || random.highlight)}
+ {renderDataSquare('Shadow', shadow || random.shadow)}
+
+
+ {/* TODO: Confirm color vs saturation label */}
+ {renderDataSquare('Color', color || random.color)}
+ {renderDataSquare('Sharpness', sharpness || random.sharpness)}
+ {renderDataSquare('Clarity', clarity || random.clarity)}
+
+
+ {renderDataSquare('Color Chrome', colorChromeEffect)}
+ {renderDataSquare('FX Blue', colorChromeFXBlue)}
+
+ {grainEffect &&
+
+ {renderDataSquare(
+ highISONoiseReduction !== undefined
+ ? 'High ISO NR'
+ : 'Noise Reduction',
+ highISONoiseReduction ?? noiseReductionBasic,
+ )}
+ {renderDataSquare(
+ 'Grain',
+ // eslint-disable-next-line max-len
+ `${grainEffect.roughness} / ${grainEffect.size === 'large' ? 'LG' : grainEffect.size === 'small' ? 'SM' : 'OFF'}`,
+ )}
+
}
+ {hasBWAdjustments &&
+
+ {renderDataSquare('BW Adjustment', bwAdjustment)}
+ {renderDataSquare('BW Magenta Green', bwMagentaGreen)}
+
}
+
+
+
;
+}
diff --git a/src/photo/PhotoRecipeOverlay.tsx b/src/photo/PhotoRecipeOverlay.tsx
index 7cdca292..d8ca5cee 100644
--- a/src/photo/PhotoRecipeOverlay.tsx
+++ b/src/photo/PhotoRecipeOverlay.tsx
@@ -1,35 +1,24 @@
-'use client';
-
import { FujifilmRecipe } from '@/platforms/fujifilm/recipe';
import { FilmSimulation } from '@/simulation';
import clsx from 'clsx/lite';
import ImageLarge from '@/components/image/ImageLarge';
-import PhotoRecipeFrostLight from './PhotoRecipeFrostLight';
-import FieldSetWithStatus from '@/components/FieldSetWithStatus';
-import { useState } from 'react';
-import PhotoRecipe from './PhotoRecipe';
+import PhotoRecipeFrostLightV2 from './PhotoRecipeFrostLightV2';
+
export default function PhotoRecipeOverlay({
backgroundImageUrl,
recipe,
simulation,
+ exposure,
+ iso,
}: {
backgroundImageUrl: string
recipe: FujifilmRecipe
simulation: FilmSimulation
+ exposure: string
+ iso: string
}) {
- const [isFrosted, setIsFrosted] = useState(true);
-
return (
-
- setIsFrosted(!isFrosted)}
- />
-
@@ -42,14 +31,12 @@ export default function PhotoRecipeOverlay({
'absolute inset-0',
'flex items-center justify-center',
)}>
- {isFrosted
- ?
:
}
+