From 00d6c68b2f9cd36c329f442cc28ec1b253b68724 Mon Sep 17 00:00:00 2001 From: Adriano Date: Sun, 8 Feb 2026 10:29:30 +0100 Subject: [PATCH] fix: enable scale/rotation on annotation objects and restore transforms on load - Remove hasControls:false and lockScaling from markers so resize/rotate handles appear - Add setActiveObject() after creating arrows and rectangles for immediate control visibility - Restore angle, scaleX, scaleY when loading saved annotations (all object types) Co-Authored-By: Claude Opus 4.6 --- client/static/js/annotation-editor.js | 36 ++++++++++++++++++------ client/templates/maker/task_drawing.html | 2 +- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/client/static/js/annotation-editor.js b/client/static/js/annotation-editor.js index 6eb40e8..44c7c67 100644 --- a/client/static/js/annotation-editor.js +++ b/client/static/js/annotation-editor.js @@ -403,10 +403,7 @@ function annotationEditor() { left: x, top: y, selectable: true, - hasControls: false, hasBorders: true, - lockScalingX: true, - lockScalingY: true, // Custom properties objectType: 'marker', markerNumber: markerNumber, @@ -469,6 +466,7 @@ function annotationEditor() { }); this.canvas.add(arrow); + this.canvas.setActiveObject(arrow); this.isDirty = true; window.dispatchEvent(new CustomEvent('annotations-changed', { detail: { json: this.getAnnotationsJson() } })); return arrow; @@ -505,6 +503,7 @@ function annotationEditor() { }); this.canvas.add(rect); + this.canvas.setActiveObject(rect); this.isDirty = true; window.dispatchEvent(new CustomEvent('annotations-changed', { detail: { json: this.getAnnotationsJson() } })); return rect; @@ -885,8 +884,15 @@ function annotationEditor() { if (obj.type === 'marker') { var savedColor = this.currentColor; if (obj.fill) this.currentColor = obj.fill; - this.addMarker(obj.left, obj.top, obj.markerNumber); + var created = this.addMarker(obj.left, obj.top, obj.markerNumber); this.currentColor = savedColor; + // Restore transforms (scale + rotation) + created.set({ + angle: obj.angle || 0, + scaleX: obj.scaleX || 1, + scaleY: obj.scaleY || 1, + }); + created.setCoords(); } else if (obj.type === 'arrow') { var savedColor2 = this.currentColor; var savedWidth = this.currentStrokeWidth; @@ -900,10 +906,19 @@ function annotationEditor() { var y1 = obj.y1 != null ? obj.y1 : obj.top; var x2 = obj.x2 != null ? obj.x2 : obj.left + (obj.width || 100); var y2 = obj.y2 != null ? obj.y2 : obj.top + (obj.height || 50); - this.addArrow(x1, y1, x2, y2); + var created2 = this.addArrow(x1, y1, x2, y2); this.currentColor = savedColor2; this.currentStrokeWidth = savedWidth; this.currentLineDash = savedDash; + // Restore transforms (position + scale + rotation) + created2.set({ + left: obj.left, + top: obj.top, + angle: obj.angle || 0, + scaleX: obj.scaleX || 1, + scaleY: obj.scaleY || 1, + }); + created2.setCoords(); } else if (obj.type === 'area') { var savedColor3 = this.currentColor; var savedWidth2 = this.currentStrokeWidth; @@ -912,12 +927,17 @@ function annotationEditor() { if (obj.strokeWidth) this.currentStrokeWidth = obj.strokeWidth; if (obj.lineDash) this.currentLineDash = obj.lineDash; else this.currentLineDash = []; - var w = (obj.width || 150) * (obj.scaleX || 1); - var h = (obj.height || 100) * (obj.scaleY || 1); - this.addRect(obj.left, obj.top, w, h); + var created3 = this.addRect(obj.left, obj.top, obj.width || 150, obj.height || 100); this.currentColor = savedColor3; this.currentStrokeWidth = savedWidth2; this.currentLineDash = savedDash2; + // Restore transforms (scale + rotation) + created3.set({ + angle: obj.angle || 0, + scaleX: obj.scaleX || 1, + scaleY: obj.scaleY || 1, + }); + created3.setCoords(); } } diff --git a/client/templates/maker/task_drawing.html b/client/templates/maker/task_drawing.html index be2008e..8fc348a 100644 --- a/client/templates/maker/task_drawing.html +++ b/client/templates/maker/task_drawing.html @@ -353,7 +353,7 @@ - +