jebin2 commited on
Commit
f6b1d10
·
1 Parent(s): c38c187
comic_panel_extractor/static/annotator.html CHANGED
@@ -649,6 +649,12 @@
649
  this.lastMouseX = 0;
650
  this.lastMouseY = 0;
651
 
 
 
 
 
 
 
652
  this.init();
653
  }
654
 
@@ -893,7 +899,7 @@
893
  }
894
  this.ctx.stroke();
895
 
896
- // Draw points (larger for selected polygon)
897
  const pointRadius = isSelected ? 6 : 4;
898
  points.forEach((point, index) => {
899
  this.ctx.fillStyle = isSelected ? '#0066ff' : strokeColor;
@@ -901,7 +907,6 @@
901
  this.ctx.arc(point.x, point.y, pointRadius, 0, 2 * Math.PI);
902
  this.ctx.fill();
903
 
904
- // Draw point outline for selected polygon
905
  if (isSelected) {
906
  this.ctx.strokeStyle = '#ffffff';
907
  this.ctx.lineWidth = 2;
@@ -909,19 +914,90 @@
909
  }
910
  });
911
 
912
- // Draw edge midpoints for selected polygon (for adding points)
913
- if (isSelected && points.length > 2) {
914
- this.ctx.fillStyle = 'rgba(0, 102, 255, 0.7)';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
915
  for (let i = 0; i < points.length; i++) {
916
  const nextIndex = (i + 1) % points.length;
917
  const midX = (points[i].x + points[nextIndex].x) / 2;
918
  const midY = (points[i].y + points[nextIndex].y) / 2;
919
 
920
- this.ctx.beginPath();
921
- this.ctx.arc(midX, midY, 3, 0, 2 * Math.PI);
922
- this.ctx.fill();
 
923
  }
924
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
925
  }
926
 
927
  // Polygon-specific editing methods
@@ -1071,21 +1147,30 @@
1071
  const pos = this.getMousePos(e);
1072
  this.lastMouseX = pos.x;
1073
  this.lastMouseY = pos.y;
 
1074
 
