jhh6576 commited on
Commit
279de67
·
verified ·
1 Parent(s): 3f1e7d2

Update app_enhanced.py

Browse files
Files changed (1) hide show
  1. app_enhanced.py +38 -17
app_enhanced.py CHANGED
@@ -509,7 +509,7 @@ class EnhancedComicGenerator:
509
  .panel img { width: 100%; height: 100%; object-fit: cover; object-position: center; transition: transform 0.1s ease-out; }
510
  .panel img.pannable { cursor: grab; }
511
  .panel img.panning { cursor: grabbing; }
512
- .speech-bubble { font-family: 'Comic Neue', cursive; position: absolute; display: flex; justify-content: center; align-items: center; width: 150px; height: 80px; min-width: 50px; min-height: 30px; box-sizing: border-box; padding: 8px; box-shadow: 2px 2px 5px rgba(0,0,0,0.3); z-index: 10; cursor: move; overflow: visible; font-size: 13px; font-weight: bold; text-align: center; }
513
  .bubble-text { padding: 2px; word-wrap: break-word; }
514
  .speech-bubble.selected { outline: 2px dashed #4CAF50; }
515
  .speech-bubble textarea { position: absolute; top: 0; left: 0; width: 100%; height: 100%; box-sizing: border-box; border: 1px solid #4CAF50; background: rgba(255,255,255,0.95); font: inherit; text-align: center; resize: none; padding: 8px; z-index: 102; }
@@ -623,7 +623,6 @@ class EnhancedComicGenerator:
623
  let currentlySelectedBubble = null;
624
  let currentlySelectedPanel = null;
625
  let isPanning = false, panStartX, panStartY, panStartTranslateX, panStartTranslateY;
626
- let isResizing = false, resizeHandle, originalWidth, originalHeight, originalX, originalY, originalMouseX, originalMouseY;
627
 
628
  function renderComic(data) {
629
  const container = document.getElementById('comic-pages');
@@ -686,6 +685,8 @@ class EnhancedComicGenerator:
686
  bubble.addEventListener('dblclick', e => { e.stopPropagation(); editBubbleText(bubble); });
687
  bubble.addEventListener('mousedown', e => { e.stopPropagation(); startDrag(e); });
688
  bubble.addEventListener('click', e => { e.stopPropagation(); selectBubble(bubble); });
 
 
689
  ['nw', 'ne', 'sw', 'se'].forEach(dir => {
690
  const handle = document.createElement('div');
691
  handle.className = `resize-handle ${dir}`;
@@ -761,12 +762,20 @@ class EnhancedComicGenerator:
761
  panel.classList.add('selected');
762
  currentlySelectedPanel = panel;
763
  selectBubble(null);
 
 
 
 
764
  }
765
 
766
  function selectBubble(bubble) {
767
  if (currentlySelectedBubble) currentlySelectedBubble.classList.remove('selected');
768
  currentlySelectedBubble = bubble;
769
- const bubbleControls = ['bubble-text-color', 'bubble-fill-color', 'bubble-type-select', 'font-select'];
 
 
 
 
770
 
771
  if (currentlySelectedBubble) {
772
  currentlySelectedBubble.classList.add('selected');
@@ -774,16 +783,15 @@ class EnhancedComicGenerator:
774
  currentlySelectedPanel = null;
775
 
776
  const styles = window.getComputedStyle(currentlySelectedBubble);
777
- document.getElementById('bubble-text-color').value = rgbToHex(styles.color);
778
- document.getElementById('bubble-fill-color').value = rgbToHex(styles.backgroundColor);
779
- document.getElementById('bubble-type-select').value = currentlySelectedBubble.dataset.type || 'speech';
780
- document.getElementById('font-select').value = styles.fontFamily.split(',')[0].replace(/"/g, "").replace(/'/g, "").trim();
781
 
782
  document.getElementById('zoom-slider').disabled = true;
783
- bubbleControls.forEach(id => document.getElementById(id).disabled = false);
784
  } else {
785
- bubbleControls.forEach(id => document.getElementById(id).disabled = true);
786
- if(currentlySelectedPanel) document.getElementById('zoom-slider').disabled = false;
787
  }
788
  }
789
 
@@ -792,8 +800,9 @@ class EnhancedComicGenerator:
792
  currentlyEditing = bubble;
793
  const textSpan = bubble.querySelector('.bubble-text');
794
  const textarea = document.createElement('textarea');
795
- const originalHeight = bubble.offsetHeight;
796
- bubble.style.height = `${originalHeight}px`;
 
797
 
798
  textarea.value = textSpan.textContent;
799
  bubble.appendChild(textarea);
@@ -803,6 +812,9 @@ class EnhancedComicGenerator:
803
  textSpan.textContent = textarea.value;
804
  bubble.removeChild(textarea);
805
  textSpan.style.display = '';
 
 
 
806
  currentlyEditing = null;
807
  };
808
  textarea.addEventListener('blur', finishEditing, { once: true });
@@ -839,6 +851,9 @@ class EnhancedComicGenerator:
839
  }
840
  }
841
 
 
 
 
842
  function startResize(e, dir) {
843
  e.preventDefault();
844
  e.stopPropagation();
@@ -860,19 +875,25 @@ class EnhancedComicGenerator:
860
  const dy = e.clientY - originalMouseY;
861
  const bubble = currentlySelectedBubble;
862
 
863
- if (resizeHandle.includes('e')) bubble.style.width = `${originalWidth + dx}px`;
 
 
864
  if (resizeHandle.includes('w')) {
865
  bubble.style.width = `${originalWidth - dx}px`;
866
  bubble.style.left = `${originalX + dx}px`;
867
  }
868
- if (resizeHandle.includes('s')) bubble.style.height = `${originalHeight + dy}px`;
 
 
869
  if (resizeHandle.includes('n')) {
870
  bubble.style.height = `${originalHeight - dy}px`;
871
  bubble.style.top = `${originalY + dy}px`;
872
  }
873
  }
874
 
875
- function stopResize() { isResizing = false; }
 
 
876
 
877
  function clearSavedState() {
878
  if (confirm("Reset all edits?")) {
@@ -900,8 +921,8 @@ class EnhancedComicGenerator:
900
  .then(data => {
901
  if (data.success) {
902
  img.src = `/frames/final/${data.new_filename}?t=${new Date().getTime()}`;
903
- img.style.objectFit = 'contain';
904
- resetPanelTransform();
905
  } else { alert('Error replacing image: ' + data.error); }
906
  img.style.opacity = '1';
907
  })
 
509
  .panel img { width: 100%; height: 100%; object-fit: cover; object-position: center; transition: transform 0.1s ease-out; }
510
  .panel img.pannable { cursor: grab; }
511
  .panel img.panning { cursor: grabbing; }
512
+ .speech-bubble { font-family: 'Comic Neue', cursive; position: absolute; display: flex; justify-content: center; align-items: center; width: 150px; height: 80px; min-width: 50px; max-width: 220px; min-height: 30px; box-sizing: border-box; padding: 8px; box-shadow: 2px 2px 5px rgba(0,0,0,0.3); z-index: 10; cursor: move; overflow: visible; font-size: 13px; font-weight: bold; text-align: center; }
513
  .bubble-text { padding: 2px; word-wrap: break-word; }
514
  .speech-bubble.selected { outline: 2px dashed #4CAF50; }
515
  .speech-bubble textarea { position: absolute; top: 0; left: 0; width: 100%; height: 100%; box-sizing: border-box; border: 1px solid #4CAF50; background: rgba(255,255,255,0.95); font: inherit; text-align: center; resize: none; padding: 8px; z-index: 102; }
 
623
  let currentlySelectedBubble = null;
624
  let currentlySelectedPanel = null;
625
  let isPanning = false, panStartX, panStartY, panStartTranslateX, panStartTranslateY;
 
626
 
627
  function renderComic(data) {
628
  const container = document.getElementById('comic-pages');
 
685
  bubble.addEventListener('dblclick', e => { e.stopPropagation(); editBubbleText(bubble); });
686
  bubble.addEventListener('mousedown', e => { e.stopPropagation(); startDrag(e); });
687
  bubble.addEventListener('click', e => { e.stopPropagation(); selectBubble(bubble); });
688
+
689
+ // Add resize handles
690
  ['nw', 'ne', 'sw', 'se'].forEach(dir => {
691
  const handle = document.createElement('div');
692
  handle.className = `resize-handle ${dir}`;
 
762
  panel.classList.add('selected');
763
  currentlySelectedPanel = panel;
764
  selectBubble(null);
765
+
766
+ const img = currentlySelectedPanel.querySelector('img');
767
+ document.getElementById('zoom-slider').value = img.dataset.zoom || 100;
768
+ document.getElementById('zoom-slider').disabled = false;
769
  }
770
 
771
  function selectBubble(bubble) {
772
  if (currentlySelectedBubble) currentlySelectedBubble.classList.remove('selected');
773
  currentlySelectedBubble = bubble;
774
+ const textColorPicker = document.getElementById('bubble-text-color');
775
+ const fillColorPicker = document.getElementById('bubble-fill-color');
776
+ const typeSelect = document.getElementById('bubble-type-select');
777
+ const fontSelect = document.getElementById('font-select');
778
+ const bubbleControls = [textColorPicker, fillColorPicker, typeSelect, fontSelect];
779
 
780
  if (currentlySelectedBubble) {
781
  currentlySelectedBubble.classList.add('selected');
 
783
  currentlySelectedPanel = null;
784
 
785
  const styles = window.getComputedStyle(currentlySelectedBubble);
786
+ textColorPicker.value = rgbToHex(styles.color);
787
+ fillColorPicker.value = rgbToHex(styles.backgroundColor);
788
+ typeSelect.value = currentlySelectedBubble.dataset.type || 'speech';
789
+ fontSelect.value = styles.fontFamily.split(',')[0].replace(/"/g, "").replace(/'/g, "").trim();
790
 
791
  document.getElementById('zoom-slider').disabled = true;
792
+ bubbleControls.forEach(c => c.disabled = false);
793
  } else {
794
+ bubbleControls.forEach(c => c.disabled = true);
 
795
  }
796
  }
797
 
 
800
  currentlyEditing = bubble;
801
  const textSpan = bubble.querySelector('.bubble-text');
802
  const textarea = document.createElement('textarea');
803
+ // FIX: Preserve height before editing
804
+ const originalHeight = bubble.style.height || `${bubble.offsetHeight}px`;
805
+ bubble.style.height = originalHeight;
806
 
807
  textarea.value = textSpan.textContent;
808
  bubble.appendChild(textarea);
 
812
  textSpan.textContent = textarea.value;
813
  bubble.removeChild(textarea);
814
  textSpan.style.display = '';
815
+ // FIX: Re-apply height, then set to auto to allow natural flow
816
+ bubble.style.height = originalHeight;
817
+ setTimeout(() => { bubble.style.height = 'auto'; }, 0);
818
  currentlyEditing = null;
819
  };
820
  textarea.addEventListener('blur', finishEditing, { once: true });
 
851
  }
852
  }
853
 
854
+ let isResizing = false;
855
+ let resizeHandle, originalWidth, originalHeight, originalX, originalY, originalMouseX, originalMouseY;
856
+
857
  function startResize(e, dir) {
858
  e.preventDefault();
859
  e.stopPropagation();
 
875
  const dy = e.clientY - originalMouseY;
876
  const bubble = currentlySelectedBubble;
877
 
878
+ if (resizeHandle.includes('e')) {
879
+ bubble.style.width = `${originalWidth + dx}px`;
880
+ }
881
  if (resizeHandle.includes('w')) {
882
  bubble.style.width = `${originalWidth - dx}px`;
883
  bubble.style.left = `${originalX + dx}px`;
884
  }
885
+ if (resizeHandle.includes('s')) {
886
+ bubble.style.height = `${originalHeight + dy}px`;
887
+ }
888
  if (resizeHandle.includes('n')) {
889
  bubble.style.height = `${originalHeight - dy}px`;
890
  bubble.style.top = `${originalY + dy}px`;
891
  }
892
  }
893
 
894
+ function stopResize() {
895
+ isResizing = false;
896
+ }
897
 
898
  function clearSavedState() {
899
  if (confirm("Reset all edits?")) {
 
921
  .then(data => {
922
  if (data.success) {
923
  img.src = `/frames/final/${data.new_filename}?t=${new Date().getTime()}`;
924
+ img.style.objectFit = 'contain'; // FIX: Show full image
925
+ resetPanelTransform(); // FIX: Reset any old zoom/pan
926
  } else { alert('Error replacing image: ' + data.error); }
927
  img.style.opacity = '1';
928
  })