Files
dekupai/index.html
T

339 lines
17 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dekupai - Turunçgil AI Dekupaj</title>
<!-- Google Fonts: Inter & Outfit -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<!-- CropperJS CSS from node_modules (linked locally) -->
<link rel="stylesheet" href="node_modules/cropperjs/dist/cropper.css">
<!-- Main Stylesheet -->
<link rel="stylesheet" href="styles.css">
</head>
<body>
<!-- Ambient Background Orbs -->
<div class="ambient-glow bg-orb-1"></div>
<div class="ambient-glow bg-orb-2"></div>
<!-- Custom Sleek Glass Titlebar -->
<header class="app-titlebar">
<div class="titlebar-logo">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L2 7L12 12L22 7L12 2Z" fill="url(#neon-grad)" stroke="#fff" stroke-opacity="0.2" stroke-width="1.5"/>
<path d="M2 17L12 22L22 17" stroke="url(#neon-grad)" stroke-width="2" stroke-linecap="round"/>
<path d="M2 12L12 17L22 12" stroke="#a78bfa" stroke-opacity="0.5" stroke-width="1.5" stroke-linecap="round"/>
<defs>
<linearGradient id="neon-grad" x1="2" y1="2" x2="22" y2="22" gradientUnits="userSpaceOnUse">
<stop stop-color="#ff7a00"/>
<stop offset="1" stop-color="#ffb800"/>
</linearGradient>
</defs>
</svg>
<span>DEKUPAI</span>
<span class="badge">Turunçgil AI</span>
</div>
<div class="titlebar-controls">
<button class="win-btn min-btn" id="win-min" title="Minimize">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="5" y1="12" x2="19" y2="12"></line></svg>
</button>
<button class="win-btn max-btn" id="win-max" title="Maximize">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="5" y="5" width="14" height="14" rx="2"></rect></svg>
</button>
<button class="win-btn close-btn" id="win-close" title="Close">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
</button>
</div>
</header>
<!-- Setup Overlay (Displayed if environment is missing) -->
<div class="overlay-container glass-panel hidden" id="setup-overlay">
<div class="setup-wizard text-center">
<div class="wizard-header">
<div class="glow-icon-container">
<svg class="glow-icon animated-float" width="64" height="64" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2V6M12 18V22M4.93 4.93L7.76 7.76M16.24 16.24L19.07 19.07M2 12H6M18 12H22M4.93 19.07L7.76 16.24M16.24 7.76L19.07 4.93" stroke="url(#neon-grad)" stroke-width="2" stroke-linecap="round"/>
<circle cx="12" cy="12" r="4" fill="url(#neon-grad)" opacity="0.3"/>
</svg>
</div>
<h1>Initializing AI Engine</h1>
<p class="subtitle">Dekupai requires a local Python environment to run the BiRefNet neural network models.</p>
</div>
<div class="setup-progress-box glass-panel-inner">
<div class="setup-steps">
<div class="step-item" id="step-venv">
<span class="step-dot"></span>
<span class="step-text">Creating isolated virtual environment (.venv)</span>
</div>
<div class="step-item" id="step-pip">
<span class="step-dot"></span>
<span class="step-text">Upgrading Python package installer (pip)</span>
</div>
<div class="step-item" id="step-deps">
<span class="step-dot"></span>
<span class="step-text">Installing PyTorch AI Engine (CPU version)</span>
</div>
<div class="step-item" id="step-libs">
<span class="step-dot"></span>
<span class="step-text">Installing HuggingFace Transformers & PIL library</span>
</div>
</div>
<div class="progress-bar-container">
<div class="progress-bar" id="setup-progress-bar"></div>
</div>
<div class="progress-status" id="setup-status-text">Ready to configure environment.</div>
</div>
<div class="wizard-actions">
<button class="btn btn-primary" id="btn-start-setup">
<span>Configure Engine (Automatic)</span>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
</button>
</div>
</div>
</div>
<!-- Main Grid Workspace -->
<main class="app-workspace">
<!-- Left Workspace Screen -->
<section class="workspace-viewport glass-panel">
<!-- Empty Dropzone State -->
<div class="dropzone" id="dropzone">
<div class="dropzone-content">
<div class="dropzone-glow-icon">
<svg width="56" height="56" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
<circle cx="8.5" cy="8.5" r="1.5"></circle>
<polyline points="21 15 16 10 5 21"></polyline>
</svg>
</div>
<h2>Drag & Drop Image Here</h2>
<p class="dropzone-sub">Supports PNG, JPG, JPEG, or WebP formats</p>
<div class="or-separator"><span>OR</span></div>
<button class="btn btn-glass" id="btn-browse">
<span>Browse Local Files</span>
</button>
</div>
</div>
<!-- Editor Canvas Workspace -->
<div class="editor-container hidden" id="editor-container">
<!-- Checkerboard patterned preview -->
<div class="preview-canvas-wrapper checkerboard" id="canvas-wrapper">
<img id="image-element" src="" alt="Workspace Image">
<div class="canvas-ambient-backdrop" id="canvas-bg-overlay"></div>
</div>
<!-- Float Crop Workspace Controls -->
<div class="editor-controls glass-panel-inner">
<div class="btn-group">
<button class="ctrl-btn" id="ctrl-crop-drag" title="Drag / Navigate Image" class="active">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 9l-3 3 3 3M9 5l3-3 3 3M15 19l-3 3-3-3M19 9l3 3-3 3M2 12h20M12 2v20"></path></svg>
</button>
<button class="ctrl-btn" id="ctrl-crop-box" title="Crop Selection Box">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 16V8a2 2 0 0 0-2-2h-5m-9 0h5M3 8v8a2 2 0 0 0 2 2h8m9 0h-5"></path><path d="M10 2L2 10m20 4l-8 8"></path></svg>
</button>
</div>
<div class="divider-v"></div>
<div class="btn-group">
<button class="ctrl-btn" id="ctrl-rot-l" title="Rotate Left 90°">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21.5 2v6h-6M21.34 8a10 10 0 1 0-.45 7"></path></svg>
</button>
<button class="ctrl-btn" id="ctrl-rot-r" title="Rotate Right 90°">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M2.5 2v6h6M2.66 8a10 10 0 1 1 .45 7"></path></svg>
</button>
<button class="ctrl-btn" id="ctrl-flip-h" title="Flip Horizontal">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v20M2 12h20M7 8l-5 4 5 4M17 8l5 4-5 4"></path></svg>
</button>
<button class="ctrl-btn" id="ctrl-flip-v" title="Flip Vertical">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v20M2 12h20M8 7l4-5 4 5M8 17l4 5 4-5"></path></svg>
</button>
</div>
<div class="divider-v"></div>
<!-- Aspect ratio selectors -->
<div class="aspect-presets select-wrapper">
<select id="crop-ratio-select">
<option value="NaN">Free Crop</option>
<option value="1">1:1 Square</option>
<option value="1.77777777778">16:9 Cinema</option>
<option value="1.33333333333">4:3 Photo</option>
<option value="0.75">3:4 Portrait</option>
<option value="0.5625">9:16 Story</option>
</select>
</div>
<div class="divider-v"></div>
<button class="btn btn-secondary btn-sm glow-btn-purple" id="ctrl-auto-trim" title="Automatically shrink crop box to subject edges" disabled>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 3h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z"></path><path d="M8 8h8v8H8z"></path></svg>
<span>Auto-Trim</span>
</button>
<button class="ctrl-btn btn-danger-icon" id="ctrl-reset" title="Reset Image State">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"></path><path d="M3 3v5h5"></path></svg>
</button>
</div>
</div>
</section>
<!-- Right Control Panel Tower -->
<aside class="control-tower glass-panel">
<!-- Section 1: File Properties Info -->
<section class="tower-group" id="sec-file-info">
<div class="tower-heading">
<span class="step-badge">1</span>
<h3>Source File</h3>
</div>
<div class="info-card glass-panel-inner" id="info-card-empty">
<p class="text-muted text-center py-2">No image loaded</p>
</div>
<div class="info-card glass-panel-inner hidden" id="info-card-loaded">
<div class="info-row">
<span class="label">Name</span>
<span class="val truncate" id="info-filename">-</span>
</div>
<div class="info-row">
<span class="label">Resolution</span>
<span class="val" id="info-resolution">-</span>
</div>
<div class="info-row">
<span class="label">Size</span>
<span class="val" id="info-size">-</span>
</div>
</div>
</section>
<!-- Section 2: AI Background Remover Panel -->
<section class="tower-group" id="sec-ai-process">
<div class="tower-heading">
<span class="step-badge">2</span>
<h3>Background Removal</h3>
</div>
<button class="btn btn-primary w-full" id="btn-remove-bg" disabled>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-2-2h-5m-9 0h5M3 8v8a2 2 0 0 0 2 2h8m9 0h-5"></path></svg>
<span>Extract Subject</span>
</button>
<!-- Loader panel inside -->
<div class="loader-box glass-panel-inner hidden" id="loader-box">
<div class="loader-ring-wrapper">
<div class="glow-ring"></div>
<svg class="loader-ring" viewBox="0 0 50 50">
<circle cx="25" cy="25" r="20" fill="none" stroke-width="4"></circle>
</svg>
</div>
<div class="loader-text" id="loader-text">Initializing AI Model...</div>
<div class="loader-subtext" id="loader-subtext">First launch downloads model (~200MB)</div>
</div>
</section>
<!-- Section 3: Background Overlay Customizer -->
<section class="tower-group disabled-group" id="sec-canvas-bg">
<div class="tower-heading">
<span class="step-badge">3</span>
<h3>Background Settings</h3>
</div>
<div class="bg-mode-tabs glass-panel-inner">
<button class="bg-tab active" data-mode="transparent" id="tab-bg-trans">
<span>Transparent</span>
</button>
<button class="bg-tab" data-mode="solid" id="tab-bg-solid">
<span>Solid Color</span>
</button>
<button class="bg-tab" data-mode="gradient" id="tab-bg-grad">
<span>Gradient</span>
</button>
</div>
<!-- Solid Colors Panel -->
<div class="bg-settings-subpanel hidden" id="subpanel-solid">
<label class="panel-sublabel">Select Solid Fill</label>
<div class="color-swatches-grid">
<button class="swatch white active" data-color="#ffffff"></button>
<button class="swatch black" data-color="#000000"></button>
<button class="swatch red" data-color="#ef4444"></button>
<button class="swatch blue" data-color="#3b82f6"></button>
<button class="swatch green" data-color="#10b981"></button>
<button class="swatch custom" id="btn-custom-color-picker" title="Pick Custom Color">
<input type="color" id="custom-color-picker" value="#a78bfa">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 14.7255 3.09032 17.1962 4.85857 19C5.34306 18.6653 5.96205 18.5 6.6 18.5C8.47772 18.5 10 20.0223 10 21.9C10 21.9335 9.99965 21.9669 9.99896 22H12Z"></path></svg>
</button>
</div>
</div>
<!-- Gradients Panel -->
<div class="bg-settings-subpanel hidden" id="subpanel-gradient">
<label class="panel-sublabel">Select High-End Gradient</label>
<div class="gradient-swatches-grid">
<button class="grad-swatch grad-1 active" data-gradient="linear-gradient(135deg, #a78bfa, #06b6d4)" title="Violet Cyan Glow"></button>
<button class="grad-swatch grad-2" data-gradient="linear-gradient(135deg, #f43f5e, #f97316)" title="Sunset Horizon"></button>
<button class="grad-swatch grad-3" data-gradient="linear-gradient(135deg, #10b981, #06b6d4)" title="Emerald Sea"></button>
<button class="grad-swatch grad-4" data-gradient="linear-gradient(135deg, #ec4899, #8b5cf6)" title="Cyber Punk Pink"></button>
<button class="grad-swatch grad-5" data-gradient="linear-gradient(135deg, #3b82f6, #8b5cf6)" title="Aether Blue"></button>
<button class="grad-swatch grad-6" data-gradient="linear-gradient(135deg, #f59e0b, #ef4444)" title="Warm Ember"></button>
</div>
</div>
</section>
<!-- Section 4: Export Engine Panel -->
<section class="tower-group disabled-group" id="sec-export">
<div class="tower-heading">
<span class="step-badge">4</span>
<h3>Export Studio</h3>
</div>
<div class="export-settings-box glass-panel-inner">
<div class="settings-row">
<label for="export-format">Format</label>
<div class="select-wrapper">
<select id="export-format">
<option value="png">PNG (Lossless)</option>
<option value="jpeg">JPEG (Solid BG)</option>
<option value="webp">WebP (Optimized)</option>
</select>
</div>
</div>
<div class="settings-row hidden" id="row-quality-slider">
<div class="slider-labels">
<label for="export-quality">Quality</label>
<span class="slider-val" id="export-quality-val">90%</span>
</div>
<input type="range" id="export-quality" min="10" max="100" value="90">
</div>
</div>
<button class="btn btn-primary glow-btn-cyan w-full" id="btn-export">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
<span>Export Masterpiece</span>
</button>
</section>
</aside>
</main>
<!-- Global Alert/Notification Toast Banner -->
<div class="toast-notification glass-panel-inner hidden" id="toast-banner">
<div class="toast-icon" id="toast-icon"></div>
<div class="toast-content">
<div class="toast-title" id="toast-title">Notification</div>
<div class="toast-message" id="toast-message">Message details goes here.</div>
</div>
<button class="toast-close" id="btn-close-toast">&times;</button>
</div>
<!-- Loaded locally in package.json dependencies -->
<script src="node_modules/cropperjs/dist/cropper.js"></script>
<script src="renderer.js"></script>
</body>
</html>