Skip to content

Placed views

Read and edit the layout of the views already placed on the Present canvas. A placed view is a saved view that has been dropped onto a layout sheet (or the open canvas) — the live linked view shape sheets.place and the Present views panel's drag-drop create. Accessed via snaptrude.presentation.placedViews.

These methods change where a placed view sits, how big it is, its architectural scale, its rotation, and its crop. To refresh a placed view's content from the current model, use sheets.updatePlacedView — content refresh lives on sheets, layout lives here.

All methods are host API calls that return Promises. list never throws when Present mode is closed (it returns []); get and every write require Present mode to be open.

At a glance

MethodWhat it doesMutates?
list(sheetId?)List the placed views (optionally only those on one sheet)
get(shapeId)Read one placed view by its shape id
move(shapeId, position, options?)Reposition a placed view, optionally moving it to another sheet
scale(shapeId, factor)Uniformly resize a placed view (2D and 3D)
setScale(shapeId, scale)Set a standard architectural scale (the Scale dropdown; 2D only)
setCrop(shapeId, crop)Crop a placed view to a window of itself, or clear the crop
setRotation(shapeId, rotation)Set a placed view's absolute rotation (radians; 3D views only)
getStyles(shapeId)Read the per-category presentation styles (resolved)
updateStyles(shapeId, category, patch)Restyle one category (line weights, dash styles, fills, …)
resetStyles(shapeId)Reset all styling to defaults (the sidebar Reset)
updateFontStyles(shapeId, category, patch)Label typography for one category (the Text tab)
listLabels(shapeId)List a view's labels (text, category, position, hidden)
moveLabel(labelId, position)Reposition one label (view-relative coordinates)
setLabelHidden(labelId, hidden)Hide/show one label individually
listShapes(sheetId?)List ALL top-level canvas shapes with an origin classification
getShape(shapeId)Read any canvas shape (AI outputs, diagram images, …)
moveShape(shapeId, position, options?)Move any canvas shape, optionally onto a sheet
resizeShape(shapeId, factor)Uniformly resize any canvas shape
rotateShape(shapeId, rotation)Set any canvas shape's absolute rotation (radians)
deleteShapes(shapeIds)Delete canvas shapes (atomic; annotations + sheets protected)
setOpacity(shapeId, opacity)Whole-shape opacity, 0–1 (the sidebar slider)
setMask(shapeId, enabled)Toggle "mask context buildings" on a view

Present mode required

get and every write throw "Present mode is not open" when Present mode (the documentation editor) is closed. list does not throw — it returns [], so a plugin cannot distinguish "Present mode is closed" from "nothing is placed".

Undo lives on the Present canvas

"Undoable" / "one undo step" here means the Present canvas's own history — the user's Ctrl+Z while Present mode is open. core.history.undo steps the design-side command stack and does not revert Present-canvas edits.

Types

PluginPlacedView

A view placed on the Present canvas. shapeId is the id sheets.place returned. For a grouped placed view (e.g. a sustainability 3D view grouped with its legend), position/size/rotation describe the whole group — the unit the user sees — while shapeId stays the view shape's id.

