diff --git a/attached_assets/image_1760182750418.png b/attached_assets/image_1760182750418.png new file mode 100644 index 0000000..3ba190d Binary files /dev/null and b/attached_assets/image_1760182750418.png differ diff --git a/client/src/pages/image-editor.tsx b/client/src/pages/image-editor.tsx index 095fea2..aa4a96a 100644 --- a/client/src/pages/image-editor.tsx +++ b/client/src/pages/image-editor.tsx @@ -43,7 +43,11 @@ interface Filters { saturation: number; blur: number; sharpen: number; - effect: "none" | "grayscale" | "sepia" | "vintage"; + vibrance: number; + hue: number; + gamma: number; + vignette: number; + effect: "none" | "grayscale" | "sepia" | "vintage" | "incognito" | "athena" | "audrey"; } export default function ImageEditor() { @@ -77,6 +81,10 @@ export default function ImageEditor() { saturation: 0, blur: 0, sharpen: 0, + vibrance: 0, + hue: 0, + gamma: 0, + vignette: 0, effect: "none" }); @@ -200,8 +208,43 @@ export default function ImageEditor() { if (filters.sharpen > 0) { transformations.push(`e_sharpen:${filters.sharpen * 100}`); } + if (filters.vibrance !== 0) { + transformations.push(`e_vibrance:${filters.vibrance}`); + } + if (filters.hue !== 0) { + transformations.push(`e_hue:${filters.hue}`); + } + if (filters.gamma !== 0) { + transformations.push(`e_gamma:${filters.gamma}`); + } + if (filters.vignette > 0) { + transformations.push(`e_vignette:${filters.vignette}`); + } if (filters.effect !== "none") { - transformations.push(`e_${filters.effect}`); + // Map effects to proper Cloudinary transformations + switch(filters.effect) { + case "grayscale": + transformations.push("e_grayscale"); + break; + case "sepia": + transformations.push("e_sepia"); + break; + case "vintage": + // Vintage effect: combine sepia + vignette + reduced saturation + transformations.push("e_sepia:50"); + transformations.push("e_vignette:30"); + transformations.push("e_saturation:-20"); + break; + case "incognito": + transformations.push("e_art:incognito"); + break; + case "athena": + transformations.push("e_art:athena"); + break; + case "audrey": + transformations.push("e_art:audrey"); + break; + } } // Note: Ribbon and price badge overlays are rendered as CSS elements in preview @@ -603,7 +646,67 @@ export default function ImageEditor() {
- +
+ + {filters.vibrance} +
+ setFilters({ ...filters, vibrance: value })} + min={-100} + max={100} + step={10} + data-testid="slider-vibrance" + /> +
+ +
+
+ + {filters.hue}° +
+ setFilters({ ...filters, hue: value })} + min={-180} + max={180} + step={10} + data-testid="slider-hue" + /> +
+ +
+
+ + {filters.gamma} +
+ setFilters({ ...filters, gamma: value })} + min={-50} + max={150} + step={10} + data-testid="slider-gamma" + /> +
+ +
+
+ + {filters.vignette} +
+ setFilters({ ...filters, vignette: value })} + min={0} + max={100} + step={10} + data-testid="slider-vignette" + /> +
+ +
+
@@ -684,22 +790,16 @@ export default function ImageEditor() { -
- - -
+ ) : (