Limit how far a block may extend past its page during user interactions. The constraints apply to mouse and touch gestures — moving, resizing, and scaling. API calls bypass them.
overshoot is a non-negative fraction of the block’s own size: 0 pins the block fully inside, 0.2 allows a 20% overshoot. Each rule’s scope decides which blocks it applies to:
.scene— scene-wide default..block(id)— a specific block (pages count as blocks)..blockType(name)— every block of the given type.
Scene-wide default#
Apply a rule that affects every page in the scene:
// Allow every block in the scene to overshoot by 20% of its own size.try engine.editor.setMovementConstraint(MovementConstraintRule(overshoot: 0.2))Per block type#
Scope a rule with .blockType to restrict all blocks of that type. Call setMovementConstraint with an array to apply several rules in one call:
// Pin all text and caption blocks fully inside the page.try engine.editor.setMovementConstraint([ MovementConstraintRule(overshoot: 0, scope: .blockType("text")), MovementConstraintRule(overshoot: 0, scope: .blockType("caption")),])Per page#
Pages are blocks, so you can target a page block to set a default for its children:
// Override the scene-wide default for blocks on this page.try engine.editor.setMovementConstraint( MovementConstraintRule(overshoot: 0.1, scope: .block(page)),)Per block#
Target a specific block ID to override every other level:
// Override every other level for one specific block.try engine.editor.setMovementConstraint( MovementConstraintRule(overshoot: 0, scope: .block(block)),)Read the active value#
Read the resolved constraint for a block. The lookup walks the priority chain: block, parent page, blockType, then scene-wide. It returns nil when the block is unconstrained.
// Read the resolved constraint, walking the priority chain:// block > parent page > blockType > scene-wide.let active = try engine.editor.getMovementConstraint(block)Remove a constraint#
Pass the matching MovementConstraintScope to clear any level of the priority chain, or call removeMovementConstraint() with no argument to clear the scene-wide default:
// Clear a scope by passing the matching descriptor. Use no argument to remove// the scene-wide default.try engine.editor.removeMovementConstraint(.block(block)) // per-blocktry engine.editor.removeMovementConstraint(.blockType("text")) // per-typetry engine.editor.removeMovementConstraint(.block(page)) // per-pagetry engine.editor.removeMovementConstraint() // scene-wide defaultFull code#
Here’s the full code:
import Foundationimport IMGLYEngine
@MainActorfunc movementConstraints(engine: Engine) async throws { let scene = try engine.scene.create()
let page = try engine.block.create(.page) try engine.block.setWidth(page, value: 800) try engine.block.setHeight(page, value: 600) try engine.block.appendChild(to: scene, child: page)
let block = try engine.block.create(.graphic) try engine.block.appendChild(to: page, child: block)
// Allow every block in the scene to overshoot by 20% of its own size. try engine.editor.setMovementConstraint(MovementConstraintRule(overshoot: 0.2))
// Pin all text and caption blocks fully inside the page. try engine.editor.setMovementConstraint([ MovementConstraintRule(overshoot: 0, scope: .blockType("text")), MovementConstraintRule(overshoot: 0, scope: .blockType("caption")), ])
// Override the scene-wide default for blocks on this page. try engine.editor.setMovementConstraint( MovementConstraintRule(overshoot: 0.1, scope: .block(page)), )
// Override every other level for one specific block. try engine.editor.setMovementConstraint( MovementConstraintRule(overshoot: 0, scope: .block(block)), )
// Read the resolved constraint, walking the priority chain: // block > parent page > blockType > scene-wide. let active = try engine.editor.getMovementConstraint(block)
// Clear a scope by passing the matching descriptor. Use no argument to remove // the scene-wide default. try engine.editor.removeMovementConstraint(.block(block)) // per-block try engine.editor.removeMovementConstraint(.blockType("text")) // per-type try engine.editor.removeMovementConstraint(.block(page)) // per-page try engine.editor.removeMovementConstraint() // scene-wide default
_ = active}