Control how much of a design is visible by driving the camera zoom from code.
Set an exact zoom level, frame a block, follow content as it resizes, constrain
the camera, and react to zoom changes through the Engine scene API.
The zoom level is a ratio between design dots and screen pixels. A zoom level of 1F shows one design dot as one screen pixel; 2F shows it as two. The snippets below operate on the active scene and a valid page block in that scene.
Get and Set the Zoom Level#
Set an absolute zoom level with engine.scene.setZoomLevel() and read the current value with engine.scene.getZoomLevel(). Reading first lets you apply a relative change, such as halving the current zoom.
engine.scene.setZoomLevel(level = 1F)val zoom100 = engine.scene.getZoomLevel()
engine.scene.setZoomLevel(level = zoom100 * 0.5F)val zoom50 = engine.scene.getZoomLevel()Zoom to a Block#
Frame a specific block - the scene, a page, or any element - with engine.scene.zoomToBlock(). Padding is measured in screen pixels and leaves space around the block. Use engine.scene.immediateZoomToBlock() when the layout is already up to date and you need the camera to move synchronously.
engine.scene.zoomToBlock( block = page, paddingLeft = 20F, paddingTop = 20F, paddingRight = 20F, paddingBottom = 20F,)
engine.scene.immediateZoomToBlock( block = page, paddingLeft = 20F, paddingTop = 20F, paddingRight = 20F, paddingBottom = 20F, forceUpdate = true,)Auto-Fit Zoom#
Auto-fit continuously refits a block as its bounding box changes. Choose the axis with ZoomAutoFitAxis.BOTH, ZoomAutoFitAxis.HORIZONTAL, or ZoomAutoFitAxis.VERTICAL. Auto-fit only has a visible effect while the zoom is not controlled by an editor UI layer, and calling setZoomLevel() or zoomToBlock() disables it.
engine.scene.enableZoomAutoFit( block = page, axis = ZoomAutoFitAxis.BOTH, paddingLeft = 20F, paddingTop = 20F, paddingRight = 20F, paddingBottom = 20F,)val autoFitEnabled = engine.scene.isZoomAutoFitEnabled(page)Disable Auto-Fit#
Stop following a block with engine.scene.disableZoomAutoFit(), and check whether auto-fit is still active with engine.scene.isZoomAutoFitEnabled().
engine.scene.disableZoomAutoFit(page)val autoFitDisabled = engine.scene.isZoomAutoFitEnabled(page).not()Limit the Zoom Range#
Use engine.scene.enableCameraZoomClamping() to keep the camera zoom within a range relative to one or more blocks. Negative limits mean unbounded. The camera-clamping APIs are annotated with @UnstableEngineApi, so opt in at the calling scope.
@OptIn(UnstableEngineApi::class)fun configureZoomClamping( engine: Engine, page: DesignBlock,): Boolean { engine.scene.enableCameraZoomClamping( blocks = listOf(page), minZoomLimit = 0.125F, maxZoomLimit = 8F, ) val zoomClampingEnabled = engine.scene.isCameraZoomClampingEnabled(page) return zoomClampingEnabled}Constrain the Camera Position#
Use engine.scene.enableCameraPositionClamping() to keep panning within the bounds of the supplied blocks. Padding defines how far the camera can move past those bounds; scaled padding grows with the zoom level until it reaches five times the initial value.
@OptIn(UnstableEngineApi::class)fun configurePositionClamping( engine: Engine, scene: DesignBlock,): Boolean { engine.scene.enableCameraPositionClamping( blocks = listOf(scene), paddingLeft = 10F, paddingTop = 10F, paddingRight = 10F, paddingBottom = 10F, scaledPaddingLeft = 0F, scaledPaddingTop = 0F, scaledPaddingRight = 0F, scaledPaddingBottom = 0F, ) val positionClampingEnabled = engine.scene.isCameraPositionClampingEnabled(scene) return positionClampingEnabled}Subscribe to Zoom Changes#
engine.scene.onZoomLevelChanged() returns a Flow<Unit> that emits whenever the zoom changes. Collect it from your UI scope to keep custom controls in sync, and cancel the returned job when the control leaves the screen.
fun observeZoomLevel( engine: Engine, zoomControlScope: CoroutineScope, onZoomChanged: (Float) -> Unit,): Job = engine.scene.onZoomLevelChanged() .onEach { onZoomChanged(engine.scene.getZoomLevel()) } .launchIn(zoomControlScope)API Reference#
| Method | Description |
|---|---|
engine.scene.setZoomLevel(level=_) |
Set the active scene’s zoom level. |
engine.scene.getZoomLevel() |
Read the active scene’s current zoom level. |
engine.scene.zoomToBlock(block=_, paddingLeft=_, paddingTop=_, paddingRight=_, paddingBottom=_) |
Asynchronously frame a block after its dimensions are known, with optional per-side padding. |
engine.scene.immediateZoomToBlock(block=_, paddingLeft=_, paddingTop=_, paddingRight=_, paddingBottom=_, forceUpdate=_) |
Frame a block synchronously; pass forceUpdate=true to run a layout pass first. |
engine.scene.enableZoomAutoFit(block=_, axis=_, paddingLeft=_, paddingTop=_, paddingRight=_, paddingBottom=_) |
Continuously refit a block on the selected ZoomAutoFitAxis. |
engine.scene.disableZoomAutoFit(block=_) |
Stop a previously enabled auto-fit. |
engine.scene.isZoomAutoFitEnabled(block=_) |
Query whether auto-fit is enabled for a block or scene. |
engine.scene.enableCameraZoomClamping(blocks=_, minZoomLimit=_, maxZoomLimit=_, paddingLeft=_, paddingTop=_, paddingRight=_, paddingBottom=_) |
Constrain the zoom range relative to the supplied blocks. Experimental. |
engine.scene.disableCameraZoomClamping() |
Remove zoom clamping. Experimental. |
engine.scene.isCameraZoomClampingEnabled(blockOrScene=_) |
Query whether zoom clamping is enabled. Experimental. |
engine.scene.enableCameraPositionClamping(blocks=_, paddingLeft=_, paddingTop=_, paddingRight=_, paddingBottom=_, scaledPaddingLeft=_, scaledPaddingTop=_, scaledPaddingRight=_, scaledPaddingBottom=_) |
Keep the camera position inside the supplied block bounds. Experimental. |
engine.scene.disableCameraPositionClamping() |
Remove position clamping. Experimental. |
engine.scene.isCameraPositionClampingEnabled(blockOrScene=_) |
Query whether position clamping is enabled. Experimental. |
engine.scene.onZoomLevelChanged() |
Subscribe to zoom-level change events as a Kotlin Flow. |
Troubleshooting#
| Problem | Resolution |
|---|---|
| Zoom level does not change | Confirm a scene exists before calling zoom methods, and that no editor UI layer is overriding the zoom. |
| Auto-fit has no effect | Only one block per scene can drive auto-fit, and setZoomLevel() or zoomToBlock() disables it. Pass a valid block that belongs to the active scene. |
| Zoom feels capped | An active zoom clamp limits the range. Check with isCameraZoomClampingEnabled() and adjust or remove it. |
Next Steps#
- Start With Blank Canvas - Start the editor with an empty scene to zoom into.
- Load a Scene - Open an existing design before adjusting the camera.