Annotation Plugin
Annotation Plugin
The annotation plugin (annotation-plugin) provides a complete set of drawing review and markup tools for WebCAD. All annotation entities are placed on the dedicated _ANNOTATION layer, supporting one-click show/hide and clear operations without affecting the original drawing.
Feature Overview
| Tool | Command | Description |
|---|---|---|
| Cloud | ANNO_CLOUD | Revision cloud annotation with arc length adapted to drawing extent |
| Arrow | ANNO_ARROW | Supports single-headed, double-headed, and polyline arrows |
| Rectangle | ANNO_RECT | Rectangular markup box |
| Ellipse | ANNO_ELLIPSE | Elliptical markup (polyline approximation, supports thicker display) |
| Text | ANNO_TEXT | Text annotation (delegates to MTEXT) |
| Leader | ANNO_LEADER | Leader annotation (delegates to MLEADER) |
| Freehand | ANNO_FREEHAND | Freehand sketch line |
| Stamp | ANNO_STAMP | Predefined stamps (Approved / Rejected / Reviewed / Modified / Void / Draft) |
| Highlight | ANNO_HIGHLIGHT | Semi-transparent rectangular highlight |
| Show | ANNO_SHOW | Show annotation layer |
| Hide | ANNO_HIDE | Hide annotation layer |
| Clear | ANNO_CLEAR | Clear all annotation entities |
| List | ANNO_LIST | Open the annotation list sidebar panel |
Installation and Loading
The built artifact of the annotation plugin is vcad-plugin-annotation.js, which can be loaded as follows:
// Load through PluginManager
const pm = PluginManager.getInstance();
await pm.loadFromUrl('./plugins/vcad-plugin-annotation.js');It can also be installed from the plugin marketplace.
Usage
1. Open Annotation Toolbar
Run the ANNOTATION command (or click the Annotation button under the Ribbon Review tab) to open the floating toolbar:
ANNOTATIONThe toolbar contains all annotation tools. Click an icon to start the corresponding annotation action.
2. Cloud Annotation
ANNO_CLOUDDraw a revision cloud. The arc length is automatically calculated based on the current view extent, and can also be specified manually. Supports Close (C) and Undo (U) operations.
3. Arrow Annotation
ANNO_ARROWSupports three arrow styles:
- S (Single): arrowhead at the endpoint
- D (Double): arrowheads at both ends
- P (Polyline): multi-segment polyline with an arrowhead at the end
4. Stamp Annotation
ANNO_STAMPEnter a number to select a predefined stamp:
| No. | Stamp |
|---|---|
| 1 | Approved |
| 2 | Rejected |
| 3 | Reviewed |
| 4 | Modified |
| 5 | Void |
| 6 | Draft |
After selection, click the placement position and the plugin automatically creates centered text with a rectangular border.
5. Annotation Management
ANNO_SHOW # Show all annotations
ANNO_HIDE # Hide all annotations
ANNO_CLEAR # Clear all annotations (undo supported)
ANNO_LIST # Open annotation list panelIn the annotation list panel, double-clicking a record automatically zooms to the corresponding annotation location.
Technical Design
Annotation Layer
All annotation entities are placed on the _ANNOTATION layer, whose color is red (ACI 1). Annotation commands automatically switch to this layer while running and restore the original layer afterward.
// Standard pattern for annotation commands
const svc = AnnotationLayerService.getInstance();
const prev = svc.setAsCurrentLayer(); // Switch to _ANNOTATION
try {
// Draw annotation entities...
} finally {
svc.restoreLayer(prev); // Restore original layer
}Adaptive Line Width
Annotations use polyline globalWidth for thick display instead of lineWeight:
globalWidthis always visible and does not depend on theLWDISPLAYswitch- Line width is automatically calculated from the current view WCS diagonal (
diag / 500) - Large-coordinate drawings (such as GIS coordinates around
10⁸) and small-coordinate drawings (around10²) both display correctly
import { getAnnoLineWidth } from './services/AnnotationLayerService';
const lw = getAnnoLineWidth(); // Calculate automatically
entity.globalWidth = lw;Cloud arc length adapts similarly (diag / 30), ensuring proper cloud appearance across drawings of different scales.
Command Delegation
Text annotation (ANNO_TEXT) and leader annotation (ANNO_LEADER) delegate to the built-in MTEXT / MLEADER commands. Because the WebCAD command system does not support nested command execution, a delayed dispatch via setTimeout is used:
// Switch layer first so main() can finish and release the command system
setTimeout(async () => {
await Engine.editor.executerWithOp('MTEXT');
svc.restoreLayer(prev);
}, 50);Note
Do not directly await Engine.editor.executerWithOp() inside a command's main(). That causes nested command execution and breaks command-system state.
Plugin Structure
annotation-plugin/
├── package.json
├── vite.config.ts
├── tsconfig.json
└── src/
├── index.ts # Entry: register commands, icons, Ribbon, menu
├── constants.ts # Layer name, colors, stamp presets
├── icons.ts # SVG icons
├── commands/
│ ├── AnnotationCommand.ts # Main command - opens floating toolbar
│ ├── AnnoCloudCommand.ts # Cloud annotation
│ ├── AnnoArrowCommand.ts # Arrow annotation (single / double / polyline)
│ ├── AnnoRectCommand.ts # Rectangle markup
│ ├── AnnoEllipseCommand.ts # Ellipse markup
│ ├── AnnoTextCommand.ts # Text annotation
│ ├── AnnoLeaderCommand.ts # Leader annotation
│ ├── AnnoFreehandCommand.ts# Freehand line
│ ├── AnnoStampCommand.ts # Stamp
│ ├── AnnoHighlightCommand.ts # Highlight
│ ├── AnnoShowCommand.ts # Show
│ ├── AnnoHideCommand.ts # Hide
│ ├── AnnoClearCommand.ts # Clear
│ └── AnnoListCommand.ts # List panel
├── services/
│ └── AnnotationLayerService.ts # Layer management + adaptive calculations
└── ui/
└── AnnoListPanel.ts # Annotation list sidebar panelRibbon and Menu
After the plugin is activated, it automatically adds:
- Ribbon: a
Reviewtab containing theAnnotationtools group andManagementgroup - Menu: a
Reviewmenu containing the annotation toolbar, show / hide / clear / list items
// Ribbon registration example
context.addRibbonTab({ id: 'review', label: 'Review', groups: [] }, 'plugins');
context.addRibbonGroup('review', {
id: 'annotation-tools',
label: 'Annotation',
primaryButtons: [
{ icon: 'annotation', cmd: 'ANNOTATION', prompt: 'Annotation toolbar', type: 'large' },
],
moreButtons: [
{ icon: 'anno_cloud', cmd: 'ANNO_CLOUD', prompt: 'Cloud annotation' },
{ icon: 'anno_arrow', cmd: 'ANNO_ARROW', prompt: 'Arrow annotation' },
// ...
],
});Next Steps
- Plugin Basics - understand the plugin interface and lifecycle
- Plugin Context - detailed
PluginContextAPI - Menu and Ribbon - UI extension methods
- Plugin Examples - more plugin development examples