Initial commit
This commit is contained in:
+326
@@ -0,0 +1,326 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CSG Image Upload Tool — CollisionStoneGuard</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Header -->
|
||||
<header id="app-header">
|
||||
<div class="header-inner">
|
||||
<div class="header-brand">
|
||||
<img id="header-logo" src="watermark.png" alt="CSG" onerror="this.style.display='none'">
|
||||
<div>
|
||||
<h1>CSG Image Tool</h1>
|
||||
<p>CollisionStoneGuard Product Photo Uploader</p>
|
||||
</div>
|
||||
</div>
|
||||
<button id="btn-settings" class="btn-icon" title="Settings">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
<path
|
||||
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Step Progress -->
|
||||
<nav id="steps-nav">
|
||||
<div class="step active" data-step="1">
|
||||
<div class="step-num">1</div><span>Import</span>
|
||||
</div>
|
||||
<div class="step-connector"></div>
|
||||
<div class="step" data-step="2">
|
||||
<div class="step-num">2</div><span>Process</span>
|
||||
</div>
|
||||
<div class="step-connector"></div>
|
||||
<div class="step" data-step="3">
|
||||
<div class="step-num">3</div><span>Upload</span>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main id="app-main">
|
||||
|
||||
<!-- STEP 1: Import -->
|
||||
<section id="step-1" class="step-panel active">
|
||||
<div class="panel-header">
|
||||
<h2>Import Photos</h2>
|
||||
</div>
|
||||
|
||||
<div id="drop-zone">
|
||||
<div class="drop-zone-inner">
|
||||
<div class="drop-icon">
|
||||
<svg viewBox="0 0 64 64" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<rect x="8" y="8" width="48" height="48" rx="4" />
|
||||
<path d="M8 44l12-12 8 8 10-14 10 18" />
|
||||
<circle cx="20" cy="24" r="4" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Drop photos here</h3>
|
||||
<p>From your DPP4 output folder or any folder</p>
|
||||
<div class="drop-actions">
|
||||
<button id="btn-browse-files" class="btn-primary">Browse Files</button>
|
||||
<button id="btn-browse-folder" class="btn-secondary">Browse Folder</button>
|
||||
</div>
|
||||
<input type="file" id="input-files" accept="image/*" multiple hidden>
|
||||
<input type="file" id="input-folder" accept="image/*" webkitdirectory multiple hidden>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="import-preview" class="hidden">
|
||||
<div class="preview-toolbar">
|
||||
<span id="import-count"></span>
|
||||
<button id="btn-clear-import" class="btn-ghost">✕ Clear</button>
|
||||
</div>
|
||||
<div id="import-grid" class="thumb-grid"></div>
|
||||
<div class="step-actions">
|
||||
<button id="btn-to-process" class="btn-primary btn-lg">Process Images →</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- STEP 2: Process -->
|
||||
<section id="step-2" class="step-panel">
|
||||
<div class="panel-header">
|
||||
<h2>Process & Preview</h2>
|
||||
<button id="btn-process-all" class="btn-primary">⚡ Process All</button>
|
||||
</div>
|
||||
|
||||
<div class="options-bar">
|
||||
<div class="option-group" title="Adjust JPEG/WebP compression. Higher = better quality, lower = smaller file size.">
|
||||
<label>Quality <span id="quality-display">75</span>%</label>
|
||||
<input type="range" id="quality-slider" min="30" max="100" value="75">
|
||||
</div>
|
||||
<div class="option-group" title="Sensitivity of background removal. Higher removes more background, lower preserves more detail.">
|
||||
<label>BG Tolerance <span id="bg-tol-display">25</span></label>
|
||||
<input type="range" id="bg-tol-slider" min="5" max="200" value="25">
|
||||
</div>
|
||||
<label class="toggle-label" title="Enable to automatically remove the photo background.">
|
||||
<input type="checkbox" id="toggle-bg" checked>
|
||||
<span class="toggle-track"></span>
|
||||
Remove BG
|
||||
</label>
|
||||
<label class="toggle-label" title="Turn the part into a solid black silhouette (perfect for black parts with glare).">
|
||||
<input type="checkbox" id="toggle-silhouette">
|
||||
<span class="toggle-track"></span>
|
||||
Solid Black
|
||||
</label>
|
||||
<label class="toggle-label" title="Add a soft, professional drop shadow to the subject.">
|
||||
<input type="checkbox" id="toggle-shadow" checked>
|
||||
<span class="toggle-track"></span>
|
||||
Drop Shadow
|
||||
</label>
|
||||
<label class="toggle-label" title="Overlay the CSG watermark on the processed image.">
|
||||
<input type="checkbox" id="toggle-watermark" checked>
|
||||
<span class="toggle-track"></span>
|
||||
Watermark
|
||||
</label>
|
||||
<label class="toggle-label" title="Automatically crop to the subject and center it on a square canvas.">
|
||||
<input type="checkbox" id="toggle-crop" checked>
|
||||
<span class="toggle-track"></span>
|
||||
Center & Crop
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div id="process-grid" class="process-grid"></div>
|
||||
|
||||
<div class="step-actions">
|
||||
<button id="btn-back-to-1" class="btn-ghost">← Back</button>
|
||||
<button id="btn-to-upload" class="btn-primary btn-lg">Upload to WooCommerce →</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- STEP 3: Upload -->
|
||||
<section id="step-3" class="step-panel">
|
||||
<div class="panel-header">
|
||||
<h2>Upload to WooCommerce</h2>
|
||||
<button id="btn-upload-all" class="btn-success">⬆ Upload All</button>
|
||||
</div>
|
||||
|
||||
<div id="upload-grid" class="upload-grid"></div>
|
||||
|
||||
<div class="step-actions">
|
||||
<button id="btn-back-to-2" class="btn-ghost">← Back</button>
|
||||
<button id="btn-start-over" class="btn-secondary" title="Clear everything and start from the beginning.">↺ Start Over</button>
|
||||
</div>
|
||||
|
||||
<div id="upload-log" class="hidden">
|
||||
<h3>Upload Log</h3>
|
||||
<div id="log-entries"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Settings Modal -->
|
||||
<div id="settings-modal" class="modal hidden">
|
||||
<div class="modal-backdrop" id="modal-backdrop"></div>
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h2>Settings</h2>
|
||||
<button id="btn-close-settings" class="btn-icon">✕</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="settings-section">
|
||||
<h3>WooCommerce API</h3>
|
||||
<div class="form-group">
|
||||
<label for="s-url">Site URL</label>
|
||||
<input type="url" id="s-url" placeholder="https://collisionstoneguard.com">
|
||||
</div>
|
||||
<div class="form-group input-reveal-row">
|
||||
<label for="s-ck">Consumer Key</label>
|
||||
<input type="password" id="s-ck" placeholder="ck_..." title="WooCommerce REST API Consumer Key (found in WC > Settings > Advanced > REST API)">
|
||||
<button class="btn-reveal" data-target="s-ck">👁</button>
|
||||
</div>
|
||||
<div class="form-group input-reveal-row">
|
||||
<label for="s-cs">Consumer Secret</label>
|
||||
<input type="password" id="s-cs" placeholder="cs_..." title="WooCommerce REST API Consumer Secret">
|
||||
<button class="btn-reveal" data-target="s-cs">👁</button>
|
||||
</div>
|
||||
<button id="btn-test-api" class="btn-secondary">Test Connection</button>
|
||||
<div id="api-status"></div>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h3>WordPress Auth (Media Library)</h3>
|
||||
<p style="font-size: 11px; color: var(--text-dim); margin-bottom: 10px;">
|
||||
If media uploads fail with 401/Unauthorized, enter a WordPress User and <a href="https://wordpress.org/support/article/application-passwords/" target="_blank" style="color: var(--accent);">Application Password</a>.
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<label>WP Username</label>
|
||||
<input type="text" id="s-wp-user" placeholder="admin">
|
||||
</div>
|
||||
<div class="form-group input-reveal-row">
|
||||
<label>Application Password</label>
|
||||
<input type="password" id="s-wp-pass" placeholder="xxxx xxxx xxxx xxxx">
|
||||
<button class="btn-reveal" data-target="s-wp-pass">👁</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h3>Watermark Image</h3>
|
||||
<div class="form-group">
|
||||
<div class="watermark-row">
|
||||
<img id="wm-preview" src="watermark.png" alt="Watermark preview"
|
||||
onerror="this.src=''; this.alt='No image loaded'">
|
||||
<button id="btn-load-wm" class="btn-secondary">Change Image</button>
|
||||
<input type="file" id="input-wm" accept="image/png,image/svg+xml" hidden>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Opacity <span id="wm-opacity-display">30</span>%</label>
|
||||
<input type="range" id="s-wm-opacity" min="5" max="80" value="30">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Size <span id="wm-size-display">25</span>% of image width</label>
|
||||
<input type="range" id="s-wm-size" min="5" max="50" value="25">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h3>Background Removal</h3>
|
||||
<div class="form-group">
|
||||
<label>Color Tolerance <span id="bg-thresh-display">35</span></label>
|
||||
<input type="range" id="s-bg-thresh" min="5" max="80" value="35">
|
||||
<small>Higher = removes more background variation. Lower = more precise edges.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h3>Output Size</h3>
|
||||
<div class="form-group">
|
||||
<label>Max Dimension <span id="max-dim-display">1500</span>px</label>
|
||||
<input type="range" id="s-max-dim" min="600" max="4000" step="100" value="1500" title="The maximum width or height of the exported image.">
|
||||
<small>Longest side limit. Transparent images export as WebP (alpha + lossy = small file).</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="btn-save-settings" class="btn-primary">Save Settings</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Editor Modal -->
|
||||
<div id="editor-modal" class="modal hidden">
|
||||
<div class="modal-backdrop" id="editor-backdrop"></div>
|
||||
<div class="editor-box">
|
||||
<div class="editor-top">
|
||||
<span id="editor-filename"></span>
|
||||
<div class="editor-top-actions">
|
||||
<button id="ed-apply" class="btn-success">✓ Apply</button>
|
||||
<button id="ed-close-btn" class="btn-icon">✕</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-body">
|
||||
<div class="editor-preview-wrap" id="ed-preview-wrap">
|
||||
<div id="ed-zoom-container">
|
||||
<canvas id="ed-canvas"></canvas>
|
||||
<canvas id="ed-overlay-canvas" style="position: absolute; pointer-events: none; z-index: 8;"></canvas>
|
||||
<img id="ed-wm-img" class="ed-wm-draggable" draggable="false" alt="watermark">
|
||||
<div id="ed-selection-box" class="selection-box hidden"></div>
|
||||
</div>
|
||||
<div id="ed-loader" class="editor-loader hidden">
|
||||
<div class="spinner"></div>
|
||||
<span>Processing...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-sidebar">
|
||||
<div class="editor-tool-group">
|
||||
<button id="ed-tool-move" class="btn-tool active" title="Move Watermark: Click and drag the logo to reposition it.">✋</button>
|
||||
<button id="ed-tool-box" class="btn-tool" title="Box Cutout: Draw a rectangle to clear anything outside the subject.">⛶</button>
|
||||
<button id="ed-tool-lasso" class="btn-tool" title="Lasso Cutout: Draw a freehand shape around the subject to clear the background.">➰</button>
|
||||
<button id="ed-tool-erase" class="btn-tool" title="Lasso Erase: Draw a shape around any leftover shadow/background to delete it.">🧽</button>
|
||||
<button id="ed-tool-nudge" class="btn-tool" title="Nudge Part: Click and drag the product to fine-tune its position in the frame.">🎯</button>
|
||||
</div>
|
||||
<div class="form-group" title="Adjust sensitivity for this specific image.">
|
||||
<label>BG Tolerance <strong id="ed-thresh-val">25</strong></label>
|
||||
<input type="range" id="ed-thresh" min="5" max="200" value="25">
|
||||
</div>
|
||||
<div class="form-group" title="Add extra breathing room around the product.">
|
||||
<label>Crop Padding <strong id="ed-pad-val">5</strong>%</label>
|
||||
<input type="range" id="ed-pad" min="0" max="25" value="5">
|
||||
</div>
|
||||
<div class="form-group" title="Adjust the scale of the watermark for this image.">
|
||||
<label>Watermark Size <strong id="ed-wm-sz-val">25</strong>%</label>
|
||||
<input type="range" id="ed-wm-sz" min="5" max="50" value="25">
|
||||
</div>
|
||||
<div class="form-group" title="Adjust the darkness of the drop shadow.">
|
||||
<label>Shadow Intensity <strong id="ed-shadow-val">22</strong>%</label>
|
||||
<input type="range" id="ed-shadow" min="0" max="100" value="22">
|
||||
</div>
|
||||
<label class="toggle-label" title="Show a solid white background instead of the checkerboard.">
|
||||
<span>White Preview</span>
|
||||
<input type="checkbox" id="ed-white-bg">
|
||||
<span class="toggle-track"></span>
|
||||
</label>
|
||||
<label class="toggle-label" title="Turn the subject into a solid black silhouette.">
|
||||
<span>Solid Black</span>
|
||||
<input type="checkbox" id="ed-solid-black">
|
||||
<span class="toggle-track"></span>
|
||||
</label>
|
||||
<button id="ed-clear-erase" class="btn-secondary" style="width:100%;margin-top:8px" title="Clear all manual erase paths.">✕ Clear Erases</button>
|
||||
<button id="ed-reset" class="btn-danger-outline" style="width:100%;margin-top:8px" title="Undo all manual changes for this image and reset to global defaults.">↺ Reset All Changes</button>
|
||||
<p class="editor-hint">Use Box/Lasso tools to trace the subject, and Move/Nudge tools to position items.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hidden processing canvas -->
|
||||
<canvas id="proc-canvas" style="display:none"></canvas>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user