3.2 KiB
3.2 KiB
Mini Photoshop — Browser Image Editor
Overview
Client-side image editor tool at /editor on images.wadevelop.ru.
All processing via Canvas API — images never leave the browser.
File
/public/editor.html— standalone page (~600 lines)
Layout
- Sidebar (56px) — standard site navigation
- Toolbar (44px top) — Open, Export, drawing tools, transforms, undo/redo, color, zoom
- Tool Options Bar (36px, contextual) — appears when tool selected
- Canvas Viewport (center) — checkerboard bg for transparency, 3 stacked canvases
- Status Bar (28px bottom) — dimensions, zoom%, cursor coords, history position
Canvas Architecture
3 overlaid <canvas> elements:
canvasMain— final imagecanvasOverlay— preview of drawing/crop/filters (cleared each frame)canvasUI— cursors, selection frames
Zoom/pan via CSS transform: translate() scale() on wrapper (GPU-accelerated).
Undo/Redo
- History as PNG blobs (
canvas.toBlob()→URL.createObjectURL()) - Max 30 snapshots
- Ctrl+Z / Ctrl+Shift+Z
Image Loading
- File input (Open button)
- Drag & drop on viewport
- Paste from clipboard (Ctrl+V)
- Before loading — dropzone with hint, toolbar disabled
Tools
Crop
- Presets: Free, 1:1, 4:3, 16:9, 3:2, 2:3, 9:16
- 8 drag handles (corners + edges)
- Semi-transparent overlay outside crop, rule of thirds
- Apply / Cancel buttons
Resize
- Width/height in px, aspect ratio lock (on by default)
imageSmoothingQuality = 'high'- Max 16384x16384
Rotate 90 CW/CCW
- Two buttons in toolbar
- Via temp canvas with
ctx.translate()+ctx.rotate()
Flip H/V
- Two buttons, via
ctx.scale(-1, 1)/ctx.scale(1, -1)
Brightness / Contrast / Saturation
- Three sliders -100...+100
- Preview via CSS
filteron overlay (instant) - Commit via pixel-level ImageData processing
- Apply / Cancel
Brush
- Sliders: size 1-100px, opacity 0-100%
lineCap: 'round',lineJoin: 'round'- Drawing on overlay → commit to main on pointerup
Eraser
- Like brush but
globalCompositeOperation: 'destination-out' - Draws directly on main canvas
Line, Rectangle, Circle, Arrow
- Stroke width 1-20px, fill toggle (rect/circle)
- Shift for snap to 45 degrees (line/arrow) and square/circle (rect/circle)
- Arrow: filled triangle arrowhead
Text
- Font select (sans-serif, serif, monospace, Manrope, JetBrains Mono)
- Size 8-200px, Bold, Italic, Color
- Click on canvas →
<textarea>at position → Ctrl+Enter to commit ctx.fillText()with multiline text support
Color Picker (Eyedropper)
- Click →
getImageData(x, y, 1, 1)→ hex → sets as foreground color - Color chosen via native
<input type="color">
Export
- Formats: PNG, JPEG, WebP
- Quality 1-100 (for JPEG/WebP)
- Filename (pre-filled from original)
- Warning for JPEG + transparency
canvas.toBlob()→ download via<a download>
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
| Ctrl+O | Open |
| Ctrl+S | Export |
| Ctrl+Z | Undo |
| Ctrl+Shift+Z | Redo |
| B | Brush |
| E | Eraser |
| T | Text |
| C | Crop |
| L | Line |
| U | Rectangle |
| O | Ellipse |
| A | Arrow |
| I | Eyedropper |
| [ / ] | Brush size +/- |
| Space+drag | Pan |
| Ctrl+scroll | Zoom |
| Ctrl+0 | Fit |
| Ctrl+1 | 100% |
| Escape | Cancel |