Overview
Layouts provide composition tools for organizing your architectural drawings into professional presentation formats. They manage paper frames, borders, title blocks, and drawing organization.
Layouts are essential for creating technical drawings, construction documents, and presentation sheets that follow architectural standards.
Paper Frames
Paper frames represent the physical drawing sheet with configurable formats, orientations, and margins.
Source: src/layouts/paper-frame.ts:30
Creating Paper Frames
const paperFrame = openPlans . paperFrame ({
labelName: 'Floor Plan - Ground Level' ,
type: 'PAPERFRAME' ,
format: 'A3' ,
orientation: 'landscape' ,
margin: 10 ,
backgroundColor: 0xFFFFFF ,
borderColor: 0x000000 ,
borderWidth: 1
});
Properties
Name or title of the drawing sheet
Paper size format: ‘A4’, ‘A3’, ‘A2’, or ‘Custom’
Sheet orientation: ‘portrait’ or ‘landscape’
Margin size in units (default: 10)
Background color in hexadecimal (default: 0xFFFFFF)
Border color in hexadecimal (default: 0x000000)
Width of the border line (default: 1)
OpenPlans supports standard ISO paper sizes:
Source: src/layouts/paper-frame.ts:10
const paperSizes = {
A4: { width: 21.0 , height: 29.7 }, // 210mm × 297mm
A3: { width: 29.7 , height: 42.0 }, // 297mm × 420mm
A2: { width: 42.0 , height: 59.4 }, // 420mm × 594mm
Custom: { width: 0 , height: 0 } // User-defined
};
const a4Portrait = openPlans . paperFrame ({
labelName: 'Detail Drawing' ,
format: 'A4' ,
orientation: 'portrait'
});
// Dimensions: 21.0 cm × 29.7 cm
const a3Landscape = openPlans . paperFrame ({
labelName: 'Floor Plan' ,
format: 'A3' ,
orientation: 'landscape'
});
// Dimensions: 42.0 cm × 29.7 cm (landscape)
const a2Portrait = openPlans . paperFrame ({
labelName: 'Site Plan' ,
format: 'A2' ,
orientation: 'portrait'
});
// Dimensions: 42.0 cm × 59.4 cm
const custom = openPlans . paperFrame ({
labelName: 'Custom Size' ,
format: 'Custom' ,
orientation: 'landscape'
});
// Set custom dimensions
custom . paperSize = { width: 35 , height: 50 };
Modifying Paper Frames
// Switch to different format
paperFrame . format = 'A2' ;
// Change orientation
paperFrame . orientation = 'landscape' ;
Source: src/layouts/paper-frame.ts:60
When you change the format, the paper frame:
Updates paperSize from the format table
Regenerates geometry via setOPGeometry()
Recreates borders and margins
Adjusting Margins
// Set margin size
paperFrame . margin = 15 ; // Larger margin
// Get current margin
const currentMargin = paperFrame . margin ;
Source: src/layouts/paper-frame.ts:73
Margins affect the inner border positioning:
const margin = this . propertySet . margin / 10 ;
const innerVertices = [
new Vector3 ( - width / 2 + margin , - height / 2 + margin , 0 ),
new Vector3 ( width / 2 - margin , - height / 2 + margin , 0 ),
new Vector3 ( width / 2 - margin , height / 2 - margin , 0 ),
new Vector3 ( - width / 2 + margin , height / 2 - margin , 0 )
];
Updating Colors
// Change border color
paperFrame . borderColor = 0x0000FF ;
// Change background
paperFrame . backgroundColor = 0xFFFFF0 ; // Ivory
Paper Frame Geometry
Paper frames consist of multiple geometric elements:
Outer Border
Source: src/layouts/paper-frame.ts:144
The main sheet outline:
const vertices = [
new Vector3 ( - width / 2 , - height / 2 , 0 ), // Bottom left
new Vector3 ( width / 2 , - height / 2 , 0 ), // Bottom right
new Vector3 ( width / 2 , height / 2 , 0 ), // Top right
new Vector3 ( - width / 2 , height / 2 , 0 ) // Top left
];
this . setConfig ({
vertices: vertices ,
color: backgroundColor
});
Inner Border
Source: src/layouts/paper-frame.ts:175
The drawing area border with margins:
private createInnerBorder () {
const innerVertices = [
// Horizontal lines
new Vector3 ( - width / 2 + margin , - height / 2 + margin , 0 ),
new Vector3 ( width / 2 - margin , - height / 2 + margin , 0 ),
new Vector3 ( width / 2 - margin , height / 2 - margin , 0 ),
new Vector3 ( - width / 2 + margin , height / 2 - margin , 0 ),
// Vertical lines
new Vector3 ( - width / 2 + margin , - height / 2 + margin , 0 ),
new Vector3 ( - width / 2 + margin , height / 2 - margin , 0 ),
new Vector3 ( width / 2 - margin , - height / 2 + margin , 0 ),
new Vector3 ( width / 2 - margin , height / 2 - margin , 0 )
];
const innerBorder = new THREE . LineSegments ( geometry , material );
this . subElements . set ( 'InnerBorder' , innerBorder );
}
Positioning and Rotation
Paper frames are positioned in 3D space:
Source: src/layouts/paper-frame.ts:156
// Rotate to face camera (horizontal)
this . rotation . x = - Math . PI / 2 ;
// Position below ground level
this . position . y = - 0.01 ;
This ensures the paper frame:
Lies flat on the XZ plane
Doesn’t conflict with floor elements
Is visible from the top camera view
Outline Rendering
Source: src/layouts/paper-frame.ts:159
Paper frames use outline rendering:
This enables:
Clean border rendering
Professional line work
Compatibility with profile views
Sub-Elements Management
Paper frames maintain sub-elements:
subElements : Map < string , THREE . Object3D > = new Map ();
// Inner border is stored as sub-element
this . subElements . set ( 'InnerBorder' , innerBorderMesh );
// Access sub-elements
const innerBorder = paperFrame . subElements . get ( 'InnerBorder' );
Working with Layouts
Creating a Drawing Set
// Create multiple sheets
const groundFloor = openPlans . paperFrame ({
labelName: 'A-101 Ground Floor Plan' ,
format: 'A3' ,
orientation: 'landscape' ,
margin: 10
});
const firstFloor = openPlans . paperFrame ({
labelName: 'A-102 First Floor Plan' ,
format: 'A3' ,
orientation: 'landscape' ,
margin: 10
});
const sections = openPlans . paperFrame ({
labelName: 'A-201 Building Sections' ,
format: 'A2' ,
orientation: 'portrait' ,
margin: 15
});
Positioning Sheets
// Arrange sheets in space
groundFloor . position . set ( 0 , - 0.01 , 0 );
firstFloor . position . set ( 50 , - 0.01 , 0 );
sections . position . set ( 100 , - 0.01 , 0 );
Custom Paper Sizes
const customSheet = openPlans . paperFrame ({
labelName: 'Custom Detail Sheet' ,
format: 'Custom' ,
orientation: 'landscape'
});
// Set specific dimensions
customSheet . paperSize = {
width: 40 , // 40 cm wide
height: 30 // 30 cm tall
};
Custom paper sizes can only be set when format is ‘Custom’. Attempting to set paperSize on standard formats will throw an error.
Integration with Views
Paper frames work with OpenPlans’ 2D view system:
// Create a 2D view container
const container = document . getElementById ( 'drawing-view' );
const { camera , renderer } = openPlans . create2DView ( container , 0 );
// The paper frame will be visible in this view
const sheet = openPlans . paperFrame ({
labelName: 'Floor Plan' ,
format: 'A3' ,
orientation: 'landscape'
});
// Position camera to view the sheet
camera . position . set ( 0 , 20 , 0 );
camera . lookAt ( 0 , 0 , 0 );
Best Practices
Use consistent margins across your drawing set: const STANDARD_MARGIN = 10 ;
const sheet1 = openPlans . paperFrame ({
margin: STANDARD_MARGIN ,
format: 'A3'
});
const sheet2 = openPlans . paperFrame ({
margin: STANDARD_MARGIN ,
format: 'A3'
});
Use clear, professional naming conventions: // Good: Clear sheet identification
const sheet = openPlans . paperFrame ({
labelName: 'A-101 Ground Floor Plan' ,
// ...
});
// Avoid: Vague names
const sheet = openPlans . paperFrame ({
labelName: 'Sheet 1' ,
// ...
});
Advanced Usage
Dynamic Sheet Creation
interface SheetConfig {
number : string ;
title : string ;
format : PaperFormat ;
}
const sheets : SheetConfig [] = [
{ number: 'A-101' , title: 'Ground Floor Plan' , format: 'A3' },
{ number: 'A-102' , title: 'First Floor Plan' , format: 'A3' },
{ number: 'A-201' , title: 'Building Sections' , format: 'A2' },
{ number: 'A-301' , title: 'Details' , format: 'A4' }
];
sheets . forEach (( config , index ) => {
const sheet = openPlans . paperFrame ({
labelName: ` ${ config . number } ${ config . title } ` ,
format: config . format ,
orientation: config . format === 'A4' ? 'portrait' : 'landscape' ,
margin: 10
});
// Position sheets in a grid
const x = ( index % 3 ) * 60 ;
const z = Math . floor ( index / 3 ) * 80 ;
sheet . position . set ( x , - 0.01 , z );
});
Sheet Templates
class SheetTemplate {
static createFloorPlan ( title : string ) {
return openPlans . paperFrame ({
labelName: title ,
format: 'A3' ,
orientation: 'landscape' ,
margin: 10 ,
backgroundColor: 0xFFFFFF ,
borderColor: 0x000000
});
}
static createDetail ( title : string ) {
return openPlans . paperFrame ({
labelName: title ,
format: 'A4' ,
orientation: 'portrait' ,
margin: 8 ,
backgroundColor: 0xFFFFFF ,
borderColor: 0x000000
});
}
static createSitePlan ( title : string ) {
return openPlans . paperFrame ({
labelName: title ,
format: 'A2' ,
orientation: 'landscape' ,
margin: 15 ,
backgroundColor: 0xFFFFFF ,
borderColor: 0x000000
});
}
}
// Usage
const groundPlan = SheetTemplate . createFloorPlan ( 'A-101 Ground Floor' );
const windowDetail = SheetTemplate . createDetail ( 'D-101 Window Detail' );
const site = SheetTemplate . createSitePlan ( 'SP-001 Site Plan' );
Future Enhancements
The layout system includes commented code for future features:
Source: src/layouts/paper-frame.ts:217
Title blocks and info blocks
Logo placement
Row information blocks
Automatic block positioning
Layout templates
These features are planned for future releases and will provide:
Professional title blocks
Company logo integration
Drawing information tables
Automated sheet composition