tien_nemo

resize manual

...@@ -37,15 +37,31 @@ ...@@ -37,15 +37,31 @@
37 :style="getBoxStyle(item, index)" 37 :style="getBoxStyle(item, index)"
38 @click="onBoxClick(index)"> 38 @click="onBoxClick(index)">
39 39
40 - <div class="edge top" data-handle="top"></div> 40 + <div class="edge top" data-handle="top"
41 - <div class="edge right" data-handle="right"></div> 41 + @mousedown="startResize($event, index, 'top')">
42 - <div class="edge bottom" data-handle="bottom"></div> 42 + </div>
43 - <div class="edge left" data-handle="left"></div> 43 + <div class="edge right" data-handle="right"
44 + @mousedown="startResize($event, index, 'right')">
45 + </div>
46 + <div class="edge bottom" data-handle="bottom"
47 + @mousedown="startResize($event, index, 'bottom')">
48 + </div>
49 + <div class="edge left" data-handle="left"
50 + @mousedown="startResize($event, index, 'left')">
51 + </div>
44 <!-- 4 góc --> 52 <!-- 4 góc -->
45 - <div class="corner nw" data-handle="nw"></div> 53 + <div class="corner top-left" data-handle="top-left"
46 - <div class="corner ne" data-handle="ne"></div> 54 + @mousedown="startResize($event, index, 'top-left')">
47 - <div class="corner sw" data-handle="sw"></div> 55 + </div>
48 - <div class="corner se" data-handle="se"></div> 56 + <div class="corner top-right" data-handle="top-right"
57 + @mousedown="startResize($event, index, 'top-right')">
58 + </div>
59 + <div class="corner bottom-left" data-handle="bottom-left"
60 + @mousedown="startResize($event, index, 'bottom-left')">
61 + </div>
62 + <div class="corner bottom-right" data-handle="bottom-right"
63 + @mousedown="startResize($event, index, 'bottom-right')">
64 + </div>
49 65
50 <button v-if="item.isManual && item.showDelete" 66 <button v-if="item.isManual && item.showDelete"
51 class="delete-btn" 67 class="delete-btn"
...@@ -140,6 +156,60 @@ ...@@ -140,6 +156,60 @@
140 } 156 }
141 }, 157 },
142 methods: { 158 methods: {
159 + startResize(e, index, handle) {
160 + e.stopPropagation();
161 + this.resizing = {
162 + index,
163 + handle,
164 + startX: e.clientX,
165 + startY: e.clientY,
166 + origBox: [...this.ocrData[index].bbox], // [x1, y1, x2, y2]
167 + };
168 +
169 + document.addEventListener("mousemove", this.onResizing);
170 + document.addEventListener("mouseup", this.stopResize);
171 + },
172 +
173 + onResizing(e) {
174 + if (!this.resizing) return;
175 +
176 + const { index, handle, startX, startY, origBox } = this.resizing;
177 + const dx = (e.clientX - startX) * (this.imageWidth / this.$refs.pdfImage.clientWidth);
178 + const dy = (e.clientY - startY) * (this.imageHeight / this.$refs.pdfImage.clientHeight);
179 +
180 + let [x1, y1, x2, y2] = origBox;
181 +
182 + if (handle === 'top-left') {
183 + x1 += dx; y1 += dy;
184 + } else if (handle === 'top-right') {
185 + x2 += dx; y1 += dy;
186 + } else if (handle === 'bottom-left') {
187 + x1 += dx; y2 += dy;
188 + } else if (handle === 'bottom-right') {
189 + x2 += dx; y2 += dy;
190 + } else if (handle === 'top') {
191 + y1 += dy;
192 + } else if (handle === 'bottom') {
193 + y2 += dy;
194 + } else if (handle === 'left') {
195 + x1 += dx;
196 + } else if (handle === 'right') {
197 + x2 += dx;
198 + }
199 +
200 +
201 + // giữ không cho x1 > x2, y1 > y2
202 + if (x1 < x2 && y1 < y2) {
203 + this.$set(this.ocrData[index], "bbox", [x1, y1, x2, y2]);
204 + }
205 + },
206 +
207 + stopResize() {
208 + document.removeEventListener("mousemove", this.onResizing);
209 + document.removeEventListener("mouseup", this.stopResize);
210 + this.resizing = null;
211 + },
212 +
143 // Map field cho box (không set active, chỉ dùng để load data từ DB) 213 // Map field cho box (không set active, chỉ dùng để load data từ DB)
144 mapFieldToBox(index, fieldName, text = null) { 214 mapFieldToBox(index, fieldName, text = null) {
145 if (index == null) return; 215 if (index == null) return;
......