Spaces:
Running
Running
| class AIEditor extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| background: rgba(0,0,0,0.7); | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| z-index: 1000; | |
| padding: 2rem; | |
| backdrop-filter: blur(5px); | |
| } | |
| .editor-container { | |
| background: #1e293b; | |
| max-width: 1200px; | |
| margin: 2rem auto; | |
| border-radius: 1rem; | |
| overflow: hidden; | |
| box-shadow: 0 10px 25px rgba(0,0,0,0.3); | |
| display: grid; | |
| grid-template-columns: 1fr 300px; | |
| height: 80vh; | |
| } | |
| .image-view { | |
| position: relative; | |
| overflow: hidden; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| background: #0f172a; | |
| } | |
| .image-view img { | |
| max-width: 100%; | |
| max-height: 100%; | |
| object-fit: contain; | |
| } | |
| .tools-panel { | |
| background: #334155; | |
| padding: 1.5rem; | |
| overflow-y: auto; | |
| } | |
| .close-btn { | |
| position: absolute; | |
| top: 1rem; | |
| right: 1rem; | |
| background: #ef4444; | |
| color: white; | |
| border: none; | |
| width: 2rem; | |
| height: 2rem; | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| z-index: 10; | |
| } | |
| h3 { | |
| color: white; | |
| margin-top: 0; | |
| } | |
| .tool-section { | |
| margin-bottom: 1.5rem; | |
| } | |
| .slider-control { | |
| margin-bottom: 1rem; | |
| } | |
| label { | |
| display: block; | |
| color: #94a3b8; | |
| margin-bottom: 0.5rem; | |
| font-size: 0.875rem; | |
| } | |
| input[type="range"] { | |
| width: 100%; | |
| } | |
| .ai-prompt { | |
| width: 100%; | |
| background: #475569; | |
| border: 1px solid #64748b; | |
| color: white; | |
| padding: 0.75rem; | |
| border-radius: 0.5rem; | |
| margin-bottom: 1rem; | |
| } | |
| .apply-btn { | |
| background: #6366f1; | |
| color: white; | |
| border: none; | |
| padding: 0.75rem 1.5rem; | |
| border-radius: 0.5rem; | |
| width: 100%; | |
| cursor: pointer; | |
| font-weight: 500; | |
| } | |
| .preset-buttons { | |
| display: grid; | |
| grid-template-columns: repeat(2, 1fr); | |
| gap: 0.5rem; | |
| margin-bottom: 1rem; | |
| } | |
| .preset-btn { | |
| background: #475569; | |
| color: white; | |
| border: none; | |
| padding: 0.5rem; | |
| border-radius: 0.25rem; | |
| font-size: 0.75rem; | |
| cursor: pointer; | |
| } | |
| </style> | |
| <div class="editor-container"> | |
| <div class="image-view"> | |
| <img src="" alt="Image being edited"> | |
| <button class="close-btn">×</button> | |
| </div> | |
| <div class="tools-panel"> | |
| <div class="tool-section"> | |
| <h3>AI Enhancements</h3> | |
| <input type="text" class="ai-prompt" placeholder="Describe how you want to modify the image..."> | |
| <button class="apply-btn">Apply AI Magic</button> | |
| </div> | |
| <div class="tool-section"> | |
| <h3>Quick Presets</h3> | |
| <div class="preset-buttons"> | |
| <button class="preset-btn" data-preset="enhance">Enhance</button> | |
| <button class="preset-btn" data-preset="background-remove">Remove BG</button> | |
| <button class="preset-btn" data-preset="cartoonify">Cartoonify</button> | |
| <button class="preset-btn" data-preset="oil-painting">Oil Painting</button> | |
| <button class="preset-btn" data-preset="sketch">Pencil Sketch</button> | |
| <button class="preset-btn" data-preset="vintage">Vintage</button> | |
| </div> | |
| </div> | |
| <div class="tool-section"> | |
| <h3>Adjustments</h3> | |
| <div class="slider-control"> | |
| <label>Brightness</label> | |
| <input type="range" min="0" max="200" value="100"> | |
| </div> | |
| <div class="slider-control"> | |
| <label>Contrast</label> | |
| <input type="range" min="0" max="200" value="100"> | |
| </div> | |
| <div class="slider-control"> | |
| <label>Saturation</label> | |
| <input type="range" min="0" max="200" value="100"> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| this.shadowRoot.querySelector('.close-btn').addEventListener('click', () => { | |
| this.remove(); | |
| }); | |
| this.shadowRoot.querySelector('.apply-btn').addEventListener('click', () => { | |
| this.applyAIEdits(); | |
| }); | |
| this.shadowRoot.querySelectorAll('.preset-btn').forEach(btn => { | |
| btn.addEventListener('click', () => { | |
| this.applyAIPreset(btn.dataset.preset); | |
| }); | |
| }); | |
| } | |
| setImage(src) { | |
| this.shadowRoot.querySelector('img').src = src; | |
| } | |
| applyAIEdits() { | |
| const prompt = this.shadowRoot.querySelector('.ai-prompt').value; | |
| // In a real app, this would call your AI API | |
| console.log('Applying AI edits with prompt:', prompt); | |
| // Simulate AI processing | |
| const img = this.shadowRoot.querySelector('img'); | |
| img.style.filter = 'brightness(1.1) contrast(1.1) saturate(1.1)'; | |
| // Show processing indicator | |
| const btn = this.shadowRoot.querySelector('.apply-btn'); | |
| btn.disabled = true; | |
| btn.innerHTML = '<i data-feather="loader" class="animate-spin"></i> Processing...'; | |
| // Simulate API call | |
| setTimeout(() => { | |
| btn.disabled = false; | |
| btn.textContent = 'Apply AI Magic'; | |
| // In a real app, you'd update the image with the AI result | |
| }, 2000); | |
| } | |
| applyAIPreset(preset) { | |
| console.log('Applying AI preset:', preset); | |
| // Simulate different presets | |
| const img = this.shadowRoot.querySelector('img'); | |
| switch(preset) { | |
| case 'enhance': | |
| img.style.filter = 'brightness(1.1) contrast(1.1) saturate(1.2)'; | |
| break; | |
| case 'background-remove': | |
| // Would call BG removal API in real app | |
| img.style.opacity = '0.8'; | |
| break; | |
| case 'cartoonify': | |
| img.style.filter = 'contrast(1.5) saturate(1.5)'; | |
| break; | |
| default: | |
| img.style.filter = ''; | |
| } | |
| } | |
| } | |
| customElements.define('ai-editor', AIEditor); |