Skip to content

Blocks

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 or page
  • Graphic: //ly.img.ubq/graphic or graphic
  • Text: //ly.img.ubq/text or text
  • Audio: //ly.img.ubq/audio or audio
  • Cutout: //ly.img.ubq/cutout or cutout

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 blocks
const 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 type
const blockType = engine.block.getType(block);
// Alter a blocks name
engine.block.setName(block, 'someName');
const name = engine.block.getName(block);
const uuid = engine.block.getUUID(block);\
// You may duplicate or destroy blocks
const 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 Properties
engine.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,
}); // White
engine.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' });