PropertyTypeDescription
shapeIdstringId of the placed view shape (the id sheets.place returns)
sheetIdstring | nullThe sheet it sits on (null when placed loose on the canvas)
titlestringThe saved view's title
viewIdstringId of the saved view it was placed from
position{ x: number, y: number }Top-left position — sheet-local when on a sheet, page coordinates otherwise
size{ width: number, height: number }Displayed size on the canvas
scalenumber | nullArchitectural scale (e.g. 100 = 1:100); null for 3D views
is3dbooleanWhether it is a 3D view (no architectural scale)
rotationnumberRotation in radians, [0, 2π) (nonzero only for 3D views — 2D views cannot rotate on their own; set with setRotation. Exception: a 2D view grouped with other shapes rotates with its group — the record's root resolves to the group, matching the interactive group rotate handle)
cropPluginPlacedViewCrop | nullCrop window (null when uncropped)
isUnlinkedbooleanWhether the source proposal was removed (an unlinked view no longer refreshes)

PluginPlacedViewCrop

A crop window, as fractions (0–1) of the uncropped view. topLeft must be strictly less than bottomRight on both axes.

PropertyTypeDescription
topLeft{ x: number, y: number }Top-left of the visible window (fractions 0–1)
bottomRight{ x: number, y: number }Bottom-right of the visible window (fractions 0–1)

Functions

list(sheetId?)

List the placed views in the presentation — those nested on a layout sheet (with that sheet's id) and those sitting loose on the canvas (sheetId: null). Pass sheetId to list only the views placed on that sheet.

  • Parameters:
    • sheetId: string | undefined — optional sheet id to filter by
  • Returns: { placedViews: PluginPlacedView[] } — empty when Present mode is closed or nothing is placed.
  • Throws: If sheetId is given but is not a sheet (with Present mode open).
ts
const { placedViews } = await snaptrude.presentation.placedViews.list("sheet_1");
for (const p of placedViews) console.log(p.title, p.position, p.scale);

get(shapeId)

Read a single placed view by its shape id — the id sheets.place returned (also reported by list).

  • Parameters:
    • shapeId: string — the placed view shape to read
  • Returns: PluginPlacedView.
  • Throws: If Present mode is not open, or shapeId is unknown or is not a placed view.
ts
const placed = await snaptrude.presentation.placedViews.get(shapeId);
console.log(placed.sheetId, placed.size, placed.crop);

move(shapeId, position, options?)

Reposition a placed view. position is the new top-left in sheet coordinates (page coordinates when the view is off-sheet). Pass options.sheetId to move the view onto another sheet — it is reparented to that sheet first, then positioned at position in the new sheet's coordinates. A grouped placed view moves as one unit. Undoable.

  • Parameters:
    • shapeId: string — the placed view shape to move
    • position: { x: number, y: number } — new top-left position (sheet-local; page coordinates when off-sheet)
    • options.sheetId: string | undefined — move the view onto this sheet
  • Returns: PluginPlacedView — the updated placed view.
  • Throws: If Present mode is not open, shapeId is unknown or is not a placed view, or options.sheetId is given but is not a sheet.
ts
await snaptrude.presentation.placedViews.move(shapeId, { x: 50, y: 50 }, { sheetId: "sheet_2" });

scale(shapeId, factor)

Uniformly resize a placed view about its top-left corner — the same resize as dragging a corner handle, aspect ratio held. Works for 2D and 3D views; labels and grouped legends resize with it. For a 2D view the printed architectural scale changes proportionally — doubling the size of a 1:100 plan makes it a 1:50 plan. Use setScale to land on an exact standard scale instead. Undoable.

  • Parameters:
    • shapeId: string — the placed view shape to resize
    • factor: number — uniform scale factor, between 0.01 and 100 (2 doubles the size, 0.5 halves it)
  • Returns: PluginPlacedView — the updated placed view.
  • Throws: If Present mode is not open, shapeId is unknown or is not a placed view, or factor is not a finite number between 0.01 and 100.
ts
const scaled = await snaptrude.presentation.placedViews.scale(shapeId, 2);
console.log(scaled.size, scaled.scale); // twice the size; a 2D view's scale halved

setScale(shapeId, scale)

Set a placed view's architectural scale — the same write the placed view's Scale dropdown performs. The view (and its labels) is resized about its top-left corner so it prints at the given scale. scale must be one of the standard values for the project's unit system — the same table as sheets.place (metric 10, 20, 50, 100, 150, 200, 250, 500, 1000; imperial e.g. 48 = 1/4″ = 1′). 3D views have no architectural scale — calling this on one throws. Undoable.

  • Parameters:
    • shapeId: string — the placed view shape to set the scale of
    • scale: number — a standard scale value for the project's unit system
  • Returns: PluginPlacedView — the updated placed view.
  • Throws: If Present mode is not open, shapeId is unknown or is not a placed view, scale is not a standard value for the project's unit system, or the placed view is a 3D view.
ts
await snaptrude.presentation.placedViews.setScale(shapeId, 100); // 1:100

setCrop(shapeId, crop)

Crop a placed view, or clear its crop. crop selects the visible window as fractions (0–1) of the uncropped viewtopLeft strictly less than bottomRight on both axes. The visible region stays anchored on the page (the same behavior as the interactive crop), labels that fall outside the crop are hidden, and the view's architectural scale is untouched. Pass null to clear the crop and restore the full view in its uncropped footprint (the interactive double-click-edge reset). Undoable.

The crop survives a content refresh: sheets.updatePlacedView recomputes the crop against the refreshed content and only clears it when the refreshed view no longer overlaps the cropped region.

  • Parameters:
    • shapeId: string — the placed view shape to crop
    • crop: PluginPlacedViewCrop | null — the crop window, or null to clear
  • Returns: PluginPlacedView — the updated placed view.
  • Throws: If Present mode is not open, shapeId is unknown or is not a placed view, or crop is not a valid 0–1 rectangle with topLeft < bottomRight on both axes.
ts
// keep the left half of the view
await snaptrude.presentation.placedViews.setCrop(shapeId, {
  topLeft: { x: 0, y: 0 },
  bottomRight: { x: 0.5, y: 1 }
});
await snaptrude.presentation.placedViews.setCrop(shapeId, null); // clear

setRotation(shapeId, rotation)

Set a placed view's absolute rotation — radians, tldraw convention, the same value rotation reads back: setRotation(x) then get returns exactly x (values are canonicalized into [0, 2π), so pass values in that range for an exact round-trip). The view rotates about its page-space bounds center — the same pivot the interactive rotation handle uses — so the center stays put. A grouped placed view rotates as one unit. One undo step.

3D placed views only. 2D and site-plan views cannot rotate on their own — the canvas hides their rotate handle and reverts any rotation applied to them — so calling this on one throws instead of silently no-opping. One exception: a 2D view grouped with other shapes rotates with its group (the rotation targets the outermost non-frame root, which resolves to the group — the same unit the interactive group rotate handle turns), so setRotation on a grouped 2D view rotates the whole group.

  • Parameters:
    • shapeId: string — the placed view shape to rotate
    • rotation: number — the absolute rotation in radians (a finite number; 0 is unrotated)
  • Returns: PluginPlacedView — the updated placed view.
  • Throws: If Present mode is not open, shapeId is unknown or is not a placed view, rotation is not finite, or the placed view is a 2D/site-plan view.
ts
const rotated = await snaptrude.presentation.placedViews.setRotation(shapeId, Math.PI / 4);
console.log(rotated.rotation); // 0.7853981633974483 — exactly what was set
await snaptrude.presentation.placedViews.setRotation(shapeId, 0); // back upright

getStyles(shapeId) / updateStyles(shapeId, category, patch) / resetStyles(shapeId)

The Present sidebar's per-category styling, per placed instance (the same saved view placed twice can be styled differently). Works on placed views and auto-diagram sheets (sheet writes fan out across the sheet's diagram set).

Ten categories: Site, Topography, Space, Department, Envelope, Facade/Mass, Dimension, Reference Line, Adjacency Line, Landscape elements. A patch may set any subset the category supports: lineStyle (solid/dashed/dashdot/hidden/center/phantom/propertyLine), lineColor (hex), dashLength (multiplier), line weights in mmcutWidth + projectionWidth (Revit-style cut/projection split; lineWidth where a category has one weight; treeLineWidth/parkingLineWidth on Landscape) — colorMode (department/texture/monochrome/tag:<tagCategoryId>), opacity (0–100), hide (cascades to that category's labels), viewStyle (NONE/FILLET/BUBBLE) with radius/inset, and Topography's mapOpacity/buildingOpacity/mapHide/buildingHide/noBuilding.

getStyles returns fully-resolved values plus each category's supported setting ids and a disabled flag (category not visible in the view). updateStyles validates everything up front (typed VALIDATION with the supported list — nothing is written on a bad patch), lands as one undo step per call, and re-renders immediately. resetStyles is the sidebar Reset: clears all overrides, view styles, font styles, and styling-hidden labels.

ts
await snaptrude.presentation.placedViews.updateStyles(shapeId, "Space", {
  cutWidth: 0.5,
  projectionWidth: 0.18,
  lineStyle: "dashed",
  colorMode: "department"
});

updateFontStyles(shapeId, category, patch)

The configure panel's Text tab: label typography per label type — objectLabels (the name), department, areas — each with fontFamily (system or any Google Font, loaded automatically), fontWeight (numeric string, e.g. "700"), fontStyle (normal/italic), fontSize (px number). visibleTypes controls which label types render ([] hides all). Topography, Facade/Mass, Reference Line and Adjacency Line have no Text tab and reject font writes.

listLabels(shapeId) / moveLabel(labelId, position) / setLabelHidden(labelId, hidden)

A placed view's labels (space names, departments, areas, dimension texts) as addressable shapes: { labelId, category, text, position, scale, hidden } with positions relative to the view. moveLabel repositions one (undoable, survives style changes); setLabelHidden hides/shows one individually — independent of the category-level hide and the Text-tab visibleTypes.

listShapes(sheetId?) / getShape(shapeId)

The generic canvas surface: every top-level Present shape, not just placed views — { shapeId, type, origin, sheetId, position, size, rotation, opacity } with originview / aiOutput / pluginShape / annotation / image / other. This is how a plugin acts on the shape ids aiInspiration.generate and diagrams.place return. listShapes returns [] when Present mode is closed.

moveShape(shapeId, position, options?) / resizeShape(shapeId, factor) / rotateShape(shapeId, rotation)

move/scale/setRotation counterparts that accept ANY canvas shape (AI outputs, diagram images, plugin shapes, annotations — views too). Same coordinate semantics as move; options.sheetId reparents onto a sheet. rotateShape sets the absolute rotation in radians about the shape's page-space bounds center (the same semantics as setRotation, exact round-trip via getShape); a view passed to it falls under the same 3D-only rule as setRotation. All undoable (one undo step each).

deleteShapes(shapeIds)

Delete canvas shapes — one undo step, atomic (any rejected id deletes nothing). Deletable: placed views, AI outputs, diagram/plain images, plugin shapes. Protected: sheets (use sheets.delete) and user-drawn annotations (typed VALIDATION). → { deleted: string[] }.

setOpacity(shapeId, opacity) / setMask(shapeId, enabled)

setOpacity is the sidebar's whole-shape opacity slider (01, any canvas shape) — distinct from the per-category fill opacity in updateStyles. setMask toggles "mask context buildings" on a placed view (views only).

Errors

Failed calls reject with a typed PluginError — see Error Handling. Conditions specific to this namespace:

CodeThrown byWhendetails
PRECONDITION_FAILEDget and every writePresent mode is not open
HANDLE_INVALIDevery methodshapeId is unknown or is not a placed view, or a given sheetId is not a sheetkind
PRECONDITION_FAILEDsetScaleThe placed view is a 3D view (3D views have no architectural scale)handles — the shape id
PRECONDITION_FAILEDsetRotation, rotateShapeThe target is a 2D/site-plan placed view (only 3D placed views rotate)handles — the shape id
VALIDATIONsetScalescale is not one of the standard scale values for the project's unit systemscale, unitSystem, standardScales
VALIDATIONscale, setCropfactor out of range, or crop is not a valid 0–1 rectangle
VALIDATIONsetRotation, rotateShaperotation is not a finite number
HANDLE_INVALIDstyling methodsshapeId is not a placed view or auto-diagram sheet (styleableShape)kind
VALIDATIONupdateStylesCategory not applicable, setting unsupported by the category, or bad valuecategory, setting, supported
VALIDATIONupdateFontStylesThe category has no Text tabcategory
HANDLE_INVALIDlabel methodslabelId is not a view label (viewLabel)kind
HANDLE_INVALIDcanvas-shape methodsshapeId is unknown or a sheet (canvasShape)kind
VALIDATIONdeleteShapesAny id is a protected user annotation — the whole batch is refusedshapeId, type, origin

list and listShapes never throw when Present mode is closed — they return [].