BoxOfColors commited on
Commit
0378fbe
·
1 Parent(s): c97fd8e

fix: draw and hit-test segments by unique region to prevent overlap highlight bleed

Browse files

Segment color blocks and click targets were drawn using each segment's full
[start, end] span. Since windows overlap (e.g. seg0=0-8s, seg1=6-14s), this
caused adjacent segment colors to visually bleed into each other, and clicking
in an overlap zone would ambiguously match multiple segments.

Fix: each segment now owns only [start, nextSeg.start) visually and for click
detection, with the final segment owning [start, end]. This means exactly one
colored block is highlighted during regen and clicks always target precisely
the visible segment the user clicked on.

Files changed (1) hide show
  1. app.py +20 -5
app.py CHANGED
@@ -1123,8 +1123,14 @@ def _build_regen_pending_html(segments: list, regen_seg_idx: int, slot_id: str,
1123
 
1124
  seg_divs = ""
1125
  for i, seg in enumerate(segments):
1126
- left_pct = seg[0] / duration * 100
1127
- width_pct = (seg[1] - seg[0]) / duration * 100
 
 
 
 
 
 
1128
  color = active_color if i == regen_seg_idx else seg_colors[i % len(seg_colors)]
1129
  extra = "border:2px solid #ffb300;animation:wf_pulse 0.8s ease-in-out infinite alternate;" if i == regen_seg_idx else ""
1130
  seg_divs += (
@@ -1262,10 +1268,14 @@ def _build_waveform_html(audio_path: str, segments: list, slot_id: str,
1262
  ctx.fillRect(0, 0, W, H);
1263
 
1264
  segments.forEach(function(seg, idx) {{
 
 
1265
  const x1 = (seg[0] / duration) * W;
1266
- const x2 = (seg[1] / duration) * W;
 
 
1267
  ctx.fillStyle = segColors[idx % segColors.length];
1268
- ctx.fillRect(x1, 0, x2-x1, H);
1269
  ctx.fillStyle = 'rgba(255,255,255,0.6)';
1270
  ctx.font = '10px sans-serif';
1271
  ctx.fillText('Seg '+(idx+1), x1+3, 12);
@@ -1300,8 +1310,13 @@ def _build_waveform_html(audio_path: str, segments: list, slot_id: str,
1300
  const r=cv.getBoundingClientRect();
1301
  const xRel=(e.clientX-r.left)/r.width;
1302
  const tClick=xRel*duration;
 
 
1303
  let hit=-1;
1304
- segments.forEach(function(seg,idx){{ if(tClick>=seg[0]&&tClick<=seg[1]) hit=idx; }});
 
 
 
1305
  console.log('[wf click] tClick='+tClick.toFixed(2)+' hit='+hit+' audioDuration='+audioDuration+' segments='+JSON.stringify(segments));
1306
  if (hit>=0) showPopup(hit, e.clientX, e.clientY);
1307
  else hidePopup();
 
1123
 
1124
  seg_divs = ""
1125
  for i, seg in enumerate(segments):
1126
+ # Draw only the non-overlapping (unique) portion of each segment so that
1127
+ # overlapping windows don't visually bleed into adjacent segments.
1128
+ # Each segment owns the region from its own start up to the next segment's
1129
+ # start (or its own end for the final segment).
1130
+ seg_start = seg[0]
1131
+ seg_end = segments[i + 1][0] if i + 1 < len(segments) else seg[1]
1132
+ left_pct = seg_start / duration * 100
1133
+ width_pct = (seg_end - seg_start) / duration * 100
1134
  color = active_color if i == regen_seg_idx else seg_colors[i % len(seg_colors)]
1135
  extra = "border:2px solid #ffb300;animation:wf_pulse 0.8s ease-in-out infinite alternate;" if i == regen_seg_idx else ""
1136
  seg_divs += (
 
1268
  ctx.fillRect(0, 0, W, H);
1269
 
1270
  segments.forEach(function(seg, idx) {{
1271
+ // Draw only each segment's unique (non-overlapping) region:
1272
+ // from its start up to the next segment's start, or its own end if last.
1273
  const x1 = (seg[0] / duration) * W;
1274
+ const xEnd = idx + 1 < segments.length
1275
+ ? (segments[idx + 1][0] / duration) * W
1276
+ : (seg[1] / duration) * W;
1277
  ctx.fillStyle = segColors[idx % segColors.length];
1278
+ ctx.fillRect(x1, 0, xEnd - x1, H);
1279
  ctx.fillStyle = 'rgba(255,255,255,0.6)';
1280
  ctx.font = '10px sans-serif';
1281
  ctx.fillText('Seg '+(idx+1), x1+3, 12);
 
1310
  const r=cv.getBoundingClientRect();
1311
  const xRel=(e.clientX-r.left)/r.width;
1312
  const tClick=xRel*duration;
1313
+ // Pick the segment whose unique (non-overlapping) region contains the click.
1314
+ // Each segment owns [seg[0], nextSeg[0]) visually; last segment owns [seg[0], seg[1]].
1315
  let hit=-1;
1316
+ segments.forEach(function(seg,idx){{
1317
+ const uniqueEnd = idx + 1 < segments.length ? segments[idx+1][0] : seg[1];
1318
+ if (tClick >= seg[0] && tClick < uniqueEnd) hit = idx;
1319
+ }});
1320
  console.log('[wf click] tClick='+tClick.toFixed(2)+' hit='+hit+' audioDuration='+audioDuration+' segments='+JSON.stringify(segments));
1321
  if (hit>=0) showPopup(hit, e.clientX, e.clientY);
1322
  else hidePopup();