Editing, Selection, and Undo
About 4 min
Editing, Selection, and Undo
Entity editing, selection set operations, and the undo system.
Entity Transformations
Move
const { LineEnt, Point2D, Engine } = vjcad;
const line = new LineEnt([0, 0], [100, 0]);
line.setDefaults();
Engine.addEntities(line);
// Move entity: move from point A to point B
line.move([0, 0], [50, 30]); // Supports [x, y] array form
// Must redraw to see the change
Engine.regen();Copy
// Use clone() to create an independent copy
const original = new LineEnt([0, 0], [100, 0]);
original.setDefaults();
Engine.addEntities(original);
const copy = original.clone();
copy.move([0, 0], [0, 50]); // Move the copy
copy.color = 2; // Modify copy properties
Engine.addEntities(copy); // Add the copy
Engine.regen();Rotate
const { Point2D, Engine } = vjcad;
// rotate(basePoint, angle) - rotate around a base point (angle in radians)
const basePoint = new Point2D(50, 50); // Requires a Point2D object
entity.rotate(basePoint, Math.PI / 4); // Rotate 45°
Engine.regen();Scale
const { Point2D, Engine } = vjcad;
// scale(basePoint, scaleFactor) - scale around a base point
const basePoint = new Point2D(0, 0);
entity.scale(basePoint, 0.5); // Scale down to 0.5x
entity.scale(basePoint, 2.0); // Scale up to 2x
Engine.regen();Mirror
const { Point2D, Engine } = vjcad;
// mirror(p1, p2) - mirror along the line defined by p1-p2
const p1 = new Point2D(100, 0);
const p2 = new Point2D(100, 100);
entity.mirror(p1, p2); // Mirror across the vertical line x=100
Engine.regen();Notes:
move()supports[x, y]array form- Point parameters of
rotate(),scale(), andmirror()must bePoint2Dobjects - Call
Engine.regen()after a transformation to see changes
Delete Entities
const { Engine } = vjcad;
// Delete a single entity
Engine.eraseEntities(entity);
// Delete multiple entities
Engine.eraseEntities([entity1, entity2, entity3]);
// After deletion, entity.isAlive becomes false
console.log(entity.isAlive); // falseDraw Order
const { Engine } = vjcad;
// Method 1: use commands
await Engine.editor.executerWithOp('ENTDRAWFRONT'); // Bring selected entities to front
await Engine.editor.executerWithOp('ENTDRAWBACK'); // Send selected entities to back
await Engine.editor.executerWithOp('LAYDRAWFRONT'); // Bring selected entities' layers to front
await Engine.editor.executerWithOp('LAYDRAWBACK'); // Send selected entities' layers to back
// Method 2: manipulate the items array directly
const items = Engine.currentSpace.items;
const idx = items.indexOf(entity);
if (idx > -1) {
items.splice(idx, 1); // Remove
items.push(entity); // Add to end (front-most)
Engine.pcanvas.regen(true);
}Grouping
const { GroupEnt, LineEnt, CircleEnt, Engine } = vjcad;
// Create entities
const line = new LineEnt([0, 0], [100, 0]);
const circle = new CircleEnt([50, 50], 20);
line.setDefaults();
circle.setDefaults();
// Create group
const group = new GroupEnt("MyGroup", [line, circle]);
group.setDefaults();
Engine.addEntities(group);
// Access entities in the group
group.items.forEach((item, index) => {
console.log(`${index}: ${item.type}, color: ${item.color}`);
});
// Explode the group
const explodedEntities = group.explode();
explodedEntities.forEach(ent => {
Engine.addEntities(ent);
});
Engine.eraseEntities(group);
Engine.regen(true);
// Use commands
await Engine.editor.executerWithOp('GROUP'); // Create group
await Engine.editor.executerWithOp('UNGROUP'); // UngroupHighlighting
const { Engine } = vjcad;
// Highlight specified entities
Engine.highLightEntities([entity1, entity2]);
// Clear highlight
Engine.clearHighLight();
// Highlighting is a temporary visual effect and does not affect entity propertiesSelection Set Operations
Set Selection Set
const { Engine } = vjcad;
// Select a single entity
Engine.ssSetFirst([entity]);
// Select multiple entities
Engine.ssSetFirst([entity1, entity2, entity3]);
// Clear selection set
Engine.ssSetFirst([]);
// Select all entities
const allEntities = Engine.getEntities();
Engine.ssSetFirst(allEntities);Get Selection Set
const { Engine } = vjcad;
// Get current selection set
const selected = Engine.ssGetFirst();
console.log(`Selected ${selected.length} entities`);
// Iterate through selection set
selected.forEach((entity, index) => {
console.log(`${index + 1}. Type: ${entity.type}, color: ${entity.color}`);
});
// Operate on selected entities
selected.forEach(entity => {
entity.color = 1;
});
Engine.regen();Get Entities
Get All Entities
const { Engine } = vjcad;
const allEntities = Engine.getEntities();Get by Type
const { Engine } = vjcad;
const lines = Engine.getEntitiesByType('LINE');
const circles = Engine.getEntitiesByType('CIRCLE');
const arcs = Engine.getEntitiesByType('ARC');
const plines = Engine.getEntitiesByType('PLINE');
const texts = Engine.getEntitiesByType('TEXT');
const mtexts = Engine.getEntitiesByType('MTEXT');
const inserts = Engine.getEntitiesByType('INSERT');
const hatches = Engine.getEntitiesByType('HATCH');Filter by Condition
const { Engine } = vjcad;
// Filter by color
const redEntities = Engine.getEntities(ent => ent.color === 1);
// Filter by layer
const layerAEntities = Engine.getEntities(ent => ent.layer === "LayerA");
// Combined condition
const redLines = Engine.getEntities(ent =>
ent.type === "LINE" && ent.color === 1
);
// Custom complex condition
const largeCircles = Engine.getEntities(ent =>
ent.type === "CIRCLE" && ent.radius > 50
);
// Exclude some entities
const notHidden = Engine.getEntities(ent =>
ent.layer !== "HiddenLayer"
);Undo System
Basic Undo/Redo
const { Engine } = vjcad;
const undoMgr = Engine.undoManager;
// Check whether undo/redo is available
if (undoMgr.canUndo()) {
undoMgr.undo();
}
if (undoMgr.canRedo()) {
undoMgr.redo();
}Undo Marks
const { Engine, Point2D } = vjcad;
const undoMgr = Engine.undoManager;
// Undo mark for adding entities
undoMgr.added_undoMark([entity1, entity2]);
// Undo mark for deleting entities
undoMgr.erased_undoMark([entity1, entity2]);
// Undo mark for move operation
const fromPt = new Point2D(0, 0);
const toPt = new Point2D(40, 0);
entity.move(fromPt, toPt);
undoMgr.moved_undoMark([entity], fromPt, toPt);
// Undo mark for rotate operation
undoMgr.rotate_undoMark(entities, basePoint, angle);
// Undo mark for scale operation
undoMgr.scaled_undoMark(entities, basePoint, scale);Note: Engine.addEntities() and Engine.eraseEntities() automatically record undo information.
Undo Grouping
Merge multiple operations into a single undo action.
const { Engine, LineEnt, CircleEnt } = vjcad;
const undoMgr = Engine.undoManager;
// Start undo group
undoMgr.start_undoMark();
try {
// Perform multiple operations
const line = new LineEnt([0, 0], [100, 0]);
line.setDefaults();
Engine.addEntities(line);
const circle = new CircleEnt([50, 50], 30);
circle.setDefaults();
Engine.addEntities(circle);
// Move operation
line.move([0, 0], [50, 0]);
undoMgr.moved_undoMark([line], new Point2D(0, 0), new Point2D(50, 0));
} finally {
// End undo group (must ensure it is called)
undoMgr.end_undoMark();
}
// Undo will revert all operations in the group at onceView Operations
Zoom
const { Engine } = vjcad;
// Zoom to extents
Engine.zoomExtents();
// Zoom to specified entities
Engine.zoomToEntities([entity1, entity2]);
// Zoom with padding
Engine.zoomToEntities(entities, {
padding: { top: 50, bottom: 50, left: 50, right: 50 }
});Refresh Display
const { Engine } = vjcad;
// render() - lowest-level rendering, GPU draw only
Engine.render();
// redraw() - update view transform and render
Engine.redraw();
// regen() - partial update, only redraw modified entities (fast)
Engine.regen();
// regen(true) - fully redraw all graphics (slow)
Engine.regen(true);Preview
const { Engine } = vjcad;
// Draw preview entities
Engine.drawPreviewEntity(entity);
Engine.drawPreviewEntities([entity1, entity2]);
// Clear preview
Engine.clearPreview();Set View Center
const { Engine, Point2D } = vjcad;
// Set view center point
Engine.setCenter(new Point2D(100, 100));
// Set with padding
Engine.setCenter(new Point2D(100, 100), true, {
top: 50, bottom: 50, left: 50, right: 50
});Background Color
const { Engine } = vjcad;
// Set background grayscale value (0 = pure black, 255 = pure white)
Engine.setBgc(0); // Pure black
Engine.setBgc(33); // Dark gray (default dark theme)
Engine.setBgc(255); // Pure white
Engine.redraw();Theme
const { Engine } = vjcad;
// Switch theme
Engine.THEME_MODE = 0; // Dark theme
Engine.setBgc(33);
Engine.redraw();
Engine.THEME_MODE = 1; // Light theme
Engine.setBgc(255);
Engine.redraw();
// Check current theme
const isDark = Engine.isDarkTheme();Screen Range
const { Engine } = vjcad;
// Get screen bounds (world coordinate system)
const bounds = Engine.getScreenBoundsWcs();
// Returns: { minX, minY, maxX, maxY }
// Get entities currently on screen
const screenEntities = Engine.getScreenEntities();
const expandedEntities = Engine.getScreenEntities(1.5); // Expand range by 1.5xZoom Factor
const { Engine } = vjcad;
// Get current zoom scale
const zoom = Engine.currentSpace.zoom;
// Set mouse-wheel zoom factor (1-100, default 75)
Engine.ZOOMFACTOR = 50; // Slower zoom
Engine.ZOOMFACTOR = 100; // Faster zoom