tester343 commited on
Commit
41320de
·
verified ·
1 Parent(s): c70f030

Update app_enhanced.py

Browse files
Files changed (1) hide show
  1. app_enhanced.py +21 -27
app_enhanced.py CHANGED
@@ -118,7 +118,7 @@ def generate_comic_gpu(video_path, user_dir, frames_dir, metadata_path, target_p
118
  raw_moments = [{'text': s.content, 'start': s.start.total_seconds(), 'end': s.end.total_seconds()} for s in valid_subs]
119
 
120
  if target_pages <= 0: target_pages = 1
121
- # CHANGED TO 4 PANELS
122
  panels_per_page = 4
123
  total_panels_needed = target_pages * panels_per_page
124
 
@@ -332,26 +332,32 @@ INDEX_HTML = '''
332
  background: white;
333
  width: 1000px;
334
  height: 700px;
335
- box-shadow: 0 0 50px rgba(0,0,0,0.2);
336
  position: relative;
337
  z-index: 1;
338
  overflow: hidden;
339
- border: 2px solid black;
 
 
340
  }
341
 
342
  /* HANDLES FOR DRAGGING */
343
  .handle {
344
  position: absolute;
345
- width: 16px; height: 16px;
 
346
  background: #ff4757;
347
- border: 2px solid white;
348
  border-radius: 50%;
349
  cursor: ew-resize;
350
  z-index: 999;
351
  transform: translate(-50%, -50%);
352
  box-shadow: 0 2px 5px rgba(0,0,0,0.3);
353
  }
354
- .handle.horiz { cursor: ns-resize; width: 40px; height: 12px; border-radius: 6px; }
 
 
 
 
355
 
356
  /* PANELS */
357
  .panel {
@@ -514,11 +520,10 @@ INDEX_HTML = '''
514
  let startX, startY, initX, initY, panStartX, panStartY, panStartTx, panStartTy;
515
  let activeLayoutHandle = null, activePageId = null;
516
 
517
- // 4-PANEL DEFAULT LAYOUT
518
  const DEFAULT_LAYOUT = {
519
  width: 1000, height: 700, gutter: 10, tierY: 350,
520
- r1: { topX: 500, botX: 500 }, // Top Row Vertical Split
521
- r2: { topX: 500, botX: 500 } // Bottom Row Vertical Split
522
  };
523
 
524
  let historyStack = [];
@@ -627,7 +632,6 @@ INDEX_HTML = '''
627
  div.id = pageId;
628
  div.dataset.layout = JSON.stringify(layout);
629
 
630
- // Generate 4 Panels
631
  for(let i=0; i<4; i++) {
632
  const pDiv = document.createElement('div');
633
  pDiv.className = 'panel'; pDiv.id = `${pageId}-p${i}`;
@@ -643,11 +647,10 @@ INDEX_HTML = '''
643
  div.appendChild(pDiv);
644
  }
645
 
646
- // Generate Handles (Vertical Dividers and Tier Divider)
647
  const handles = [
648
- {id: 'h1-top', t:0, l:0}, {id: 'h1-bot', t:0, l:0}, // Top Row
649
- {id: 'h2-top', t:0, l:0}, {id: 'h2-bot', t:0, l:0}, // Bottom Row
650
- {id: 'h-tier', t:0, l:0, cls: 'horiz'} // Horizontal Tier
651
  ];
652
  handles.forEach(h => {
653
  const hDiv = document.createElement('div');
@@ -657,7 +660,6 @@ INDEX_HTML = '''
657
  div.appendChild(hDiv);
658
  });
659
 
660
- // Bubbles
661
  if(page.pageBubbles) {
662
  page.pageBubbles.forEach(bData => div.appendChild(createBubbleHTML(bData)));
663
  }
@@ -672,7 +674,6 @@ INDEX_HTML = '''
672
  pageWrapper.appendChild(div);
673
  con.appendChild(pageWrapper);
674
 
675
- // Draw Initial Layout
676
  drawLayout(pageId);
677
  });
