4.4 KiB
4.4 KiB
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) andobjectFit: 'contain'todefaultStateandstate - 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):
<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— addbackground-size,background-position,background-repeatproperties.bg-hint— overlay text on field when no image loaded ("Drop image or Ctrl+V")
4. js/ui.js — Event handlers
btnBgLoadclick → trigger hidden file inputbgFileInputchange → read file as data URL viaFileReader→state.bgImage = dataUrldocumentpaste event → detect image inclipboardData.files→ read as data URL#fieldContainerdragover/drop → read dropped file as data URLbtnBgRemoveclick → clearstate.bgImagebgObjectFitchange →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: setfield.style.backgroundImage = url(...),field.style.backgroundSize,field.style.backgroundPosition,field.style.backgroundRepeatbased 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) withhref,width,height, andpreserveAspectRatiomatching the objectFit mapping
7. js/main.js — No changes needed (updateAll already propagates)
Implementation Details
Image loading flow
- User triggers upload (paste/file/drop) → get
Fileobject FileReader.readAsDataURL(file)→ get data URL string- Store in
state.bgImage - 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
#fieldContainerfordragover(prevent default, show visual hint) anddrop(read file)
Verification
- Open
index.htmlin browser - File picker: Click "Load Image" → select image → verify it appears as background on the field in both edit (SVG) and preview modes
- Ctrl+V: Copy an image to clipboard → press Ctrl+V → verify it loads
- Drag & drop: Drag an image file onto the field area → verify it loads
- object-fit: Change dropdown → verify background resizes correctly (contain fits, cover fills, etc.)
- Remove: Click "Remove" → verify background clears
- Reset: Click "Reset" → verify background clears along with other state
- Corner drag: Load background → drag corners → verify background stays in place, corners move independently