Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
65b2aa4
Remove cmd-click on a shape to select everything
nick-skriabin Oct 9, 2025
34f2f87
Support double click
nick-skriabin Oct 9, 2025
6327bc8
Toggle transformation mode
nick-skriabin Oct 10, 2025
404fa3f
Allow selecting multiple shapes
nick-skriabin Oct 10, 2025
2d9761d
Multi-selection
nick-skriabin Oct 13, 2025
f9a146b
Selection
nick-skriabin Oct 13, 2025
6707960
Transformation
nick-skriabin Oct 13, 2025
907d954
Translation
nick-skriabin Oct 13, 2025
3abb78d
Applying transformation from global transformer
nick-skriabin Oct 13, 2025
8029b1d
Merge branch 'develop' into fb-bros-464/vector-selection
nick-skriabin Oct 13, 2025
8a5da16
Merge branch 'develop' into fb-bros-464/vector-selection
nick-skriabin Oct 14, 2025
534c70b
Reset everything
nick-skriabin Oct 14, 2025
9d3fd64
Remove cmd-click, add double click functionality
nick-skriabin Oct 14, 2025
4988900
Transform mode
nick-skriabin Oct 14, 2025
0b27edc
Remove selection tracker
nick-skriabin Oct 14, 2025
64c6e63
Multi-selection WIP
nick-skriabin Oct 14, 2025
859fea5
Merge branch 'develop' into fb-bros-464/vector-selection
nick-skriabin Oct 20, 2025
740f58d
Biome
nick-skriabin Oct 21, 2025
6dbb498
Merge branch 'develop' into fb-bros-464/vector-selection
nick-skriabin Oct 22, 2025
df204ab
Multi-selection
nick-skriabin Oct 22, 2025
c61d17e
Apply transformations to points
nick-skriabin Oct 22, 2025
f7a3fd0
Transformation wip
nick-skriabin Oct 22, 2025
06ba828
Transformation WIP
nick-skriabin Oct 22, 2025
7def038
Transformation WIP
nick-skriabin Oct 23, 2025
6b3b526
Merge branch 'develop' into fb-bros-464/vector-selection
nick-skriabin Oct 23, 2025
49c7d84
Transform multiple shapes
nick-skriabin Oct 23, 2025
774a75d
Merge branch 'develop' into fb-bros-464/vector-selection
nick-skriabin Oct 24, 2025
a1b6706
Various tiny fixes
nick-skriabin Oct 24, 2025
e319cbc
Restore double click
nick-skriabin Oct 24, 2025
9388c02
Fix alt-click to delete points
nick-skriabin Oct 24, 2025
df5814e
ci: Build tag docs
robot-ci-heartex Oct 27, 2025
5b68d5d
Merge branch 'develop' into 'fb-bros-464/vector-selection'
hlomzik Oct 27, 2025
9e2a991
Transform bounds
nick-skriabin Oct 27, 2025
65b5279
Proper bounds
nick-skriabin Oct 27, 2025
cf3b233
Proper bounds constraints
nick-skriabin Oct 27, 2025
76f229d
Fix regions coordinates reset (regression)
nick-skriabin Oct 27, 2025
3a799cd
Double click handling
nick-skriabin Oct 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/source/includes/tags/vector.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
| [skeleton] | <code>boolean</code> | <code>false</code> | Enables skeleton mode to allow branch paths |
| [minPoints] | <code>number</code> \| <code>none</code> | <code>none</code> | Minimum allowed number of points |
| [maxPoints] | <code>number</code> \| <code>none</code> | <code>none</code> | Maximum allowed number of points |
| [constrainToBounds] | <code>boolean</code> | <code>false</code> | Whether to keep shapes inside image bounds |
| [pointSizeEnabled] | <code>number</code> | <code>5</code> | Size of a point in pixels when shape is selected |
| [pointSizeDisabled] | <code>number</code> | <code>3</code> | Size of a point in pixels when shape is not selected |

1 change: 0 additions & 1 deletion docs/source/includes/tags/vectorlabels.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
| [skeleton] | <code>boolean</code> | <code>false</code> | Enables skeleton mode to allow branch paths |
| [minPoints] | <code>number</code> \| <code>none</code> | <code>none</code> | Minimum allowed number of points |
| [maxPoints] | <code>number</code> \| <code>none</code> | <code>none</code> | Maximum allowed number of points |
| [constrainToBounds] | <code>boolean</code> | <code>false</code> | Whether to keep shapes inside image bounds |
| [pointsizeenabled] | <code>number</code> | <code>5</code> | Size of a point in pixels when shape is selected |
| [pointsizedisabled] | <code>number</code> | <code>5</code> | Size of a point in pixels when shape is not selected |

