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,
|
key: s.id,
|
||||||
label: s.name,
|
label: s.name,
|
||||||
active: currentRecipeId === s.id,
|
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',
|
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.
|
// cool tint in shade, plus a seasonal atmospheric haze/fog veil.
|
||||||
export type CinemaSeason = 'spring' | 'summer' | 'autumn' | 'winter';
|
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 {
|
export interface ColorAdjustments {
|
||||||
exposure: number; // -10 to +10 (mapped to matrix multiplier or offset)
|
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.02, 0.02, 0.94, 0, 0.02,
|
||||||
0, 0, 0, 1, 0,
|
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') {
|
} else if (baseFilter === 'monochrome') {
|
||||||
// Acros Monochrome: ITU-R BT.709 luma — pure grayscale, zero color leakage
|
// Acros Monochrome: ITU-R BT.709 luma — pure grayscale, zero color leakage
|
||||||
const r = 0.2126;
|
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-astia', name: 'ASTIA', baseFilter: 'astia', adjustments: { ...DEFAULT_ADJUSTMENTS } },
|
||||||
{ id: 'sim-eterna', name: 'ETERNA', baseFilter: 'eterna', adjustments: { ...DEFAULT_ADJUSTMENTS } },
|
{ id: 'sim-eterna', name: 'ETERNA', baseFilter: 'eterna', adjustments: { ...DEFAULT_ADJUSTMENTS } },
|
||||||
{ id: 'sim-acros', name: 'ACROS', baseFilter: 'monochrome', 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).
|
// Film sim → full Recipe (never persisted; sims are applied on the fly).
|
||||||
|
|||||||
Reference in New Issue
Block a user