Files
advance-photo-gallery-web-sdk/packages/photo-sdk/src/lib/edits.ts
T
2026-07-18 01:34:52 +05:30

57 lines
2.2 KiB
TypeScript

import { FILTER_PRESETS, ZERO_ADJUSTMENTS } from '../constants';
import type { EditAdjustments, EditState } from '../types';
const clamp = (v: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, v));
function resolveAdjustments(edits: EditState): EditAdjustments {
const preset = edits.filter ? FILTER_PRESETS[edits.filter]?.adjustments ?? {} : {};
return { ...ZERO_ADJUSTMENTS, ...preset, ...edits.adjustments };
}
/** Build a CSS `filter` string approximating the adjustment stack. */
export function editFilterCss(edits?: EditState): string | undefined {
if (!edits) return undefined;
const a = resolveAdjustments(edits);
const brightness = clamp(
1 + a.exposure * 0.4 + a.brightness * 0.4 + a.shadows * 0.12 - a.highlights * 0.06,
0.2,
2.2,
);
const contrast = clamp(
1 + a.contrast * 0.5 + a.definition * 0.2 + a.sharpness * 0.15 + a.blackPoint * 0.25,
0.2,
2.6,
);
const saturate = clamp(1 + a.saturation * 0.85 + a.vibrance * 0.35, 0, 3);
const sepia = clamp(Math.max(0, a.warmth) * 0.5, 0, 1);
const hue = (a.warmth < 0 ? a.warmth * 14 : 0) + a.tint * 14;
const parts = [
`brightness(${brightness.toFixed(3)})`,
`contrast(${contrast.toFixed(3)})`,
];
// Heavily desaturated presets read as true monochrome.
if (saturate <= 0.2) parts.push('grayscale(1)');
else parts.push(`saturate(${saturate.toFixed(3)})`);
if (sepia > 0.01) parts.push(`sepia(${sepia.toFixed(3)})`);
if (Math.abs(hue) > 0.5) parts.push(`hue-rotate(${hue.toFixed(1)}deg)`);
return parts.join(' ');
}
/** Build a CSS `transform` for rotation + straighten + flips. */
export function editTransformCss(edits?: EditState): string | undefined {
if (!edits) return undefined;
const straighten = edits.straighten ?? 0;
const rot = (edits.rotation ?? 0) + straighten;
// Scale up slightly when straightening so the rotated image still covers the frame.
const cover = straighten ? 1 + Math.min(0.5, Math.abs(straighten) / 90) : 1;
const sx = (edits.flipH ? -1 : 1) * cover;
const sy = (edits.flipV ? -1 : 1) * cover;
if (!rot && sx === 1 && sy === 1) return undefined;
return `rotate(${rot}deg) scale(${sx}, ${sy})`;
}
export { ZERO_ADJUSTMENTS };