678
 
@@ -680,7 +681,6 @@ INDEX_HTML = '''
680
  document.getElementById('font-select').disabled = true;
681
  }
682
 
683
- // --- LAYOUT ENGINE (4-PANEL) ---
684
  function drawLayout(pageId) {
685
  const pageEl = document.getElementById(pageId);
686
  if(!pageEl) return;
@@ -690,27 +690,22 @@ INDEX_HTML = '''
690
  const w = state.width;
691
  const h = state.height;
692
 
693
- // P0: Top Left
694
  const p0 = document.getElementById(`${pageId}-p0`);
695
  p0.style.top='0px'; p0.style.left='0px'; p0.style.width='100%'; p0.style.height = ty + 'px';
696
  p0.style.clipPath = `polygon(0 0, ${state.r1.topX - g}px 0, ${state.r1.botX - g}px ${ty}px, 0 ${ty}px)`;
697
 
698
- // P1: Top Right
699
  const p1 = document.getElementById(`${pageId}-p1`);
700
  p1.style.top='0px'; p1.style.left='0px'; p1.style.width='100%'; p1.style.height = ty + 'px';
701
  p1.style.clipPath = `polygon(${state.r1.topX + g}px 0, ${w}px 0, ${w}px ${ty}px, ${state.r1.botX + g}px ${ty}px)`;
702
 
703
- // P2: Bottom Left
704
  const p2 = document.getElementById(`${pageId}-p2`);
705
  p2.style.top = ty + 'px'; p2.style.left='0px'; p2.style.width='100%'; p2.style.height = (h - ty) + 'px';
706
  p2.style.clipPath = `polygon(0 ${g}px, ${state.r2.topX - g}px ${g}px, ${state.r2.botX - g}px ${h-ty}px, 0 ${h-ty}px)`;
707
 
708
- // P3: Bottom Right
709
  const p3 = document.getElementById(`${pageId}-p3`);
710
  p3.style.top = ty + 'px'; p3.style.left='0px'; p3.style.width='100%'; p3.style.height = (h - ty) + 'px';
711
  p3.style.clipPath = `polygon(${state.r2.topX + g}px ${g}px, ${w}px ${g}px, ${w}px ${h-ty}px, ${state.r2.botX + g}px ${h-ty}px)`;
712
 
713
- // Update Handles Position
714
  const setH = (id, l, t) => { const el = document.getElementById(`${pageId}-${id}`); if(el) { el.style.left=l+'px'; el.style.top=t+'px'; } };
715
 
716
  setH('h1-top', state.r1.topX, 0);
@@ -727,7 +722,6 @@ INDEX_HTML = '''
727
  isDragging = true;
728
  }
729
 
730
- // --- GLOBAL MOUSE EVENTS ---
731
  document.addEventListener('mousemove', (e) => {
732
  if(isDragging && activeLayoutHandle && activePageId) {
733
  const pageEl = document.getElementById(activePageId);
@@ -769,7 +763,6 @@ INDEX_HTML = '''
769
  });
770
  }
771
 
