feat: load background file

This commit is contained in:
2026-06-24 06:48:13 +05:00
parent 680dad30bf
commit 3b49c9f3c2
7 changed files with 242 additions and 3 deletions
@@ -0,0 +1,92 @@
# Plan: Background Image Upload for CSS Matrix Calculator
## Overview
Add ability to load a background image onto the main `#field` element for visual reference when positioning corners. The image is stored as a data URL in memory (no server). Three upload methods: Ctrl+V paste, file picker, drag & drop onto the field. Adjustable via `object-fit` options.
## Files to Modify
### 1. `js/state.js` — Add background state
- Add `bgImage: null` (data URL string) and `objectFit: 'contain'` to `defaultState` and `state`
- Reset these in `resetState()`
### 2. `index.html` — New "Background" panel + hidden file input
Add a new panel in `right-col` (between Field and Widget panels, after line 78):
```html
<div class="panel">
<h2>Background</h2>
<div class="bg-controls">
<input type="file" id="bgFileInput" accept="image/*" hidden />
<button class="btn btn-edit-field" id="btnBgLoad">Load Image</button>
<button class="btn btn-cancel-field" id="btnBgRemove" style="display:none">Remove</button>
<select id="bgObjectFit">
<option value="contain">contain</option>
<option value="cover">cover</option>
<option value="fill">fill</option>
<option value="none">none</option>
<option value="scale-down">scale-down</option>
</select>
</div>
</div>
```
Add drag & drop hint overlay on `#fieldContainer` (drop zone indicator).
### 3. `style.css` — New styles
- `.bg-controls` — flex row layout for controls
- `#bgObjectFit` — styled select matching existing dark theme
- `#fieldContainer.drag-over` — dashed border highlight for drop feedback
- `#field` — add `background-size`, `background-position`, `background-repeat` properties
- `.bg-hint` — overlay text on field when no image loaded ("Drop image or Ctrl+V")
### 4. `js/ui.js` — Event handlers
- `btnBgLoad` click → trigger hidden file input
- `bgFileInput` change → read file as data URL via `FileReader``state.bgImage = dataUrl`
- `document` paste event → detect image in `clipboardData.files` → read as data URL
- `#fieldContainer` dragover/drop → read dropped file as data URL
- `btnBgRemove` click → clear `state.bgImage`
- `bgObjectFit` change → `state.objectFit = value`
- Toggle remove button visibility based on whether image is loaded
- On state change: call `updateAll()`
### 5. `js/preview.js` — Apply background to field
- If `state.bgImage`: set `field.style.backgroundImage = url(...)`, `field.style.backgroundSize`, `field.style.backgroundPosition`, `field.style.backgroundRepeat` based on objectFit
- If no image: clear background properties
### 6. `js/svg-renderer.js` — Show background in SVG editor
- If `state.bgImage`: add an `<image>` element as first child of SVG (behind grid) with `href`, `width`, `height`, and `preserveAspectRatio` matching the objectFit mapping
### 7. `js/main.js` — No changes needed (updateAll already propagates)
## Implementation Details
### Image loading flow
1. User triggers upload (paste/file/drop) → get `File` object
2. `FileReader.readAsDataURL(file)` → get data URL string
3. Store in `state.bgImage`
4. Call `updateAll()` to propagate
### object-fit mapping to SVG preserveAspectRatio
| objectFit | SVG preserveAspectRatio |
|---------------|------------------------|
| contain | xMidYMid meet |
| cover | xMidYMid slice |
| fill | none |
| none | xMinYMin meet |
| scale-down | xMidYMid meet |
### Keyboard shortcut
- Ctrl+V paste listener on `document` — check for image in clipboard items
- Only active when no input/textarea is focused (to avoid conflicts)
### Drag & drop
- Listen on `#fieldContainer` for `dragover` (prevent default, show visual hint) and `drop` (read file)
## Verification
1. Open `index.html` in browser
2. **File picker**: Click "Load Image" → select image → verify it appears as background on the field in both edit (SVG) and preview modes
3. **Ctrl+V**: Copy an image to clipboard → press Ctrl+V → verify it loads
4. **Drag & drop**: Drag an image file onto the field area → verify it loads
5. **object-fit**: Change dropdown → verify background resizes correctly (contain fits, cover fills, etc.)
6. **Remove**: Click "Remove" → verify background clears
7. **Reset**: Click "Reset" → verify background clears along with other state
8. **Corner drag**: Load background → drag corners → verify background stays in place, corners move independently