Search
Loading...
Skip to content

Force Crop

The applyForceCrop API allows you to programmatically apply a crop preset to a specific design block, typically a page. This is useful in scenarios where you want to enforce a particular format (e.g., fixed aspect ratio) and define how the editor should respond after the preset is applied.


Overview#

You can use applyForceCrop to apply predefined crop presets to a block that supports cropping, such as a page. The API automatically selects the best matching preset from the candidates you provide based on the block’s current dimensions. You can provide multiple preset candidates, and the system will intelligently choose the most appropriate one.

The API provides flexible behavior through the mode parameter, controlling whether the crop UI is shown and whether cropping is conditionally applied based on the block’s current dimensions.

This API is available as an event context.eventHandler.send(.applyForceCrop(...)) within the .imgly.onLoaded callback.

context.eventHandler.send(.applyForceCrop(
to blockID: DesignBlockID,
with presetCandidates: [ForceCropPreset],
mode: ForceCropMode
))

Parameters#

NameTypeDescription
blockIDDesignBlockIDThe ID of the block you want to apply the crop to. Must support cropping.
presetCandidates[ForceCropPreset]Array of crop preset candidates. The best matching preset will be automatically selected.
modeForceCropModeDefines how the UI should behave after applying the crop. See below.

ForceCropPreset#

Each preset candidate requires:

PropertyTypeDescription
sourceIDStringID of the asset source where the crop preset exists
presetIDStringID of the crop preset within that source

Modes#

ModeBehavior
.silentApplies the preset without opening the crop UI.
.alwaysApplies the preset and always switches to crop mode in the UI.
.ifNeededOnly applies the preset if the block’s current dimensions or aspect ratio differ from the preset. Switches to crop mode only if a change is made.

Usage Example#

The example shows how to apply a custom crop preset when the editor loads.

Creating the Preset#

// Create a custom 1:1 aspect ratio preset
let preset = AssetDefinition(
id: "custom-preset-1-1",
payload: .init(
transformPreset: .fixedAspectRatio(width: 1, height: 1),
),
label: ["en": "Square"],
)

First, define a custom AssetDefinition with the desired aspect ratio.

Setting Up the Source#

// Isolate the forced preset in the source
let sourceID = Engine.DefaultAssetSource.pagePresets.rawValue
try context.engine.asset.removeSource(sourceID: sourceID)
try context.engine.asset.addLocalSource(sourceID: sourceID)
try context.engine.asset.addAsset(to: sourceID, asset: preset)

If you’re using a demo source that contains existing presets, remove it first to start with a clean slate. Otherwise, you can add crop presets directly to your own source.

Applying Force Crop#

// Apply force crop
context.eventHandler.send(.applyForceCrop(
to: page,
with: [ForceCropPreset(sourceID: sourceID, presetID: preset.id)],
mode: .always,
))

Use the .applyForceCrop event with .always mode to apply the preset and open the crop UI.


Working with Asset Sources#

You can add multiple crop presets to an asset source. The force crop API works with any valid preset in the specified source.

Using a Demo Source#

If you’re working with a demo source that already contains presets, you may want to remove it first to avoid unwanted presets appearing in the crop options UI:

let sourceID = "ly.img.page.presets"
try context.engine.asset.removeSource(sourceID: sourceID)
try context.engine.asset.addLocalSource(sourceID: sourceID)
try context.engine.asset.addAsset(to: sourceID, asset: yourPreset)

Using Your Own Source#

If you’re using your own custom source, you can add crop presets directly without removing anything:

let sourceID = "my.custom.source"
try context.engine.asset.addLocalSource(sourceID: sourceID)
try context.engine.asset.addAsset(to: sourceID, asset: firstPreset)
try context.engine.asset.addAsset(to: sourceID, asset: secondPreset)
// Add as many presets as needed

This allows you to provide multiple crop options while still using force crop to programmatically apply specific presets.


Best Match Selection#

When you provide multiple preset candidates, the system automatically selects the best match based on how closely each preset matches the block’s current dimensions:

  • For fixed aspect ratio presets: Calculates the difference between the block’s aspect ratio and the preset’s aspect ratio
  • For fixed size presets: Calculates the total dimensional difference after harmonizing units
  • For free aspect ratio presets: These receive the lowest priority

The preset with the smallest difference (best fit) is automatically selected and applied.


Behavior Details#

  • applyForceCrop bypasses the usual user interaction required to apply crop presets manually.
  • When multiple preset candidates are provided, the best matching preset is automatically selected based on the block’s current dimensions.
  • When used in .always or .ifNeeded mode, the crop UI is automatically opened (if appropriate).
  • Invalid presetID or sourceID values in the candidates are silently skipped. At least one valid preset must be found.
  • The block must be valid and support cropping, otherwise an error is thrown.

See Also#