1075
  if (this.annotationMode === 'segmentation') {
1076
- // Check if clicking on a point of selected polygon
1077
  if (this.selectedBoxIndex >= 0) {
 
 
 
 
 
 
 
 
1078
  const pointIndex = this.getPolygonPointAtPosition(pos.x, pos.y);
1079
  if (pointIndex >= 0) {
1080
  this.isDraggingPoint = true;
1081
  this.draggingPointIndex = pointIndex;
1082
- this.canvas.style.cursor = 'move';
1083
  return;
1084
  }
1085
 
1086
  // Check if clicking on an edge to add a point
1087
  const edgeIndex = this.getPolygonEdgeAtPosition(pos.x, pos.y);
1088
- if (edgeIndex >= 0 && e.ctrlKey) { // Ctrl+click to add point
1089
  this.addPolygonPoint(this.selectedBoxIndex, edgeIndex, pos.x, pos.y);
1090
  this.drawCanvas();
1091
  return;
@@ -1099,7 +1184,7 @@
1099
  this.isDragging = true;
1100
  this.dragStartX = pos.x;
1101
  this.dragStartY = pos.y;
1102
- this.canvas.style.cursor = 'move';
1103
  this.updateSelectedBoxInfo();
1104
  this.drawCanvas();
1105
  return;
@@ -1126,7 +1211,6 @@
1126
 
1127
  // Original bbox logic remains the same...
1128
  if (this.selectedBoxIndex >= 0) {
1129
- const handle = this.getResizeHandle(pos.x, pos.y);
1130
  if (handle) {
1131
  this.isResizing = true;
1132
  this.resizeHandle = handle;
@@ -1141,7 +1225,7 @@
1141
  this.isDragging = true;
1142
  this.dragStartX = pos.x;
1143
  this.dragStartY = pos.y;
1144
- this.canvas.style.cursor = 'move';
1145
  this.updateSelectedBoxInfo();
1146
  this.drawCanvas();
1147
  return;
@@ -1189,6 +1273,13 @@
1189
  const pos = this.getMousePos(e);
1190
 
1191
  if (this.annotationMode === 'segmentation') {
 
 
 
 
 
 
 
1192
  if (this.isDraggingPoint && this.selectedBoxIndex >= 0) {
1193
  // Move individual point
1194
  this.movePolygonPoint(this.selectedBoxIndex, this.draggingPointIndex, pos.x, pos.y);
@@ -1243,6 +1334,8 @@
1243
 
1244
  onMouseUp() {
1245
  if (this.annotationMode === 'segmentation') {
 
 
1246
  this.isDraggingPoint = false;
1247
  this.draggingPointIndex = -1;
1248
  this.isDragging = false;
@@ -1292,9 +1385,17 @@
1292
  }
1293
  updatePolygonCursor(x, y) {
1294
  if (this.selectedBoxIndex >= 0 && this.annotations[this.selectedBoxIndex].type === 'segmentation') {
 
 
 
 
 
 
 
 
1295
  const pointIndex = this.getPolygonPointAtPosition(x, y);
1296
  if (pointIndex >= 0) {
1297
- this.canvas.style.cursor = 'move';
1298
  return;
1299
  }
1300
 
@@ -1305,7 +1406,7 @@
1305
  }
1306
 
1307
  if (this.isPointInPolygon(x, y, this.annotations[this.selectedBoxIndex].points)) {
1308
- this.canvas.style.cursor = 'move';
1309
  return;
1310
  }
1311
  }
@@ -1336,7 +1437,7 @@
1336
  }
1337
 
1338
  getResizeHandle(x, y) {
1339
- if (this.selectedBoxIndex < 0) return null;
1340
 
1341
  const box = this.annotations[this.selectedBoxIndex];
1342
  const handleSize = 8;
@@ -1358,7 +1459,7 @@
1358
  return handle;
1359
  }
1360
  }
1361
- return null;
1362
  }
1363
 
1364
  getBoxAtPosition(x, y) {
 
649
  this.lastMouseX = 0;
650
  this.lastMouseY = 0;
651
 
652
+ // Add these new properties for edge resizing
653
+ this.isDraggingEdge = false;
654
+ this.draggingEdgeIndex = -1;
655
+ this.edgeResizeTolerance = 8;
656
+ this.showEdgeHandles = true;
657
+
658
  this.init();
659
  }
660
 
 
899
  }
900
  this.ctx.stroke();
901
 
902
+ // Draw corner points (larger for selected polygon)
903
  const pointRadius = isSelected ? 6 : 4;
904
  points.forEach((point, index) => {
905
  this.ctx.fillStyle = isSelected ? '#0066ff' : strokeColor;
 
907
  this.ctx.arc(point.x, point.y, pointRadius, 0, 2 * Math.PI);
908
  this.ctx.fill();
909
 
 
910
  if (isSelected) {
911
  this.ctx.strokeStyle = '#ffffff';
912
  this.ctx.lineWidth = 2;
 
914
  }
915
  });
916
 
917
+ // Draw edge handles for selected polygon
918
+ if (isSelected && points.length > 2 && this.showEdgeHandles) {
919
+ this.drawEdgeHandles(points);
920
+ }
921
+ }
922
+ drawEdgeHandles(points) {
923
+ this.ctx.fillStyle = 'rgba(0, 102, 255, 0.8)';
924
+ this.ctx.strokeStyle = '#ffffff';
925
+ this.ctx.lineWidth = 2;
926
+
927
+ for (let i = 0; i < points.length; i++) {
928
+ const nextIndex = (i + 1) % points.length;
929
+ const midX = (points[i].x + points[nextIndex].x) / 2;
930
+ const midY = (points[i].y + points[nextIndex].y) / 2;
931
+
932
+ // Draw square handle
933
+ const handleSize = 8;
934
+ this.ctx.fillRect(midX - handleSize / 2, midY - handleSize / 2, handleSize, handleSize);
935
+ this.ctx.strokeRect(midX - handleSize / 2, midY - handleSize / 2, handleSize, handleSize);
936
+ }
937
+ }
938
+
939
+ // NEW METHOD: Get edge handle at position
940
+ getEdgeHandleAtPosition(x, y, tolerance = 8) {
941
+ if (this.selectedBoxIndex >= 0 && this.annotations[this.selectedBoxIndex].type === 'segmentation') {
942
+ const points = this.annotations[this.selectedBoxIndex].points;
943
  for (let i = 0; i < points.length; i++) {
944
  const nextIndex = (i + 1) % points.length;
945
  const midX = (points[i].x + points[nextIndex].x) / 2;
946
  const midY = (points[i].y + points[nextIndex].y) / 2;
947
 
948
+ const distance = Math.sqrt(Math.pow(x - midX, 2) + Math.pow(y - midY, 2));
949
+ if (distance <= tolerance) {
950
+ return i;
951
+ }
952
  }
953
  }
954
+ return -1;
955
+ }
956
+
957
+ // NEW METHOD: Resize polygon edge
958
+ resizePolygonEdge(annotationIndex, edgeIndex, mouseX, mouseY) {
959
+ if (annotationIndex < 0 || annotationIndex >= this.annotations.length) return;
960
+
961
+ const annotation = this.annotations[annotationIndex];
962
+ if (annotation.type !== 'segmentation') return;
963
+
964
+ const points = annotation.points;
965
+ const nextIndex = (edgeIndex + 1) % points.length;
966
+
967
+ // Get the edge vector
968
+ const edgeVectorX = points[nextIndex].x - points[edgeIndex].x;
969
+ const edgeVectorY = points[nextIndex].y - points[edgeIndex].y;
970
+
971
+ // Get the edge normal (perpendicular vector)
972
+ const edgeLength = Math.sqrt(edgeVectorX * edgeVectorX + edgeVectorY * edgeVectorY);
973
+ if (edgeLength === 0) return;
974
+
975
+ const normalX = -edgeVectorY / edgeLength;
976
+ const normalY = edgeVectorX / edgeLength;
977
+
978
+ // Get edge midpoint
979
+ const edgeMidX = (points[edgeIndex].x + points[nextIndex].x) / 2;
980
+ const edgeMidY = (points[edgeIndex].y + points[nextIndex].y) / 2;
981
+
982
+ // Calculate how far to move the edge
983
+ const mouseVectorX = mouseX - edgeMidX;
984
+ const mouseVectorY = mouseY - edgeMidY;
985
+
986
+ // Project mouse movement onto the normal
987
+ const moveDistance = mouseVectorX * normalX + mouseVectorY * normalY;
988
+
989
+ // Move both edge points
990
+ const newX1 = Math.max(0, Math.min(this.originalWidth, points[edgeIndex].x + normalX * moveDistance));
991
+ const newY1 = Math.max(0, Math.min(this.originalHeight, points[edgeIndex].y + normalY * moveDistance));
992
+ const newX2 = Math.max(0, Math.min(this.originalWidth, points[nextIndex].x + normalX * moveDistance));
993
+ const newY2 = Math.max(0, Math.min(this.originalHeight, points[nextIndex].y + normalY * moveDistance));
994
+
995
+ points[edgeIndex].x = newX1;
996
+ points[edgeIndex].y = newY1;
997
+ points[nextIndex].x = newX2;
998
+ points[nextIndex].y = newY2;
999
+
1000
+ annotation.saved = false;
1001
  }
1002
 
1003
  // Polygon-specific editing methods
 
1147
  const pos = this.getMousePos(e);
1148
  this.lastMouseX = pos.x;
1149
  this.lastMouseY = pos.y;
1150
+ const handle = this.getResizeHandle(pos.x, pos.y);
1151
 
1152
  if (this.annotationMode === 'segmentation') {
1153
+ // Check if clicking on an edge handle of selected polygon
1154
  if (this.selectedBoxIndex >= 0) {
1155
+ const edgeHandleIndex = this.getEdgeHandleAtPosition(pos.x, pos.y);
1156
+ if (edgeHandleIndex >= 0) {
1157
+ this.isDraggingEdge = true;
1158
+ this.draggingEdgeIndex = edgeHandleIndex;
1159
+ this.canvas.style.cursor = handle.cursor;
1160
+ return;
1161
+ }
1162
+
1163
  const pointIndex = this.getPolygonPointAtPosition(pos.x, pos.y);
1164
  if (pointIndex >= 0) {
1165
  this.isDraggingPoint = true;
1166
  this.draggingPointIndex = pointIndex;
1167
+ this.canvas.style.cursor = handle.cursor;
1168
  return;
1169
  }
1170
 
1171
  // Check if clicking on an edge to add a point
1172
  const edgeIndex = this.getPolygonEdgeAtPosition(pos.x, pos.y);
1173
+ if (edgeIndex >= 0 && e.ctrlKey) {
1174
  this.addPolygonPoint(this.selectedBoxIndex, edgeIndex, pos.x, pos.y);
1175
  this.drawCanvas();
1176
  return;
 
1184
  this.isDragging = true;
1185
  this.dragStartX = pos.x;
1186
  this.dragStartY = pos.y;
1187
+ this.canvas.style.cursor = handle.cursor;
1188
  this.updateSelectedBoxInfo();
1189
  this.drawCanvas();
1190
  return;
 
1211
 
1212
  // Original bbox logic remains the same...
1213
  if (this.selectedBoxIndex >= 0) {
 
1214
  if (handle) {
1215
  this.isResizing = true;
1216
  this.resizeHandle = handle;
 
1225
  this.isDragging = true;
1226
  this.dragStartX = pos.x;
1227
  this.dragStartY = pos.y;
1228
+ this.canvas.style.cursor = handle.cursor;
1229
  this.updateSelectedBoxInfo();
1230
  this.drawCanvas();
1231
  return;
 
1273
  const pos = this.getMousePos(e);
1274
 
1275
  if (this.annotationMode === 'segmentation') {
1276
+ if (this.isDraggingEdge && this.selectedBoxIndex >= 0) {
1277
+ // Resize edge
1278
+ this.resizePolygonEdge(this.selectedBoxIndex, this.draggingEdgeIndex, pos.x, pos.y);
1279
+ this.drawCanvas();
1280
+ return;
1281
+ }
1282
+
1283
  if (this.isDraggingPoint && this.selectedBoxIndex >= 0) {
1284
  // Move individual point
1285
  this.movePolygonPoint(this.selectedBoxIndex, this.draggingPointIndex, pos.x, pos.y);
 
1334
 
1335
  onMouseUp() {
1336
  if (this.annotationMode === 'segmentation') {
1337
+ this.isDraggingEdge = false;
1338
+ this.draggingEdgeIndex = -1;
1339
  this.isDraggingPoint = false;
1340
  this.draggingPointIndex = -1;
1341
  this.isDragging = false;
 
1385
  }
1386
  updatePolygonCursor(x, y) {
1387
  if (this.selectedBoxIndex >= 0 && this.annotations[this.selectedBoxIndex].type === 'segmentation') {
1388
+ const handle = this.getResizeHandle(x, y);
1389
+ // Check for edge handles first
1390
+ const edgeHandleIndex = this.getEdgeHandleAtPosition(x, y);
1391
+ if (edgeHandleIndex >= 0) {
1392
+ this.canvas.style.cursor = handle.cursor;
1393
+ return;
1394
+ }
1395
+
1396
  const pointIndex = this.getPolygonPointAtPosition(x, y);
1397
  if (pointIndex >= 0) {
1398
+ this.canvas.style.cursor = handle.cursor;
1399
  return;
1400
  }
1401
 
 
1406
  }
1407
 
1408
  if (this.isPointInPolygon(x, y, this.annotations[this.selectedBoxIndex].points)) {
1409
+ this.canvas.style.cursor = handle.cursor;
1410
  return;
1411
  }
1412
  }
 
1437
  }
1438
 
1439
  getResizeHandle(x, y) {
1440
+ if (this.selectedBoxIndex < 0) return {cursor: 'move'};
1441
 
1442
  const box = this.annotations[this.selectedBoxIndex];
1443
  const handleSize = 8;
 
1459
  return handle;
1460
  }
1461
  }
1462
+ return {cursor: 'move'};
1463
  }
1464
 
1465
  getBoxAtPosition(x, y) {