772
- // --- IMAGE FIT & TRANSFORM ---
773
  function fitImageToPanel(img, panel, savedState) {
774
  if(savedState && savedState.baseScale) {
775
  img.dataset.zoom = savedState.zoom || 100;
@@ -780,13 +773,15 @@ INDEX_HTML = '''
780
  return;
781
  }
782
 
783
- // Fit to 1000px width container to ensure panning works across whole row
784
  const pW = 1000;
785
  const pH = panel.offsetHeight;
786
  const iW = img.naturalWidth || img.width;
787
  const iH = img.naturalHeight || img.height;
788
 
789
- const scale = Math.max(pW / iW, pH / iH);
 
 
790
  const tx = (pW - iW * scale) / 2;
791
  const ty = (pH - iH * scale) / 2;
792
 
@@ -812,7 +807,6 @@ INDEX_HTML = '''
812
  function handleZoom(el) { if(!selectedPanel) return; const img = selectedPanel.querySelector('img'); img.dataset.zoom = el.value; updateImageTransform(img); }
813
  function resetPanelTransform() { if(!selectedPanel) return alert("Select a panel"); const img = selectedPanel.querySelector('img'); fitImageToPanel(img, selectedPanel, null); saveDraft(true); }
814
 
815
- // --- STANDARD FUNCTIONS ---
816
  function selectPanel(el) {
817
  if(selectedPanel) selectedPanel.classList.remove('selected');
818
  if(selectedBubble) { selectedBubble.classList.remove('selected'); selectedBubble = null; }
 
118
  raw_moments = [{'text': s.content, 'start': s.start.total_seconds(), 'end': s.end.total_seconds()} for s in valid_subs]
119
 
120
  if target_pages <= 0: target_pages = 1
121
+ # 4 PANELS
122
  panels_per_page = 4
123
  total_panels_needed = target_pages * panels_per_page
124
 
 
332
  background: white;
333
  width: 1000px;
334
  height: 700px;
 
335
  position: relative;
336
  z-index: 1;
337
  overflow: hidden;
338
+ /* UPDATED: THICK WHITE BORDER */
339
+ border: 10px solid white;
340
+ box-shadow: 0 0 30px rgba(0,0,0,0.5);
341
  }
342
 
343
  /* HANDLES FOR DRAGGING */
344
  .handle {
345
  position: absolute;
346
+ /* UPDATED: LARGER HANDLES */
347
+ width: 24px; height: 24px;
348
  background: #ff4757;
349
+ border: 3px solid white;
350
  border-radius: 50%;
351
  cursor: ew-resize;
352
  z-index: 999;
353
  transform: translate(-50%, -50%);
354
  box-shadow: 0 2px 5px rgba(0,0,0,0.3);
355
  }
356
+ .handle.horiz {
357
+ cursor: ns-resize;
358
+ width: 60px; height: 18px;
359
+ border-radius: 9px;
360
+ }
361
 
362
  /* PANELS */
363
  .panel {
 
520
  let startX, startY, initX, initY, panStartX, panStartY, panStartTx, panStartTy;
521
  let activeLayoutHandle = null, activePageId = null;
522
 
 
523
  const DEFAULT_LAYOUT = {
524
  width: 1000, height: 700, gutter: 10, tierY: 350,
525
+ r1: { topX: 500, botX: 500 },
526
+ r2: { topX: 500, botX: 500 }
527
  };
528
 
529
  let historyStack = [];
 
632
  div.id = pageId;
633
  div.dataset.layout = JSON.stringify(layout);
634
 
 
635
  for(let i=0; i<4; i++) {
636
  const pDiv = document.createElement('div');
637
  pDiv.className = 'panel'; pDiv.id = `${pageId}-p${i}`;
 
647
  div.appendChild(pDiv);
648
  }
649
 
 
650
  const handles = [
651
+ {id: 'h1-top', t:0, l:0}, {id: 'h1-bot', t:0, l:0},
652
+ {id: 'h2-top', t:0, l:0}, {id: 'h2-bot', t:0, l:0},
653
+ {id: 'h-tier', t:0, l:0, cls: 'horiz'}
654
  ];
655
  handles.forEach(h => {
656
  const hDiv = document.createElement('div');
 
660
  div.appendChild(hDiv);
661
  });
662
 
 
663
  if(page.pageBubbles) {
664
  page.pageBubbles.forEach(bData => div.appendChild(createBubbleHTML(bData)));
665
  }
 
674
  pageWrapper.appendChild(div);
675
  con.appendChild(pageWrapper);
676
 
 
677
  drawLayout(pageId);
678
  });
679
 
 
681
  document.getElementById('font-select').disabled = true;
682
  }
