A complete guide to using hatch entities (HatchEnt), including built-in patterns, custom patterns, and boundary creation.
WebCAD includes 80+ built-in hatch patterns, covering ANSI, ISO, JIS standards and various material patterns.
const { HatchEnt, PolylineEnt, Engine, Edge, Edges, EdgeType } = vjcad;
// 1. Create closed boundary
const boundary = new PolylineEnt();
boundary.addVertex([0, 0]);
boundary.addVertex([100, 0]);
boundary.addVertex([100, 60]);
boundary.addVertex([0, 60]);
boundary.isClosed = true;
boundary.setDefaults();
// 2. Create hatch entity
const hatch = new HatchEnt();
hatch.patternName = "SOLID"; // Pattern name
hatch.patternScale = 1; // Pattern scale
// 3. Create boundary from polyline
const edge = new Edge();
edge.edgeType = EdgeType.Polyline;
edge.bulgePoints = boundary.bulgePoints.clone();
const edges = new Edges();
edges.add(edge);
// 4. Set boundary
hatch.setLoops(edges);
hatch.setDefaults();
hatch.color = 3; // Green
// 5. Add to canvas
Engine.addEntities([boundary, hatch]);
Engine.zoomExtents();
| Property | Description |
|---|
patternName | Pattern name (e.g. "SOLID", "ANSI31") |
patternScale | Pattern scale (default 1) |
patternAngle | Pattern angle (degrees) |
color | Fill color |
const patternManager = Engine.patternManager;
const allPatternNames = patternManager.getAllPatternNames();
console.log(`Total ${allPatternNames.length} hatch patterns`);
| Pattern | Description |
|---|
SOLID | Solid fill |
| Pattern | Description |
|---|
ANSI31 | Iron, brick and stone (45° diagonal) |
ANSI32 | Steel |
ANSI33 | Bronze, brass and copper |
ANSI34 | Plastic and rubber |
ANSI35 | Fire brick and refractory material |
ANSI36 | Marble, slate and glass |
ANSI37 | Lead, zinc, magnesium and insulation (cross diagonal) |
ANSI38 | Aluminum |
| Pattern | Description |
|---|
AR-B816 | 8x16 block brick running bond |
AR-B816C | 8x16 block brick running bond (with mortar joints) |
AR-B88 | 8x8 block brick running bond |
AR-BRELM | Standard brick English bond |
AR-BRSTD | Standard brick running bond |
AR-CONC | Random dots and stone pattern (concrete) |
AR-HBONE | Herringbone pattern |
AR-PARQ1 | Parquet flooring pattern |
AR-RROOF | Roof shingle pattern |
AR-RSHKE | Roof wood shake pattern |
AR-SAND | Random dot pattern (sand) |
| Pattern | Description |
|---|
ACAD_ISO02W100 | Dashed line |
ACAD_ISO03W100 | Dash space line |
ACAD_ISO04W100 | Long dash dot line |
ACAD_ISO05W100 | Long dash double dot line |
ACAD_ISO06W100 | Long dash triple dot line |
ACAD_ISO07W100 | Dot line |
ACAD_ISO08W100 | Long dash short dash line |
ACAD_ISO09W100 | Long dash double short dash line |
ACAD_ISO10W100 | Dash dot line |
ACAD_ISO11W100 | Double dash dot line |
ACAD_ISO12W100 | Dash double dot line |
ACAD_ISO13W100 | Double dash double dot line |
ACAD_ISO14W100 | Dash triple dot line |
ACAD_ISO15W100 | Double dash triple dot line |
| Pattern | Description |
|---|
JIS_LC_8 | LC pattern (@8) |
JIS_LC_8A | LC pattern (@8 variant) |
JIS_LC_20 | LC pattern (@20) |
JIS_LC_20A | LC pattern (@20 variant) |
JIS_RC_10 | RC pattern (@10) |
JIS_RC_15 | RC pattern (@15) |
JIS_RC_18 | RC pattern (@18) |
JIS_RC_30 | RC pattern (@30) |
JIS_STN_1E | Stone pattern (@1) |
JIS_STN_2.5 | Stone pattern (@2.5) |
JIS_WOOD | Wood pattern |
| Pattern | Description |
|---|
ANGLE | Angle steel |
BOX | Box steel |
BRASS | Brass |
BRICK | Brick |
BRSTONE | Brick and stone |
CLAY | Clay |
CORK | Cork |
CROSS | Cross shape |
DASH | Dashed |
DOLMIT | Geological |
DOTS | Dots |
EARTH | Earth |
ESCHER | Escher pattern |
FLEX | Flexible material |
GRASS | Grass |
GRATE | Grate |
GRAVEL | Gravel |
HEX | Hexagon |
HONEY | Honeycomb |
HOUND | Houndstooth |
INSUL | Insulation |
LINE | Parallel horizontal lines |
MUDST | Mudstone |
NET | Horizontal/vertical grid |
NET3 | Net 0-60-120 |
PLAST | Plastic |
PLASTI | Plastic (variant) |
SACNCR | Concrete |
SQUARE | Small squares |
STARS | Six-pointed stars |
STEEL | Steel |
SWAMP | Swamp |
TRANS | Heat transfer material |
TRIANG | Equilateral triangles |
ZIGZAG | Zigzag |
GOST_GLASS | Glass (GOST) |
GOST_WOOD | Wood (GOST) |
GOST_GROUND | Ground (GOST) |
const boundary = new PolylineEnt();
boundary.setPoints([[0, 0], [60, 0], [60, 50], [30, 70], [0, 50]]);
boundary.isClosed = true;
boundary.setDefaults();
const edges = new Edges();
const edge = new Edge();
edge.edgeType = EdgeType.Polyline;
edge.bulgePoints = boundary.bulgePoints.clone();
edges.add(edge);
hatch.setLoops(edges);
const { CircleEnt } = vjcad;
const circle = new CircleEnt([100, 50], 30);
circle.setDefaults();
const edges = new Edges();
const edge = new Edge();
edge.edgeType = EdgeType.Circle;
edge.center = circle.center.clone();
edge.radius = circle.radius;
edges.add(edge);
hatch.setLoops(edges);
// Outer boundary (rectangle)
const outerRect = new PolylineEnt();
outerRect.setPoints([[0, 0], [100, 0], [100, 80], [0, 80]]);
outerRect.isClosed = true;
outerRect.setDefaults();
// Inner boundary (circular hole)
const innerCircle = new CircleEnt([50, 40], 20);
innerCircle.setDefaults();
// Create Edges (outer boundary + inner boundary)
const allEdges = new Edges();
// Outer boundary
const outerEdge = new Edge();
outerEdge.edgeType = EdgeType.Polyline;
outerEdge.bulgePoints = outerRect.bulgePoints.clone();
allEdges.add(outerEdge);
// Inner boundary (hole)
const innerEdge = new Edge();
innerEdge.edgeType = EdgeType.Circle;
innerEdge.center = innerCircle.center.clone();
innerEdge.radius = innerCircle.radius;
allEdges.add(innerEdge);
// Set boundaries
hatch.setLoops(allEdges);
const { calculateHatchPatternScale } = vjcad;
// Calculate boundary size
const bbox = boundary.boundingBox();
const boundsSize = Math.max(bbox.maxX - bbox.minX, bbox.maxY - bbox.minY);
// Get pattern definition
const patternDef = Engine.patternManager.getPattern(patternName);
// Auto-calculate appropriate scale
const autoScale = calculateHatchPatternScale(boundsSize, patternName, patternDef);
hatch.patternScale = autoScale;
hatch.patternScale = 2; // Scale up 2x
hatch.patternScale = 0.5; // Scale down to half
*PatternName,PatternDescription
angle,xOrigin,yOrigin,deltaX,deltaY[,linetype definition...]
- angle: Line drawing direction (degrees), 0=horizontal right, 90=vertical up
- xOrigin/yOrigin: Starting point coordinates of the first line
- deltaX: Offset along the line direction
- deltaY: Offset perpendicular to the line direction (row spacing)
- linetype definition: Optional dash pattern (positive=solid, negative=gap, 0=dot)
// PAT format string
const patString = `*MY_PATTERN,My custom pattern
45,0,0,0,5
135,0,0,0,5`;
// Parse PAT format
function parsePatternString(patString) {
const lines = patString.trim().split('\n');
const headerMatch = lines[0].match(/^\*([^,]+),(.*)$/);
const name = headerMatch[1].trim();
const description = headerMatch[2].trim();
const patternLines = [];
for (let i = 1; i < lines.length; i++) {
const line = lines[i].trim();
if (!line || line.startsWith(';')) continue;
const parts = line.split(',').map(p => parseFloat(p.trim()));
patternLines.push({
angle: parts[0],
xOrigin: parts[1],
yOrigin: parts[2],
deltaX: parts[3],
deltaY: parts[4],
dashes: parts.slice(5)
});
}
return { name, description, lines: patternLines };
}
// Register pattern
const patternDef = parsePatternString(patString);
Engine.patternManager.registerPattern(patternDef, "custom");
const patternManager = Engine.patternManager;
// Get all pattern names
const allNames = patternManager.getAllPatternNames();
const categoryNames = patternManager.getAllPatternNames("builtin");
// Get pattern definition
const patternDef = patternManager.getPattern("ANSI31");
console.log(patternDef.name);
console.log(patternDef.description);
console.log(patternDef.lines); // Line definition array
// Check if pattern exists
const exists = patternManager.hasPattern("MY_PATTERN");
// Register custom pattern
patternManager.registerPattern(definition, "custom");
// Get categories
const categories = patternManager.getCategories();
// Get statistics
const stats = patternManager.getStatistics();
const {
HatchEnt, PolylineEnt, TextEnt,
Engine, Edge, Edges, EdgeType
} = vjcad;
const patternManager = Engine.patternManager;
const allPatternNames = patternManager.getAllPatternNames();
const COLS = 6;
const CELL_WIDTH = 80;
const CELL_HEIGHT = 60;
const PADDING = 10;
function createEdgesFromPolyline(polyline) {
const edges = new Edges();
const edge = new Edge();
edge.edgeType = EdgeType.Polyline;
edge.bulgePoints = polyline.bulgePoints.clone();
edges.add(edge);
return edges;
}
const allEntities = [];
allPatternNames.forEach((patternName, i) => {
const col = i % COLS;
const row = Math.floor(i / COLS);
const x = col * (CELL_WIDTH + PADDING);
const y = -row * (CELL_HEIGHT + PADDING + 20);
// Boundary
const boundary = new PolylineEnt();
boundary.addVertex([x, y]);
boundary.addVertex([x + CELL_WIDTH, y]);
boundary.addVertex([x + CELL_WIDTH, y + CELL_HEIGHT]);
boundary.addVertex([x, y + CELL_HEIGHT]);
boundary.isClosed = true;
boundary.setDefaults();
allEntities.push(boundary);
// Hatch
const hatch = new HatchEnt();
hatch.patternName = patternName;
hatch.patternScale = patternName === "SOLID" ? 1 : 5;
hatch.setLoops(createEdgesFromPolyline(boundary));
hatch.setDefaults();
hatch.color = patternName === "SOLID" ? 3 : 2;
allEntities.push(hatch);
// Label
const label = new TextEnt();
label.insertionPoint = [x, y - 8];
label.text = patternName;
label.height = 5;
label.setDefaults();
allEntities.push(label);
});
Engine.addEntities(allEntities);
Engine.zoomExtents();
// HATCH command: select boundary and fill
await Engine.editor.executerWithOp('HATCH');
// HATCHEDIT command: edit existing hatch
await Engine.editor.executerWithOp('HATCHEDIT');