File size: 5,973 Bytes
8b950cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// image-editor.js - Nano Banana / Pollinations UI overlay for Image Editing
export function initImageEditor() {
  if (document.getElementById('image-editor-modal')) return;

  const modalHtml = `
    <div id="image-editor-modal" style="display: none; position: fixed; inset: 0; z-index: 9999; background: rgba(0,0,0,0.8); backdrop-filter: blur(10px); flex-direction: column; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.3s ease;">
      <div style="position: absolute; top: 20px; right: 20px; z-index: 10;">
        <button id="close-image-editor" style="background: rgba(255,255,255,0.2); border: none; width: 40px; height: 40px; border-radius: 20px; color: white; font-size: 20px; cursor: pointer; display: flex; align-items: center; justify-content: center;">
          <svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
        </button>
      </div>
      
      <div style="width: 90%; max-width: 600px; display: flex; flex-direction: column; gap: 16px;">
        <div style="position: relative; width: 100%; aspect-ratio: 1/1; background: #111; border-radius: 12px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.5);">
          <img id="editor-base-image" style="width: 100%; height: 100%; object-fit: contain; pointer-events: none;" />
          <canvas id="editor-canvas" style="position: absolute; inset: 0; width: 100%; height: 100%; cursor: crosshair; touch-action: none;"></canvas>
        </div>
        
        <div style="display: flex; gap: 8px; background: rgba(255,255,255,0.05); padding: 8px; border-radius: 12px; border: 1px solid rgba(255,255,255,0.1);">
          <input type="text" id="editor-prompt" placeholder="Was möchtest du ändern? (z.B. 'Mach den Himmel blauer')" style="flex: 1; background: transparent; border: none; color: white; padding: 12px; font-size: 16px; outline: none; min-width: 0;" />
          <button id="editor-submit" style="background: white; color: black; border: none; padding: 0 24px; border-radius: 8px; font-weight: 600; cursor: pointer;">Ändern</button>
        </div>
        <div style="text-align: center; color: rgba(255,255,255,0.5); font-size: 12px;">Hinweis: Maskierung (Inpainting) erfordert Nano Banana 2 (Premium). Aktuell wird der reine Text-Prompt verarbeitet.</div>
      </div>
    </div>
  `;

  document.body.insertAdjacentHTML('beforeend', modalHtml);

  const modal = document.getElementById('image-editor-modal');
  const closeBtn = document.getElementById('close-image-editor');
  const canvas = document.getElementById('editor-canvas');
  const promptInput = document.getElementById('editor-prompt');
  const submitBtn = document.getElementById('editor-submit');
  const baseImg = document.getElementById('editor-base-image');

  let ctx = canvas.getContext('2d');
  let isDrawing = false;
  let currentPromptContext = '';

  function resizeCanvas() {
    canvas.width = canvas.offsetWidth;
    canvas.height = canvas.offsetHeight;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';
    ctx.lineWidth = 30;
    ctx.strokeStyle = 'rgba(255, 50, 50, 0.5)';
  }

  window.addEventListener('resize', () => {
    if (modal.style.display !== 'none') resizeCanvas();
  });

  closeBtn.onclick = () => {
    modal.style.opacity = '0';
    setTimeout(() => modal.style.display = 'none', 300);
  };

  // Drawing Logic
  const startDrawing = (e) => {
    isDrawing = true;
    draw(e);
  };

  const stopDrawing = () => {
    isDrawing = false;
    ctx.beginPath();
  };

  const draw = (e) => {
    if (!isDrawing) return;
    e.preventDefault();
    
    const rect = canvas.getBoundingClientRect();
    const clientX = e.touches ? e.touches[0].clientX : e.clientX;
    const clientY = e.touches ? e.touches[0].clientY : e.clientY;
    
    const x = clientX - rect.left;
    const y = clientY - rect.top;

    ctx.lineTo(x, y);
    ctx.stroke();
    ctx.beginPath();
    ctx.moveTo(x, y);
  };

  canvas.addEventListener('mousedown', startDrawing);
  canvas.addEventListener('mousemove', draw);
  canvas.addEventListener('mouseup', stopDrawing);
  canvas.addEventListener('mouseout', stopDrawing);

  canvas.addEventListener('touchstart', startDrawing, { passive: false });
  canvas.addEventListener('touchmove', draw, { passive: false });
  canvas.addEventListener('touchend', stopDrawing);

  submitBtn.onclick = () => {
    const editInstruction = promptInput.value.trim();
    if (!editInstruction) return;
    
    // For Pollinations (Option A), we just append the edit to the prompt or overwrite it.
    // In a real API, we'd send baseImg.src and canvas.toDataURL() as a mask.
    const newPrompt = `${currentPromptContext}, modified: ${editInstruction}`;
    
    // Send a message into the chat conceptually
    const input = document.querySelector('#chat-input');
    const sendBtn = document.querySelector('#send-button');
    if (input && sendBtn) {
       input.value = `Bitte generiere das Bild mit der Änderung: "${editInstruction}". Neuer Prompt: ${newPrompt}`;
       sendBtn.click();
    }
    
    closeBtn.click();
  };

  window.openImageEditor = (url, originalPromptEncoded) => {
    baseImg.src = url;
    currentPromptContext = decodeURIComponent(originalPromptEncoded);
    promptInput.value = '';
    
    modal.style.display = 'flex';
    // Force reflow
    void modal.offsetWidth;
    modal.style.opacity = '1';
    
    setTimeout(() => {
      resizeCanvas();
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    }, 100);
  };
}

// Auto-init on load if not a module or manually called
if (typeof document !== 'undefined') {
  document.addEventListener('DOMContentLoaded', initImageEditor);
  // Just in case it's loaded dynamically after DOMContentLoaded
  if (document.readyState === 'complete' || document.readyState === 'interactive') {
    initImageEditor();
  }
}