feat: v1.1 — highlight-weighted metering, settings modal, photo viewer, shutter sound control, cleanup

This commit is contained in:
2026-09-09 09:41:55 +07:00
parent e9a9005ef2
commit 09dbc72cce
46 changed files with 1684 additions and 2491 deletions
+42 -3
View File
@@ -1,6 +1,4 @@
import { ColorAdjustments } from '../types';
export type BaseFilter = 'classic-neg' | 'provia' | 'velvia' | 'monochrome' | 'none';
import { ColorAdjustments, BaseFilter } from '../types';
// Kelvin to RGB compensation for White Balance.
// In photography, when WB is set HIGH (e.g. 10000K), the camera understands
@@ -75,6 +73,31 @@ export function getSkiaColorMatrix(baseFilter: BaseFilter, adj: ColorAdjustments
-0.05, -0.05, 1.25, 0, -0.02,
0, 0, 0, 1, 0,
];
} else if (baseFilter === 'classic-chrome') {
// Classic Chrome: muted/deep color with strong tone — desaturated reds and
// greens, slight warm amber in highlights, shadows stay soft (approx).
matrix = [
1.12, -0.03, -0.06, 0, 0.04,
-0.04, 1.0, -0.03, 0, 0.03,
-0.05, -0.06, 0.86, 0, -0.02,
0, 0, 0, 1, 0,
];
} else if (baseFilter === 'astia') {
// Astia: soft, gentle, flattering — low contrast, pastel-leaning colors.
matrix = [
1.0, 0.02, 0.02, 0, 0.01,
0.01, 1.0, 0.02, 0, 0.02,
0.01, 0.01, 1.02, 0, 0.02,
0, 0, 0, 1, 0,
];
} else if (baseFilter === 'eterna') {
// Eterna: cinema — flat (low contrast), muted color, gentle highlight rolloff.
matrix = [
0.94, 0.02, 0.02, 0, 0.02,
0.02, 0.96, 0.02, 0, 0.02,
0.02, 0.02, 0.94, 0, 0.02,
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;
@@ -148,6 +171,22 @@ export function getSkiaColorMatrix(baseFilter: BaseFilter, adj: ColorAdjustments
matrix = multiplyMatrices(wbMat, matrix);
}
// 5b. Fuji WB fine-tune Red/Blue axis (the CREATE modal's R/B offsets). These
// axes are independent channel gains on top of the Kelvin/tint preset: each
// step nudges its channel ~1.1% toward/away from neutral, matching the
// perceptible size of one Fuji fine-tune step (-9..+9).
const wbRed = adj.wbRed ?? 0;
const wbBlue = adj.wbBlue ?? 0;
if (baseFilter !== 'monochrome' && (wbRed !== 0 || wbBlue !== 0)) {
const shiftMat = [
1 + (wbRed / 9) * 0.1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1 + (wbBlue / 9) * 0.1, 0, 0,
0, 0, 0, 1, 0,
];
matrix = multiplyMatrices(shiftMat, matrix);
}
// 6. Exposure & Contrast — applied to ALL base filters (monochrome included) so
// both keep affecting mono shots. Contrast scales around mid-grey 0.5.
if (exposure !== 0 || contrast !== 0) {