Add lens bokeh preview panel
This commit is contained in:
+58
@@ -133,6 +133,62 @@ const filterDatasetForPlotType = (dataset, plotType) => {
|
|||||||
return dataset;
|
return dataset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PreviewPanel = ({ lensCurves }) => {
|
||||||
|
const previewItems = lensCurves.map((curve) => {
|
||||||
|
const infinityStat = curve.checkpointStats.find((stat) => !Number.isFinite(stat.separation));
|
||||||
|
const blurPercent = infinityStat?.blurPercentOfDiagonal ?? 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
lens: curve.lens,
|
||||||
|
blurPercent,
|
||||||
|
colorIndex: curve.colorIndex,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const maxBlurPercent = previewItems.reduce((maxValue, item) => Math.max(maxValue, item.blurPercent), 0);
|
||||||
|
const denominator = maxBlurPercent > 0 ? maxBlurPercent : 1;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg border border-slate-800 bg-slate-900/60 p-4">
|
||||||
|
<h2 className="mb-3 text-sm font-semibold uppercase tracking-wide text-slate-400">Bokeh preview</h2>
|
||||||
|
{previewItems.length === 0 ? (
|
||||||
|
<div className="text-sm text-slate-500">Select at least one lens to preview its blur at infinity.</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-wrap justify-center gap-4">
|
||||||
|
{previewItems.map((item) => {
|
||||||
|
const normalized = Math.min(item.blurPercent / denominator, 1);
|
||||||
|
const diameter = Math.max(18, 30 + normalized * 70);
|
||||||
|
const paletteColor = COLOR_PALETTE[item.colorIndex % COLOR_PALETTE.length];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={item.lens.id} className="flex w-32 flex-col items-center gap-2 text-center">
|
||||||
|
<div
|
||||||
|
className="flex items-center justify-center rounded-full border"
|
||||||
|
style={{
|
||||||
|
width: `${diameter}px`,
|
||||||
|
height: `${diameter}px`,
|
||||||
|
borderColor: paletteColor,
|
||||||
|
background: `${paletteColor}1A`,
|
||||||
|
boxShadow: `0 0 12px ${paletteColor}33`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="sr-only">{item.lens.name}</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-slate-200">
|
||||||
|
<div className="font-medium text-slate-100">{item.lens.name}</div>
|
||||||
|
<div className="text-[10px] uppercase tracking-wide text-slate-500">
|
||||||
|
∞ blur {formatNumber(item.blurPercent, 2)}%
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const PlotSection = ({ lensCurves, plotType, setPlotType }) => {
|
const PlotSection = ({ lensCurves, plotType, setPlotType }) => {
|
||||||
const axisConfig = getAxisConfig(plotType);
|
const axisConfig = getAxisConfig(plotType);
|
||||||
|
|
||||||
@@ -704,6 +760,7 @@ const App = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="space-y-6 px-4 pb-6 lg:hidden">
|
<div className="space-y-6 px-4 pb-6 lg:hidden">
|
||||||
|
<PreviewPanel lensCurves={lensCurves} />
|
||||||
<FramingPanel
|
<FramingPanel
|
||||||
framingMode={framingMode}
|
framingMode={framingMode}
|
||||||
setFramingMode={setFramingMode}
|
setFramingMode={setFramingMode}
|
||||||
@@ -741,6 +798,7 @@ const App = () => {
|
|||||||
|
|
||||||
<aside className="hidden w-full max-w-xs border-l border-slate-900/60 bg-slate-950/60 lg:block">
|
<aside className="hidden w-full max-w-xs border-l border-slate-900/60 bg-slate-950/60 lg:block">
|
||||||
<div className="space-y-6 px-4 py-6">
|
<div className="space-y-6 px-4 py-6">
|
||||||
|
<PreviewPanel lensCurves={lensCurves} />
|
||||||
<FramingPanel
|
<FramingPanel
|
||||||
framingMode={framingMode}
|
framingMode={framingMode}
|
||||||
setFramingMode={setFramingMode}
|
setFramingMode={setFramingMode}
|
||||||
|
|||||||
Reference in New Issue
Block a user