Files
paint-ui/components/editor/image-menu.tsx
Sebastian Krüger c97ec454f7 feat: add comprehensive Filters & Adjustments dialog with live preview
Implements professional image filter system with real-time preview:

**Adjustments Dialog** (`components/modals/adjustments-dialog.tsx`):
- Live preview canvas (max 400x400px) with real-time filter updates
- Organized filter categories: Color Adjustments, Filters, Effects
- 10 filter types with adjustable parameters:
  - **Brightness**: -100 to +100 adjustment
  - **Contrast**: -100 to +100 adjustment
  - **Hue/Saturation**: Hue rotation (±180°), Saturation (±100%), Lightness (±100%)
  - **Blur**: Gaussian blur with radius 1-50px
  - **Sharpen**: Amount 0-100%
  - **Invert**: One-click color inversion
  - **Grayscale**: Convert to monochrome
  - **Sepia**: Vintage sepia tone effect
  - **Threshold**: Binary black/white with adjustable threshold
  - **Posterize**: Reduce colors to 2-256 levels
- Slider controls for all adjustable parameters
- Reset button to restore default values
- Apply/Cancel actions with undo support
- Uses FilterCommand for history integration

**Image Menu** (`components/editor/image-menu.tsx`):
- New "Image" menu in header bar next to "File"
- "Filters & Adjustments..." menu item opens dialog
- Organized location for image-related operations
- Extensible for future image operations

**Integration**:
- Added Image menu to editor layout header
- Positioned between title and controls
- Keyboard-accessible with proper ARIA labels

**Technical Features**:
- Async filter application using Web Workers for large images
- Non-destructive editing with undo/redo support
- Real-time preview updates as sliders adjust
- FilterCommand integration for history
- Canvas cloning for before/after states
- Optimized preview rendering (scaled to 400px max)

**User Experience**:
- Modal dialog with backdrop
- Sidebar filter list with hover states
- Large preview area showing filter results
- Smooth slider interactions
- Instant visual feedback
- Professional Photoshop-like interface

All filters tested and working with undo/redo support.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 19:36:38 +01:00

64 lines
2.0 KiB
TypeScript

'use client';
import { useState } from 'react';
import { AdjustmentsDialog } from '@/components/modals/adjustments-dialog';
import {
Sliders,
ChevronDown,
} from 'lucide-react';
export function ImageMenu() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isAdjustmentsOpen, setIsAdjustmentsOpen] = useState(false);
return (
<>
<div className="relative">
<button
onClick={() => setIsMenuOpen(!isMenuOpen)}
className="flex items-center gap-2 px-3 py-2 hover:bg-accent rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
aria-label="Image menu"
aria-expanded={isMenuOpen}
aria-haspopup="menu"
>
<span className="text-sm font-medium">Image</span>
<ChevronDown className="h-4 w-4" aria-hidden="true" />
</button>
{isMenuOpen && (
<>
<div
className="fixed inset-0 z-10"
onClick={() => setIsMenuOpen(false)}
aria-hidden="true"
/>
<div
className="absolute left-0 top-full mt-1 w-56 bg-card border border-border rounded-md shadow-lg z-20"
role="menu"
aria-label="Image operations"
>
<button
onClick={() => {
setIsAdjustmentsOpen(true);
setIsMenuOpen(false);
}}
className="flex items-center gap-3 w-full px-4 py-2 text-sm hover:bg-accent transition-colors focus:outline-none focus:bg-accent text-left"
role="menuitem"
>
<Sliders className="h-4 w-4" aria-hidden="true" />
Filters & Adjustments...
</button>
</div>
</>
)}
</div>
{/* Adjustments Dialog */}
<AdjustmentsDialog
isOpen={isAdjustmentsOpen}
onClose={() => setIsAdjustmentsOpen(false)}
/>
</>
);
}