683
 
 
684
  function drawLayout(pageId) {
685
  const pageEl = document.getElementById(pageId);
686
  if(!pageEl) return;
 
690
  const w = state.width;
691
  const h = state.height;
692
 
 
693
  const p0 = document.getElementById(`${pageId}-p0`);
694
  p0.style.top='0px'; p0.style.left='0px'; p0.style.width='100%'; p0.style.height = ty + 'px';
695
  p0.style.clipPath = `polygon(0 0, ${state.r1.topX - g}px 0, ${state.r1.botX - g}px ${ty}px, 0 ${ty}px)`;
696
 
 
697
  const p1 = document.getElementById(`${pageId}-p1`);
698
  p1.style.top='0px'; p1.style.left='0px'; p1.style.width='100%'; p1.style.height = ty + 'px';
699
  p1.style.clipPath = `polygon(${state.r1.topX + g}px 0, ${w}px 0, ${w}px ${ty}px, ${state.r1.botX + g}px ${ty}px)`;
700
 
 
701
  const p2 = document.getElementById(`${pageId}-p2`);
702
  p2.style.top = ty + 'px'; p2.style.left='0px'; p2.style.width='100%'; p2.style.height = (h - ty) + 'px';
703
  p2.style.clipPath = `polygon(0 ${g}px, ${state.r2.topX - g}px ${g}px, ${state.r2.botX - g}px ${h-ty}px, 0 ${h-ty}px)`;
704
 
 
705
  const p3 = document.getElementById(`${pageId}-p3`);
706
  p3.style.top = ty + 'px'; p3.style.left='0px'; p3.style.width='100%'; p3.style.height = (h - ty) + 'px';
707
  p3.style.clipPath = `polygon(${state.r2.topX + g}px ${g}px, ${w}px ${g}px, ${w}px ${h-ty}px, ${state.r2.botX + g}px ${h-ty}px)`;
708
 
 
709
  const setH = (id, l, t) => { const el = document.getElementById(`${pageId}-${id}`); if(el) { el.style.left=l+'px'; el.style.top=t+'px'; } };
710
 
711
  setH('h1-top', state.r1.topX, 0);
 
722
  isDragging = true;
723
  }
724
 
 
725
  document.addEventListener('mousemove', (e) => {
726
  if(isDragging && activeLayoutHandle && activePageId) {
727
  const pageEl = document.getElementById(activePageId);
 
763
  });
764
  }
765
 
 
766
  function fitImageToPanel(img, panel, savedState) {
767
  if(savedState && savedState.baseScale) {
768
  img.dataset.zoom = savedState.zoom || 100;
 
773
  return;
774
  }
775
 
776
+ // CONTAIN LOGIC: Ensure WHOLE image fits
777
  const pW = 1000;
778
  const pH = panel.offsetHeight;
779
  const iW = img.naturalWidth || img.width;
780
  const iH = img.naturalHeight || img.height;
781
 
782
+ // Math.min makes sure it fits fully (contain)
783
+ const scale = Math.min(pW / iW, pH / iH);
784
+
785
  const tx = (pW - iW * scale) / 2;
786
  const ty = (pH - iH * scale) / 2;
787
 
 
807
  function handleZoom(el) { if(!selectedPanel) return; const img = selectedPanel.querySelector('img'); img.dataset.zoom = el.value; updateImageTransform(img); }
808
  function resetPanelTransform() { if(!selectedPanel) return alert("Select a panel"); const img = selectedPanel.querySelector('img'); fitImageToPanel(img, selectedPanel, null); saveDraft(true); }
809
 
 
810
  function selectPanel(el) {
811
  if(selectedPanel) selectedPanel.classList.remove('selected');
812
  if(selectedBubble) { selectedBubble.classList.remove('selected'); selectedBubble = null; }