Blocks are the base building blocks for scenes and represent elements on the canvas. You’re able to create complex hierarchies of blocks by appending them as children to other blocks either directly or through groups.
By default, the following blocks are available:
- Page:
//ly.img.ubq/page
orpage
- Graphic:
//ly.img.ubq/graphic
orgraphic
- Text:
//ly.img.ubq/text
ortext
- Audio:
//ly.img.ubq/audio
oraudio
- Cutout:
//ly.img.ubq/cutout
orcutout
Lifecycle
Only blocks that are direct or indirect children of a page
block are rendered. Scenes without any page
child may not be properly displayed by the CE.SDK editor.
Functions
create(type: DesignBlockType): DesignBlockId
Create a new block, fails if type is unknown.
type
: The type of the block that shall be created.- Returns The created blocks handle.
To create a scene, use scene.create
instead.
saveToString(blocks: DesignBlockId[], allowedResourceSchemes?: string[]): Promise<string>
Saves the given blocks into a string. If given the root of a block hierarchy, e.g. a page with multiple children, the entire hierarchy is saved.
blocks
: The blocks to save- Returns A promise that resolves to a string representing the blocks or an error.
saveToArchive(blocks: DesignBlockId[]): Promise<Blob>
Saves the given blocks and all of their referenced assets into an archive. The archive contains all assets that were accessible when this function was called. Blocks in the archived scene reference assets relative from to the location of the scene file. These references are resolved when loading such a scene via loadSceneFromURL
.
blocks
: The blocks to save- Returns A promise that resolves with a Blob on success or an error on failure.
loadFromString(content: string): Promise<DesignBlockId[]>
Loads existing blocks from the given string. The blocks are not attached by default and won’t be visible until attached to a page or the scene. The UUID of the loaded blocks is replaced with a new one.
content
: A string representing the given blocks.- Returns A promise that resolves with a list of handles representing the found blocks or an error.
loadFromArchiveURL(url: string): Promise<DesignBlockId[]>
Loads existing blocks from the given URL. The blocks are not attached by default and won’t be visible until attached to a page or the scene. The UUID of the loaded blocks is replaced with a new one.
url
: The URL to load the blocks from.- Returns A promise that resolves with a list of handles representing the found blocks or an error.
getType(id: DesignBlockId): ObjectTypeLonghand
Get the type of the given block, fails if the block is invalid.
id
: The block to query.- Returns The blocks type.
setName(id: DesignBlockId, name: string): void
Update a block’s name.
id
: The block to update.name
: The name to set.
getName(id: DesignBlockId): string
Get a block’s name.
id
: The block to query.
getUUID(id: DesignBlockId): string
Get a block’s UUID.
id
: The block to query.
duplicate(id: DesignBlockId): DesignBlockId
Duplicates a block including its children. Required scope: ‘lifecycle/duplicate’ If the block is parented to a track that is set always-on-bottom, the duplicate is inserted in the same track immediately after the block. Otherwise, the duplicate is moved up in the hierarchy.
id
: The block to duplicate.- Returns The handle of the duplicate.
destroy(id: DesignBlockId): void
Destroys a block. Required scope: ‘lifecycle/destroy’
id
: The block to destroy.
isValid(id: DesignBlockId): boolean
Check if a block is valid. A block becomes invalid once it has been destroyed.
id
: The block to query.- Returns True, if the block is valid.
Full Code
In this example, we will show you how to use the CreativeEditor SDK’s CreativeEngine to modify scenes through the block
API.
// Create, save and load blocksconst block = engine.block.create('graphic');const savedBlocksString = await engine.block.saveToString([block]);const loadedBlocksString = await engine.block.loadFromString(savedBlocks);const savedBlocksArchive = await engine.block.saveToArchive([block]);const loadedBlocksArchive = await engine.block.loadFromArchiveURL('https://cdn.img.ly/assets/demo/v1/ly.img.template/templates/cesdk_postcard_1_blocks.zip');
// Check a blocks typeconst blockType = engine.block.getType(block);
// Alter a blocks nameengine.block.setName(block, 'someName');const name = engine.block.getName(block);const uuid = engine.block.getUUID(block);\
// You may duplicate or destroy blocksconst duplicate = engine.block.duplicate(block);engine.block.destroy(duplicate);engine.block.isValid(duplicate); // false
Properties
UUID
A universally unique identifier (UUID) is assigned to each block upon creation and can be queried. This is stable across save & load and may be used to reference blocks.
getUUID(id: DesignBlockId): string
Get a block’s UUID.
id
: The block to query.
Reflection
For every block, you can get a list of all its properties by calling findAllProperties(id: number): string[]
. Properties specific to a block are prefixed with the block’s type followed by a forward slash. There are also common properties shared between blocks which are prefixed by their respective type. A list of all properties can be found in the Blocks Overview.
findAllProperties(id: DesignBlockId): string[]
Get all available properties of a block.
id
: The block whose properties should be queried.- Returns A list of the property names.
Given a property, you can query its type as an enum using getPropertyType(property: string): 'Bool' | 'Int' | 'Float' | 'String' | 'Color' | 'Enum' | 'Struct'
.
getPropertyType(property: string): PropertyType
Get the type of a property given its name.
property
: The name of the property whose type should be queried.- Returns The property type.
The property type 'Enum'
is a special type. Properties of this type only accept a set of certain strings. To get a list of possible values for an enum property call getEnumValues(enumProperty: string): string[]
.
getEnumValues<T = string>(enumProperty: string): T[]
Get all the possible values of an enum given an enum property.
enumProperty
: The name of the property whose enum values should be queried.- Returns A list of the enum value names as string.
Some properties can only be written to or only be read.
To find out what is possible with a property, you can use the isPropertyReadable
and isPropertyWritable
methods.
isPropertyReadable(property: string): boolean
Check if a property with a given name is readable
property
: The name of the property whose type should be queried.- Returns Whether the property is readable or not. Will return false for unknown properties
isPropertyWritable(property: string): boolean
Check if a property with a given name is writable
property
: The name of the property whose type should be queried.- Returns Whether the property is writable or not. Will return false for unknown properties
Generic Properties
There are dedicated setter and getter functions for each property type. You have to provide a block and the property path. Use findAllProperties
to get a list of all the available properties a block has.
findAllProperties(id: DesignBlockId): string[]
Get all available properties of a block.
id
: The block whose properties should be queried.- Returns A list of the property names.
setBool(id: DesignBlockId, property: string, value: boolean): void
Set a bool property of the given design block to the given value.
id
: The block whose property should be set.property
: The name of the property to set.value
: The value to set.
getBool(id: DesignBlockId, property: string): boolean
Get the value of a bool property of the given design block.
id
: The block whose property should be queried.property
: The name of the property to query.- Returns The value of the property.
setInt(id: DesignBlockId, property: string, value: number): void
Set an int property of the given design block to the given value.
id
: The block whose property should be set.property
: The name of the property to set.value
: The value to set.
getInt(id: DesignBlockId, property: string): number
Get the value of an int property of the given design block.
id
: The block whose property should be queried.property
: The name of the property to query.- Returns The value of the property.
setFloat(id: DesignBlockId, property: string, value: number): void
Set a float property of the given design block to the given value.
id
: The block whose property should be set.property
: The name of the property to set.value
: The value to set.
getFloat(id: DesignBlockId, property: string): number
Get the value of a float property of the given design block.
id
: The block whose property should be queried.property
: The name of the property to query.- Returns The value of the property.
setDouble(id: DesignBlockId, property: string, value: number): void
Set a double property of the given design block to the given value.
id
: The block whose property should be set.property
: The name of the property to set.value
: The value to set.
getDouble(id: DesignBlockId, property: string): number
Get the value of a double property of the given design block.
id
: The block whose property should be queried.property
: The name of the property to query.- Returns The value of the property.
setString(id: DesignBlockId, property: string, value: string): void
Set a string property of the given design block to the given value.
id
: The block whose property should be set.property
: The name of the property to set.value
: The value to set.
getString(id: DesignBlockId, property: string): string
Get the value of a string property of the given design block.
id
: The block whose property should be queried.property
: The name of the property to query.- Returns The value of the property.
setColor(id: DesignBlockId, property: string, value: Color): void
Set a color property of the given design block to the given value.
id
: The block whose property should be set.property
: The name of the property to set.value
: The value to set.
getColor(id: DesignBlockId, property: string): Color
Get the value of a color property of the given design block.
id
: The block whose property should be queried.property
: The name of the property to query.- Returns The value of the property.
setEnum<T extends string = string>(id: DesignBlockId, property: string, value: T): void
Set an enum property of the given design block to the given value.
id
: The block whose property should be set.property
: The name of the property to set.value
: The enum value as string.
getEnum<T extends string = string>(id: DesignBlockId, property: string): T
Get the value of an enum property of the given design block.
id
: The block whose property should be queried.property
: The name of the property to query.- Returns The value as string.
type HorizontalTextAlignment = 'Left' | 'Right' | 'Center';
The horizontal text alignment options.
type VerticalTextAlignment = 'Top' | 'Bottom' | 'Center';
The vertical text alignment options.
setGradientColorStops(id: DesignBlockId, property: string, colors: GradientColorStop[]): void
Set a gradient color stops property of the given design block.
id
: The block whose property should be set.property
: The name of the property to set.
getGradientColorStops(id: DesignBlockId, property: string): GradientColorStop[]
Get the gradient color stops property of the given design block.
id
: The block whose property should be queried.property
: The name of the property to query.- Returns The gradient colors.
setSourceSet(id: DesignBlockId, property: string, sourceSet: Source[]): void
Set the property of the given block. The crop and content fill mode of the associated block will be set to the default values.
id
: The block whose property should be set.property
: The name of the property to set.sourceSet
: The block’s new source set.
getSourceSet(id: DesignBlockId, property: string): Source[]
Get the source set value of the given property.
id
: The block that should be queried.property
: The name of the property to query.- Returns The block’s source set.
addImageFileURIToSourceSet(id: DesignBlockId, property: string, uri: string): Promise<void>
Add a source to the sourceSet
property of the given block. If there already exists in source set an image with the same width, that existing image will be replaced. If the source set is or gets empty, the crop and content fill mode of the associated block will be set to the default values. Note: This fetches the resource from the given URI to obtain the image dimensions. It is recommended to use setSourceSet if the dimension is known.
id
: The block to update.property
: The name of the property to modify.uri
: The source to add to the source set.
addVideoFileURIToSourceSet(id: DesignBlockId, property: string, uri: string): Promise<void>
Add a video file URI to the sourceSet
property of the given block. If there already exists in source set an video with the same width, that existing video will be replaced. If the source set is or gets empty, the crop and content fill mode of the associated block will be set to the default values. Note: This fetches the resource from the given URI to obtain the video dimensions. It is recommended to use setSourceSet if the dimension is known.
id
: The block to update.property
: The name of the property to modify.uri
: The source to add to the source set.
Modifying Properties
Here’s the full code snippet for modifying a block’s properties:
const uuid = engine.block.getUUID(block);
const propertyNamesStar = engine.block.findAllProperties(starShape); // Array [ "shape/star/innerDiameter", "shape/star/points", "opacity/value", ... ]const propertyNamesImage = engine.block.findAllProperties(imageFill); // Array [ "fill/image/imageFileURI", "fill/image/previewFileURI", "fill/image/externalReference", ... ]const propertyNamesText = engine.block.findAllProperties(text); // Array [ "text/text", "text/fontFileUri", "text/externalReference", "text/fontSize", "text/horizontalAlignment", ... ]
const pointsType = engine.block.getPropertyType('shape/star/points'); // "Int"const alignmentType = engine.block.getPropertyType('text/horizontalAlignment'); // "Enum"engine.block.getEnumValues('text/horizontalAlignment');const readable = engine.block.isPropertyReadable('shape/star/points');const writable = engine.block.isPropertyWritable('shape/star/points');
// Generic Propertiesengine.block.setBool(scene, 'scene/aspectRatioLock', false);engine.block.getBool(scene, 'scene/aspectRatioLock');const points = engine.block.getInt(starShape, 'shape/star/points');engine.block.setInt(starShape, 'shape/star/points', points + 2);engine.block.setFloat(starShape, 'shape/star/innerDiameter', 0.75);engine.block.getFloat(starShape, 'shape/star/innerDiameter');const audio = engine.block.create('audio');engine.block.appendChild(scene, audio);engine.block.setDouble(audio, 'playback/duration', 1.0);engine.block.getDouble(audio, 'playback/duration');
engine.block.setString(text, 'text/text', '*o*');engine.block.setString( imageFill, 'fill/image/imageFileURI', 'https://img.ly/static/ubq_samples/sample_4.jpg',);engine.block.getString(text, 'text/text');engine.block.getString(imageFill, 'fill/image/imageFileURI');engine.block.setColor(colorFill, 'fill/color/value', { r: 1, g: 1, b: 1, a: 1,}); // Whiteengine.block.getColor(colorFill, 'fill/color/value');engine.block.setEnum(text, 'text/horizontalAlignment', 'Center');engine.block.setEnum(text, 'text/verticalAlignment', 'Center');engine.block.getEnum(text, 'text/horizontalAlignment');engine.block.getEnum(text, 'text/verticalAlignment');engine.block.setGradientColorStops(gradientFill, 'fill/gradient/colors', [ { color: { r: 1.0, g: 0.8, b: 0.2, a: 1.0 }, stop: 0 }, { color: { r: 0.3, g: 0.4, b: 0.7, a: 1.0 }, stop: 1 },]);engine.block.getGradientColorStops(gradientFill, 'fill/gradient/colors');
const imageFill = engine.block.createFill('image');engine.block.setSourceSet(imageFill, 'fill/image/sourceSet', [ { uri: 'http://img.ly/my-image.png', width: 800, height: 600, },]);const sourceSet = engine.block.getSourceSet(imageFill, 'fill/image/sourceSet');await engine.block.addImageFileURIToSourceSet( imageFill, 'fill/image/sourceSet', 'https://img.ly/static/ubq_samples/sample_1.jpg',);
const videoFill = engine.block.createFill('video');await engine.block.addVideoFileURIToSourceSet( videoFill, 'fill/video/sourceSet', 'https://img.ly/static/example-assets/sourceset/1x.mp4',);
Kind Property
The kind
of a design block is a custom string that can be assigned to a block in order to categorize it and distinguish it from other blocks that have the same type. The user interface can then customize its appearance based on the kind of the selected blocks. It can also be used for automation use cases in order to process blocks in a different way based on their kind.
setKind(id: DesignBlockId, kind: string): void
Set the kind of the given block, fails if the block is invalid.
id
: The block whose kind should be changed.kind
: The new kind.- Returns The block’s kind.
getKind(id: DesignBlockId): string
Get the kind of the given block, fails if the block is invalid.
id
: The block to query.- Returns The block’s kind.
findByKind(kind: string): DesignBlockId[]
Finds all blocks with the given kind.
kind
: The kind to search for.- Returns A list of block ids.
Full Code
In this example, we will show you how to use the CreativeEditor SDK’s CreativeEngine to modify a and query the kind property of design blocks through the block
API.
engine.block.setKind(text, 'title');const kind = engine.block.getKind(text);const allTitles = engine.block.findByKind('title');
Selection & Visibility
A block can potentially be invisible (in the sense that you can’t see it), even though
isVisible()
returns true. This could be the case when a block has not been
added to a parent, the parent itself is not visible, or the block is obscured by another block on top of it.
Select blocks and change their visibility
setSelected(id: DesignBlockId, selected: boolean): void
Update the selection state of a block. Fails for invalid blocks. Required scope: ‘editor/select’
id
: The block to query.selected
: Whether or not the block should be selected.
isSelected(id: DesignBlockId): boolean
Get the selected state of a block.
id
: The block to query.- Returns True if the block is selected, false otherwise.
select(id: DesignBlockId): void
Selects the given block and deselects all other blocks.
id
: The block to be selected.
findAllSelected(): DesignBlockId[]
Get all currently selected blocks.
- Returns An array of block ids.
onSelectionChanged: (callback: () => void) => (() => void)
Subscribe to changes in the current set of selected blocks.
callback
: This function is called at the end of the engine update if the selection has changed.- Returns A method to unsubscribe.
onClicked: (callback: (id: DesignBlockId) => void) => (() => void)
Subscribe to block click events.
callback
: This function is called at the end of the engine update if a block has been clicked.- Returns A method to unsubscribe.
setVisible(id: DesignBlockId, visible: boolean): void
Update a block’s visibility. Required scope: ‘layer/visibility’
id
: The block to update.visible
: Whether the block shall be visible.
isVisible(id: DesignBlockId): boolean
Query a block’s visibility.
id
: The block to query.- Returns True if visible, false otherwise.
setClipped(id: DesignBlockId, clipped: boolean): void
Update a block’s clipped state. Required scope: ‘layer/clipping’
id
: The block to update.clipped
: Whether the block should clips its contents to its frame.
isClipped(id: DesignBlockId): boolean
Query a block’s clipped state. If true, the block should clip its contents to its frame.
id
: The block to query.- Returns True if clipped, false otherwise.
isIncludedInExport(id: DesignBlockId): boolean
Query if the given block is included on the exported result.
id
: The block to query.- Returns true, if the block is included on the exported result, false otherwise
setIncludedInExport(id: DesignBlockId, enabled: boolean): void
Set if you want the given design block to be included in exported result.
id
: The block whose exportable state should be set.enabled
: If true, the block will be included on the exported result.
Full Code
In this example, we will show you how to use the CreativeEditor SDK’s CreativeEngine to modify scenes through the block
API.
engine.block.setSelected(block, true);const isSelected = engine.block.isSelected(block);engine.block.select(block);const selectedIds = engine.block.findAllSelected();const unsubscribeSelectionChanged = engine.block.onSelectionChanged(() => { const selectedIds = engine.block.findAllSelected(); console.log('Selection changed: ', selectedIds);});const unsubscribeOnClicked = engine.block.onClicked(block => { console.log('Block clicked: ', block);});const isVisible = engine.block.isVisible(block);engine.block.setVisible(block, true);
const isClipped = engine.block.isClipped(page);engine.block.setClipped(page, true);
const isIncludedInExport = engine.block.isIncludedInExport(block);engine.block.setIncludedInExport(block, true);
State
Blocks can perform operations that take some time or that can end in bad results. When that happens, blocks put themselves in a pending state or an error state and visual feedback is shown pertaining to the state. When an external operation is done to blocks, for example with a plugin, you may want to manually set the block’s state to pending (if that external operation takes time) or to error (if that operation resulted in an error).
The possible states of a block are:
BlockStateReady { type: 'Ready';};
BlockStatePending { type: 'Pending'; progress: number; // Expected range is [0, 1]}
BlockStateError { type: 'Error'; error: | 'AudioDecoding' // Failed to decode the block's audio stream. | 'ImageDecoding' // Failed to decode the block's image stream. | 'FileFetch' // Failed to retrieve the block's remote content. | 'Unknown' // An unknown error occurred. | 'VideoDecoding'; // Failed to decode the block's video stream.}
When calling getState
, the returned state reflects the combined state of a block, the block’s fill, the block’s shape and the block’s effects.
If any of these blocks is in an Error
state, the returned state will reflect that error.
If none of these blocks is in error state but any is in Pending
state, the returned state will reflect the aggregate progress of the block’s progress.
If none of the blocks are in error state or pending state, the returned state is Ready
.
getState(id: DesignBlockId): BlockState
Returns the block’s state. If this block is in error state or this block has a Shape
block, Fill
block or Effect
block(s), that is in error state, the returned state will be Error
. Else, if this block is in pending state or this block has a Shape
block, Fill
block or Effect
block(s), that is in pending state, the returned state will be Pending
. Else, the returned state will be Ready
.
id
: The block to query.- Returns The block’s state.
setState(id: DesignBlockId, state: BlockState): void
Set the state of a block.
id
: The block whose state should be set.state
: The new state to set.
onStateChanged: (ids: DesignBlockId[], callback: (ids: DesignBlockId[]) => void) => (() => void)
Subscribe to changes to the state of a block. Like getState
, the state of a block is determined by the state of itself and its Shape
, Fill
and Effect
block(s).
blocks
: A list of blocks to filter events by. If the list is empty, events for every block are sent.callback
: The event callback.- Returns Subscription A handle to the subscription. Use it to unsubscribe when done.
Full Code
In this example, we will show you how to use CreativeEditor SDK’s CreativeEngine to retrieve’s a block’s state and to manually set a block in a pending state, an error state or back to a ready state.
const subscription = engine.block.onStateChanged([], blocks => { blocks.forEach(block => console.log(block));});const state = engine.block.getState(block);engine.block.setState(block, { type: 'Pending', progress: 0.5 });engine.block.setState(block, { type: 'Ready' });engine.block.setState(block, { type: 'Error', error: 'ImageDecoding' });