Version v1.19 of CreativeEngineSDK and CreativeEditorSDK introduces structural changes to many of the current design blocks, making them more composable and more powerful. Along with this update, there are mandatory license changes that require attention. This comes with a number of breaking changes. This document will explain the changes and describe the steps you need to take to adapt them to your setup.
License Changes#
The license
parameter is now required for CreativeEngineSDK and CreativeEditorSDK. This means that you will need to update your license parameter in the CreativeEngine.init
and CreativeEditorSDK.create
configuration object properties. There is also a new userId
, an optional unique ID tied to your application's user. This helps us accurately calculate monthly active users (MAU). Especially useful when one person uses the app on multiple devices with a sign-in feature, ensuring they're counted once. Providing this aids in better data accuracy.
Graphic Design Block#
A new generic Graphic
design block with the type id //ly.img.ubq/graphic
has been introduced, which forms the basis of the new unified block structure.
Shapes#
Similar to how the fill of a block is a separate object which can be attached to and replaced on a design block, we have now introduced a similar concept for the shape of a block.
You use the new createShape
, getShape
and setShape
APIs in order to define the shape of a design block. Only the new //ly.img.ubq/graphic
block allows for its shape to be changed with these APIs.
The new available shape types are:
//ly.img.ubq/shape/rect
//ly.img.ubq/shape/line
//ly.img.ubq/shape/ellipse
//ly.img.ubq/shape/polygon
//ly.img.ubq/shape/star
//ly.img.ubq/shape/vector_path
The following block types are now removed in favor of using a Graphic
block with one of the above mentioned shape instances:
//ly.img.ubq/shapes/rect
//ly.img.ubq/shapes/line
//ly.img.ubq/shapes/ellipse
//ly.img.ubq/shapes/polygon
//ly.img.ubq/shapes/star
//ly.img.ubq/vector_path
(The removed type ids use the plural “shapes” and the new shape types use the singular “shape”)
This structural change means that the shape-specific properties (e.g. the number of sides of a polygon) are not available on the design block any more but on the shape instances instead. You will have to add calls to getShape
to get the instance id of the shape instance and then pass that to the property getter and setter APIs.
Also remember to change property key strings in the getter and setter calls from the plural shapes/…
to the singular shape/…
to match the new type identifiers.
Image and Sticker#
Previously, //ly.img.ubq/image
and //ly.img.ubq/sticker
were their own high-level design block types. They do not support the fill APIs nor the effects APIs.
Both of these blocks are now removed in favor of using a Graphic
block with an image fill (//ly.img.ubq/fill/image
) and using the effects APIs instead of the legacy image block’s numerous effects properties.
At its core, the sticker block has always just been an image block that is heavily limited in its capabilities. You can not crop it, nor apply any effects to it. In order to replicate this difference as closely as possible in the new unified structure, more fine-grained scopes have been added. You can now limit the adopter’s ability to crop a block and to edit its appearance.
Note that since these scopes only apply to a user of the editor with the “Adopter” role, a “Creator” user will now have all of the same editing options for both images and for blocks that used to be stickers.
Scopes#
The following is the list of changes to the design block scopes:
- (Breaking) The permission to crop a block was split from
content/replace
anddesign/style
into a separate scope:layer/crop
. - Deprecated the
design/arrange
scope and renameddesign/arrange/move
→layer/move
design/arrange/resize
→layer/resize
design/arrange/rotate
→layer/rotate
design/arrange/flip
→layer/flip
- Deprecated the
content/replace
scope. For//ly.img.ubq/text
blocks, it is replaced with the newtext/edit
scope. For other blocks it is replaced withfill/change
. - Deprecated the
design/style
scope and replaced it with the following fine-grained scopes:text/character
,stroke/change
,layer/opacity
,layer/blendMode
,layer/visibility
,layer/clipping
,appearance/adjustments
,appearance/filter
,appearance/effect
,appearance/blur
,appearance/shadow
- Introduced
fill/change
,stroke/change
, andshape/change
scopes that control whether the fill, stroke or shape of a block may be edited by a user with an "Adopter" role. - The deprecated scopes are automatically mapped to their new corresponding scopes by the scope APIs for now until they will be removed completely in a future update.
Kind#
While the new unified block structure both simplifies a lot of code and makes design blocks more powerful, it also means that many of the design blocks that used to have unique type ids now all have the same generic //ly.img.ubq/graphic
type, which means that calls to the findByType
cannot be used to filter blocks based on their legacy type ids any more.
Simultaneously, there are many instances in which different blocks in the scene which might have the same type and underlying technical structure have different semantic roles in the document and should therefore be treated differently by the user interface.
To solve both of these problems, we have introduced the concept of a block “kind”. This is a mutable string that can be used to tag different blocks with a semantic label.
You can get the kind of a block using the getKind
API and you can query blocks with a specific kind using the findByKind
API.
CreativeEngine provides the following default kind values:
image
video
sticker
scene
camera
stack
page
audio
text
shape
group
Unlike the immutable design block type id, you can change the kind of a block with the new setKind
API.
It is important to remember that the underlying structure and properties of a design block are not strictly defined by its kind, since the kind, shape, fill and effects of a block can be changed independent of each other. Therefore, a user-interface should not make assumptions about available properties of a block purely based on its kind.
Note
Due to legacy reasons, blocks with the kind "sticker" will continue to not allow their contents to be cropped. This special behavior will be addressed and replaced with a more general-purpose implementation in a future update.
Asset Definitions#
The asset definitions have been updated to reflect the deprecation of legacy block type ids and the introduction of the “kind” property.
In addition to the “blockType” meta property, you can now also define the “shapeType”
,“fillType”
and “kind”
of the block that should be created by the default implementation of the applyAsset function.
“blockType”
defaults to“//ly.img.ubq/graphic”
if left unspecified.“shapeType”
defaults to“//ly.img.ubq/shape/rect”
if left unspecified“fillType”
defaults to“//ly.img.ubq/fill/color”
if left unspecified
Video block asset definitions used to specify the “blockType”
as “//ly.img.ubq/fill/video“
. The “fillType”
meta asset property should now be used instead for such fill type ids.
Automatic Migration#
CreativeEngine will always continue to support scene files that contain the now removed legacy block types. Those design blocks will be automatically replaced by the equivalent new unified block structure when the scene is loaded, which means that the types of all legacy blocks will change to “//ly.img.ubq/graphic”
.
Note that this can mean that a block gains new capabilities that it did not have before. For example, the line shape block did not have any stroke properties, so the hasStroke
API used to return false
. However, after the automatic migration its Graphic
design block replacement supports both strokes and fills, so the hasStroke
API now returns true
. Similarly, the image block did not support fills or effects, but the Graphic
block does.
List of all Removed Block Type IDs#
//ly.img.ubq/image
//ly.img.ubq/sticker
//ly.img.ubq/shapes/rect
//ly.img.ubq/shapes/line
//ly.img.ubq/shapes/ellipse
//ly.img.ubq/shapes/polygon
//ly.img.ubq/shapes/star
//ly.img.ubq/vector_path
UI Configuration#
The configuration options for the legacy blocks have also been removed under config.ui.elements.blocks
and a new configuration option for the ly.img.ubq/graphic
block type have been introduced which will then define which UI controls to enable for graphic blocks (crop, filters, adjustments, effects, blur). This new configuration option follows the same structure as before.
Here is a list of the deprecated block configuration options:
//ly.img.ubq/image
//ly.img.ubq/fill/video
//ly.img.ubq/shapes/rect
//ly.img.ubq/shapes/line
//ly.img.ubq/shapes/star
//ly.img.ubq/shapes/polygon
//ly.img.ubq/shapes/ellipse
//ly.img.ubq/vector_path
Translations#
Some of the translation keys related to Scopes and Placeholder-Settings have been also updated:
- Removed the following keys:
scope.content.replace
scope.design.arrange
scope.design.style
- Renamed the following keys:
scope.design.arrange.flip
is nowscope.layer.flip
scope.design.arrange.move
is nowscope.layer.move
scope.design.arrange.resize
is nowscope.layer.resize
scope.design.arrange.rotate
is nowscope.layer.rotate
- Added the following keys:
component.placeholder.appearance.description
component.placeholder.appearance
component.placeholder.arrange.description
component.placeholder.arrange
component.placeholder.disableAll
component.placeholder.enableAll
component.placeholder.fill.description
component.placeholder.fill
component.placeholder.general.description
component.placeholder.general
component.placeholder.shape.description
component.placeholder.shape
component.placeholder.stroke.description
component.placeholder.stroke
component.placeholder.text.description
component.placeholder.text
scope.appearance.adjustments
scope.appearance.blur
scope.appearance.effect
scope.appearance.filter
scope.appearance.shadow
scope.fill.change
scope.layer.blendMode
scope.layer.opacity
scope.shape.change
scope.stroke.change
scope.text.character
scope.text.edit
Types and API Signatures#
To improve the type safety of our APIs, we have moved away from using the DesignBlockType
enum and replaced with a set of types. Those changes have affected the following APIs:
CESDK.engine.block.create()
CESDK.engine.block.createFill()
CESDK.engine.block.createEffect()
CESDK.engine.block.createBlur()
CESDK.engine.block.findByType()
CESDK.engine.block.getType()
Note
The create
, findByType
, and getType
APIs will no longer accept the IDs of
the deprecated legacy blocks and will throw an error when those are passed
Code Examples#
This section will show some code examples of the breaking changes and how it would look like after migrating.
/** Block Creation */// Creating an Image before migrationconst image = cesdk.engine.block.create('image');cesdk.engine.block.setString(image,'image/imageFileURI','https://domain.com/link-to-image.jpg');// Creating an Image after migrationconst block = cesdk.engine.block.create('graphic');const rectShape = cesdk.engine.block.createShape('rect');const imageFill = cesdk.engine.block.createFill('image');cesdk.engine.block.setString(imageFill,'fill/image/imageFileURI','https://domain.com/link-to-image.jpg');cesdk.engine.block.setShape(block, rectShape);cesdk.engine.block.setFill(block, imageFill);cesdk.engine.block.setKind(block, 'image');// Creating a star shape before migrationconst star = cesdk.engine.block.create('shapes/star');cesdk.engine.block.setInt(star, 'shapes/star/points', 8);// Creating a star shape after migrationconst block = cesdk.engine.block.create('graphic');const starShape = cesdk.engine.block.createShape('star');const colorFill = cesdk.engine.block.createFill('color');cesdk.engine.block.setInt(starShape, 'shape/star/points', 8);cesdk.engine.block.setShape(block, starShape);cesdk.engine.block.setFill(block, colorFill);cesdk.engine.block.setKind(block, 'shape');// Creating a sticker before migrationconst sticker = cesdk.engine.block.create('sticker');cesdk.engine.setString(sticker,'sticker/imageFileURI','https://domain.com/link-to-sticker.png');// Creating a sticker after migrationconst block = cesdk.engine.block.create('graphic');const rectShape = cesdk.engine.block.createShape('rect');const imageFill = cesdk.engine.block.createFill('image');cesdk.engine.block.setString(imageFill,'fill/image/imageFileURI','https://domain.com/link-to-sticker.png');cesdk.engine.block.setShape(block, rectShape);cesdk.engine.block.setFill(block, imageFill);cesdk.engine.block.setKind(block, 'sticker');/** Block Creation */
/** Block Exploration */// Query all images in the scene before migrationconst images = cesdk.engine.block.findByType('image');// Query all images in the scene after migrationconst images = cesdk.engine.block.findByType('graphic').filter((block) => {const fill = cesdk.engine.block.getFill(block);return (cesdk.engine.block.isValid(fill) &&cesdk.engine.block.getType(fill) === '//ly.img.ubq/fill/image');});// Query all stickers in the scene before migrationconst stickers = cesdk.engine.block.findByType('sticker');// Query all stickers in the scene after migrationconst stickers = cesdk.engine.block.findByKind('sticker');// Query all Polygon shapes in the scene before migrationconst polygons = cesdk.engine.block.findByType('shapes/polygon');// Query all Polygon shapes in the scene after migrationconst polygons = cesdk.engine.block.findByType('graphic').filter((block) => {const shape = cesdk.engine.block.getShape(block);return (cesdk.engine.block.isValid(shape) &&cesdk.engine.block.getType(shape) === '//ly.img.ubq/shape/polygon');});/** Block Exploration */