feat(presets): add LEICA simulation chip; collapse recipe strip on sim select
This commit is contained in:
@@ -302,7 +302,13 @@ export default function AdjustmentPanel({
|
||||
key: s.id,
|
||||
label: s.name,
|
||||
active: currentRecipeId === s.id,
|
||||
onPress: () => onSelectRecipe(filmSimToRecipe(s)),
|
||||
// Choosing a simulation is a deliberate switch away from the saved
|
||||
// recipes: collapse the RECIPES strip above so it never lingers
|
||||
// over the freshly-applied sim.
|
||||
onPress: () => {
|
||||
setShowRecipes(false);
|
||||
onSelectRecipe(filmSimToRecipe(s));
|
||||
},
|
||||
})),
|
||||
{
|
||||
key: 'recipes-toggle',
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ export const ASPECT_RATIO_W_H: Record<Exclude<AspectRatio, 'full'>, number> = {
|
||||
// cool tint in shade, plus a seasonal atmospheric haze/fog veil.
|
||||
export type CinemaSeason = 'spring' | 'summer' | 'autumn' | 'winter';
|
||||
|
||||
export type BaseFilter = 'classic-neg' | 'classic-chrome' | 'provia' | 'velvia' | 'astia' | 'eterna' | 'monochrome' | 'none';
|
||||
export type BaseFilter = 'classic-neg' | 'classic-chrome' | 'provia' | 'velvia' | 'astia' | 'eterna' | 'monochrome' | 'leica' | 'none';
|
||||
|
||||
export interface ColorAdjustments {
|
||||
exposure: number; // -10 to +10 (mapped to matrix multiplier or offset)
|
||||
|
||||
@@ -98,6 +98,22 @@ export function getSkiaColorMatrix(baseFilter: BaseFilter, adj: ColorAdjustments
|
||||
0.02, 0.02, 0.94, 0, 0.02,
|
||||
0, 0, 0, 1, 0,
|
||||
];
|
||||
} else if (baseFilter === 'leica') {
|
||||
// Leica digital look (M/Q/SL): neutral-but-warm, deep yet open shadows,
|
||||
// restrained saturation with deep reds and true greens — never the punchy
|
||||
// chroma of Velvia or the amber of Classic Neg. A linear matrix cannot do
|
||||
// the smooth highlight rolloff (that's the tone shader's job), so this only
|
||||
// carries the mild contrast/warmth/colour balance half:
|
||||
// - gentle contrast around mid-grey (deep blacks, no lifted blacks)
|
||||
// - slight warm cast in highlights (R up, B down), near-neutral white
|
||||
// - reds a touch deeper, blues slightly muted towards natural skies
|
||||
// - green mostly untouched (Leica greens stay true, not olive)
|
||||
matrix = [
|
||||
1.08, -0.02, -0.01, 0, -0.025,
|
||||
-0.015, 1.06, -0.01, 0, -0.017,
|
||||
-0.02, -0.015, 1.04, 0, -0.013,
|
||||
0, 0, 0, 1, 0,
|
||||
];
|
||||
} else if (baseFilter === 'monochrome') {
|
||||
// Acros Monochrome: ITU-R BT.709 luma — pure grayscale, zero color leakage
|
||||
const r = 0.2126;
|
||||
|
||||
@@ -43,6 +43,11 @@ export const FILM_SIMS: FilmSim[] = [
|
||||
{ id: 'sim-astia', name: 'ASTIA', baseFilter: 'astia', adjustments: { ...DEFAULT_ADJUSTMENTS } },
|
||||
{ id: 'sim-eterna', name: 'ETERNA', baseFilter: 'eterna', adjustments: { ...DEFAULT_ADJUSTMENTS } },
|
||||
{ id: 'sim-acros', name: 'ACROS', baseFilter: 'monochrome', adjustments: { ...DEFAULT_ADJUSTMENTS } },
|
||||
// Leica digital look (M/Q/SL) is NOT a film stock: neutral-but-warm colour
|
||||
// with restrained saturation, deep open shadows and gentle highlight rolloff.
|
||||
// Matrix-only here (like every sim) — the tonal half lives in the leica
|
||||
// matrix (mild contrast + warm neutrality); users stack DR/tone on top.
|
||||
{ id: 'sim-leica', name: 'LEICA', baseFilter: 'leica', adjustments: { ...DEFAULT_ADJUSTMENTS } },
|
||||
];
|
||||
|
||||
// Film sim → full Recipe (never persisted; sims are applied on the fly).
|
||||
|
||||
Reference in New Issue
Block a user