16 changes: 1 addition & 15 deletions web/libs/core/src/lib/utils/schema/tags.json
Original file line number Diff line number Diff line change
Expand Up @@ -2738,13 +2738,6 @@
"required": false,
"default": "none"
},
"constrainToBounds": {
"name": "constrainToBounds",
"description": "Whether to keep shapes inside image bounds",
"type": ["true", "false"],
"required": false,
"default": false
},
"pointSizeEnabled": {
"name": "pointSizeEnabled",
"description": "Size of a point in pixels when shape is selected",
Expand All @@ -2763,7 +2756,7 @@
},
"VectorLabels": {
"name": "VectorLabels",
"description": "The `VectorLabels` tag is used to create labeled vectors. Use to apply labels to vectors in semantic segmentation tasks.\n\nUse with the following data types: image.\n\n## Key Features\n\n### Point Management\n- **Add Points**: Click on empty space, Shift+click on path segments\n- **Edit Points**: Drag to reposition, Shift+click to convert regular ↔ bezier\n- **Delete Points**: Alt+click on existing points\n- **Multi-Selection**: Select multiple points for batch transformations\n- **Break Closed Path**: Alt+click on any segment of a closed path to break it at that specific segment\n\n### Bezier Curves\n- **Create**: Drag while adding points or convert existing points\n- **Edit**: Drag control points, disconnect/reconnect control handles\n- **Control**: `curves` prop to enable/disable bezier functionality\n\n## Keyboard Shortcuts & Hotkeys\n\n### Point Creation & Editing\n- **Click**: Add new point in drawing mode\n- **Shift + Click** on a segment: Add point on path segment (insert between existing points)\n- **Shift + Drag**: Create bezier point with control handles\n- **Shift + Click** on a point: Convert point between regular ↔ bezier\n- **Alt + Click** on a segment: Break closed path at segment (when path is closed)\n\n### Point Selection\n- **Click**: Select single point\n- **Cmd/Ctrl + Click**: Add point to multi-selection\n- **Cmd/Ctrl + Click on shape**: Select all points in the path\n- **Cmd/Ctrl + Click on point**: Toggle point selection in multi-selection\n\n### Path Management\n- **Click on first/last point**: Close path bidirectionally (first→last or last→first)\n- **Shift + Click**: Add point on path segment without closing\n\n### Bezier Curve Control\n- **Drag control points**: Adjust curve shape\n- **Alt + Drag control point**: Disconnect control handles (make asymmetric)\n- **Shift + Drag**: Create new bezier point with control handles\n\n### Multi-Selection & Transformation\n- **Select multiple points**: Use Cmd/Ctrl + Click to build selection\n- **Transform selection**: Use transformer handles for rotation, scaling, and translation\n- **Clear selection**: Click on any point\n\n## Usage Examples\n\n### Basic Vector Path\n```jsx\n<View>\n <Image name=\"image\" value=\"$image\" />\n <VectorLabels name=\"labels\" toName=\"image\">\n <Label value=\"Road\" />\n <Label value=\"Boundary\" />\n </VectorLabels>\n</View>\n```\n\n### Polygon with Bezier Support\n```jsx\n<View>\n <Image name=\"image\" value=\"$image\" />\n <VectorLabels\n name=\"polygons\"\n toName=\"image\"\n closable={true}\n curves={true}\n minPoints=\"3\"\n maxPoints=\"20\"\n >\n <Label value=\"Building\" />\n <Label value=\"Park\" />\n </VectorLabels>\n</View>\n```\n\n### Skeleton Mode for Branching Paths\n```jsx\n<View>\n <Image name=\"image\" value=\"$image\" />\n <VectorLabels\n name=\"skeleton\"\n toName=\"image\"\n skeleton={true}\n closable={false}\n curves={true}\n >\n <Label value=\"Tree\" />\n <Label value=\"Branch\" />\n </VectorLabels>\n</View>\n```\n\n### Keypoint Annotation Tool\n```jsx\n<View>\n <Image name=\"image\" value=\"$image\" />\n <VectorLabels\n name=\"keypoints\"\n toName=\"image\"\n closable={false}\n curves={false}\n minPoints=\"1\"\n maxPoints=\"1\"\n >\n <Label value=\"Eye\" />\n <Label value=\"Nose\" />\n <Label value=\"Mouth\" />\n </VectorLabels>\n</View>\n```\n\n### Constrained Drawing\n```jsx\n<View>\n <Image name=\"image\" value=\"$image\" />\n <VectorLabels\n name=\"constrained\"\n toName=\"image\"\n closable={true}\n curves={true}\n constraintoBounds={true}\n snap=\"pixel\"\n minPoints=\"4\"\n maxPoints=\"12\"\n >\n <Label value=\"Region\" />\n </VectorLabels>\n</View>\n```\n\n## Advanced Features\n\n### Path Breaking\nWhen a path is closed, you can break it at any segment:\n- **Alt + Click** on any segment of a closed path\n- The path breaks at that segment\n- The breaking point becomes the first element\n- The point before breaking becomes active\n\n### Skeleton Mode\n- **Purpose**: Create branching paths instead of linear sequences\n- **Behavior**: New points connect to the active point, not the last added point\n- **Use Case**: Tree structures, network diagrams, anatomical features\n\n### Bezier Curve Management\n- **Symmetric Control**: By default, control points move symmetrically\n- **Asymmetric Control**: Hold Alt while dragging to disconnect handles\n- **Control Point Visibility**: Control points are shown when editing bezier points\n\n### Multi-Selection Workflow\n1. **Build Selection**: Use Cmd/Ctrl + Click to add points\n2. **Transform**: Use transformer handles for rotation, scaling, translation\n3. **Batch Operations**: Apply transformations to all selected points\n4. **Clear**: Click outside or use programmatic methods\n\n## Props Reference",
"description": "The `VectorLabels` tag is used to create labeled vectors. Use to apply labels to vectors in semantic segmentation tasks.\n\nUse with the following data types: image.\n\n## Key Features\n\n### Point Management\n- **Add Points**: Click on empty space, Shift+click on path segments\n- **Edit Points**: Drag to reposition, Shift+click to convert regular ↔ bezier\n- **Delete Points**: Alt+click on existing points\n- **Multi-Selection**: Select multiple points for batch transformations\n- **Break Closed Path**: Alt+click on any segment of a closed path to break it at that specific segment\n\n### Bezier Curves\n- **Create**: Drag while adding points or convert existing points\n- **Edit**: Drag control points, disconnect/reconnect control handles\n- **Control**: `curves` prop to enable/disable bezier functionality\n\n## Keyboard Shortcuts & Hotkeys\n\n### Point Creation & Editing\n- **Click**: Add new point in drawing mode\n- **Shift + Click** on a segment: Add point on path segment (insert between existing points)\n- **Shift + Drag**: Create bezier point with control handles\n- **Shift + Click** on a point: Convert point between regular ↔ bezier\n- **Alt + Click** on a segment: Break closed path at segment (when path is closed)\n\n### Point Selection\n- **Click**: Select single point\n- **Cmd/Ctrl + Click**: Add point to multi-selection\n- **Cmd/Ctrl + Click on shape**: Select all points in the path\n- **Cmd/Ctrl + Click on point**: Toggle point selection in multi-selection\n\n### Path Management\n- **Click on first/last point**: Close path bidirectionally (first→last or last→first)\n- **Shift + Click**: Add point on path segment without closing\n\n### Bezier Curve Control\n- **Drag control points**: Adjust curve shape\n- **Alt + Drag control point**: Disconnect control handles (make asymmetric)\n- **Shift + Drag**: Create new bezier point with control handles\n\n### Multi-Selection & Transformation\n- **Select multiple points**: Use Cmd/Ctrl + Click to build selection\n- **Transform selection**: Use transformer handles for rotation, scaling, and translation\n- **Clear selection**: Click on any point\n\n## Usage Examples\n\n### Basic Vector Path\n```jsx\n<View>\n <Image name=\"image\" value=\"$image\" />\n <VectorLabels name=\"labels\" toName=\"image\">\n <Label value=\"Road\" />\n <Label value=\"Boundary\" />\n </VectorLabels>\n</View>\n```\n\n### Polygon with Bezier Support\n```jsx\n<View>\n <Image name=\"image\" value=\"$image\" />\n <VectorLabels\n name=\"polygons\"\n toName=\"image\"\n closable={true}\n curves={true}\n minPoints=\"3\"\n maxPoints=\"20\"\n >\n <Label value=\"Building\" />\n <Label value=\"Park\" />\n </VectorLabels>\n</View>\n```\n\n### Skeleton Mode for Branching Paths\n```jsx\n<View>\n <Image name=\"image\" value=\"$image\" />\n <VectorLabels\n name=\"skeleton\"\n toName=\"image\"\n skeleton={true}\n closable={false}\n curves={true}\n >\n <Label value=\"Tree\" />\n <Label value=\"Branch\" />\n </VectorLabels>\n</View>\n```\n\n### Keypoint Annotation Tool\n```jsx\n<View>\n <Image name=\"image\" value=\"$image\" />\n <VectorLabels\n name=\"keypoints\"\n toName=\"image\"\n closable={false}\n curves={false}\n minPoints=\"1\"\n maxPoints=\"1\"\n >\n <Label value=\"Eye\" />\n <Label value=\"Nose\" />\n <Label value=\"Mouth\" />\n </VectorLabels>\n</View>\n```\n\n## Advanced Features\n\n### Path Breaking\nWhen a path is closed, you can break it at any segment:\n- **Alt + Click** on any segment of a closed path\n- The path breaks at that segment\n- The breaking point becomes the first element\n- The point before breaking becomes active\n\n### Skeleton Mode\n- **Purpose**: Create branching paths instead of linear sequences\n- **Behavior**: New points connect to the active point, not the last added point\n- **Use Case**: Tree structures, network diagrams, anatomical features\n\n### Bezier Curve Management\n- **Symmetric Control**: By default, control points move symmetrically\n- **Asymmetric Control**: Hold Alt while dragging to disconnect handles\n- **Control Point Visibility**: Control points are shown when editing bezier points\n\n### Multi-Selection Workflow\n1. **Build Selection**: Use Cmd/Ctrl + Click to add points\n2. **Transform**: Use transformer handles for rotation, scaling, translation\n3. **Batch Operations**: Apply transformations to all selected points\n4. **Clear**: Click outside or use programmatic methods\n\n## Props Reference",
"attrs": {
"name": {
"name": "name",
Expand Down Expand Up @@ -2879,13 +2872,6 @@
"required": false,
"default": "none"
},
"constrainToBounds": {
"name": "constrainToBounds",
"description": "Whether to keep shapes inside image bounds",
"type": ["true", "false"],
"required": false,
"default": false
},
"pointsizeenabled": {
"name": "pointsizeenabled",
"description": "Size of a point in pixels when shape is selected",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,21 @@ export default class TransformerComponent extends Component {
});
};

applyTransformToVectorRegions = () => {
if (!this.transformer) return;

const { item } = this.props;
const { selectedRegions } = item;

// Only apply custom transform logic for VectorRegion instances
selectedRegions.forEach((region) => {
if (region.applyTransform && typeof region.applyTransform === 'function') {
console.log('🔄 ImageTransformer calling applyTransform on VectorRegion:', region.id);
region.applyTransform({}, null);
}
});
};

renderLSTransformer() {
return (
<>
Expand Down Expand Up @@ -214,10 +229,14 @@ export default class TransformerComponent extends Component {
}}
dragBoundFunc={this.dragBoundFunc}
onDragEnd={() => {
// Call applyTransform for VectorRegion instances
this.applyTransformToVectorRegions();
this.unfreeze();
setTimeout(this.checkNode);
}}
onTransformEnd={() => {
// Call applyTransform for VectorRegion instances
this.applyTransformToVectorRegions();
setTimeout(this.checkNode);
}}
backSelector={this.props.draggableBackgroundSelector}
Expand Down Expand Up @@ -262,10 +281,14 @@ export default class TransformerComponent extends Component {
}}
dragBoundFunc={this.dragBoundFunc}
onDragEnd={() => {
// Call applyTransform for VectorRegion instances
this.applyTransformToVectorRegions();
this.unfreeze();
setTimeout(this.checkNode);
}}
onTransformEnd={() => {
// Call applyTransform for VectorRegion instances
this.applyTransformToVectorRegions();
setTimeout(this.checkNode);
}}
backSelector={this.props.draggableBackgroundSelector}
Expand Down
Loading
Loading