Some design blocks in CE.SDK allow you to modify or replace their fill. The fill is an object that defines the contents within the shape of a block. CreativeEditor SDK supports many different types of fills, such as images, solid colors, gradients and videos.
Similarly to blocks, each fill has a numeric id which can be used to query and modify its properties.
We currently support the following fill types:
FillType.Color
FillType.LinearGradient
FillType.RadialGradient
FillType.ConicalGradient
FillType.Image
FillType.Video
FillType.PixelStream
Accessing Fills
Not all types of design blocks support fills, so you should always first call the fun supportsFill(block: DesignBlock): Boolean
API before accessing any of the following APIs.
engine.block.supportsFill(scene) // Returns falseengine.block.supportsFill(block) // Returns true
In order to receive the fill id of a design block, call the fun getFill(block: DesignBlock): DesignBlock
API. You can now pass this id into other APIs in order to query more information about the fill, e.g. its type via the fun getType(block: DesignBlock): String
API.
val colorFill = engine.block.getFill(block)val defaultRectFillType = engine.block.getType(colorFill)
Fill Properties
Just like design blocks, fills with different types have different properties that you can query and modify via the API. Use fun findAllProperties(block: DesignBlock): List<String>
in order to get a list of all properties of a given fill.
For the solid color fill in this example, the call would return ["fill/color/value", "type"]
.
Please refer to the design blocks for a complete list of all available properties for each type of fill.
val allFillProperties = engine.block.findAllProperties(colorFill)
Once we know the property keys of a fill, we can use the same APIs as for design blocks in order to modify those properties. For example, we can use fun setColor(block: DesignBlock, property: String, value: Color)
in order to change the color of the fill to red.
Once we do this, our graphic block with rect shape will be filled with solid red.
engine.block.setColor( block = colorFill, property = "fill/color/value", value = Color.fromRGBA(r = 1.0F, g = 0.0F, b = 0.0F, a = 1.0F),)
Disabling Fills
You can disable and enable a fill using the fun setFillEnabled(block: DesignBlock, enabled: Boolean)
API, for example in cases where the design block should only have a stroke but no fill. Notice that you have to pass the id of the design block and not of the fill to the API.
engine.block.setFillEnabled(block, enabled = false)engine.block.setFillEnabled(block, enabled = !engine.block.isFillEnabled(block))
Changing Fill Types
All design blocks that support fills allow you to also exchange their current fill for any other type of fill. In order to do this, you need to first create a new fill object using fun createFill(fillType: FillType): DesignBlock
.
val imageFill = engine.block.createFill(FillType.Image)engine.block.setString( block = imageFill, property = "fill/image/imageFileURI", value = "https://img.ly/static/ubq_samples/sample_1.jpg",)
In order to assign a fill to a design block, simply call fun setFill(block: DesignBlock, fill: DesignBlock)
. Make sure to delete the previous fill of the design block first if you don’t need it any more, otherwise we will have leaked it into the scene and won’t be able to access it any more, because we don’t know its id.
Notice that we don’t use the appendChild
API here, which only works with design blocks and not fills.
When a fill is attached to one design block, it will be automatically destroyed when the block itself gets destroyed.
engine.block.destroy(colorFill) engine.block.setFill(block, fill = imageFill)
/* // The following line would also destroy imageFill engine.block.destroy(circle) */
Duplicating Fills
If we duplicate a design block with a fill that is only attached to this block, the fill will automatically be duplicated as well. In order to modify the properties of the duplicate fill, we have to query its id from the duplicate block.
val duplicateBlock = engine.block.duplicate(block) engine.block.setPositionX(duplicateBlock, value = 450F) val autoDuplicateFill = engine.block.getFill(duplicateBlock) engine.block.setString( block = autoDuplicateFill, property = "fill/image/imageFileURI", value = "https://img.ly/static/ubq_samples/sample_2.jpg", )
/* // We could now assign this fill to another block. val manualDuplicateFill = engine.block.duplicate(autoDuplicateFill) engine.block.destroy(manualDuplicateFill) */
Sharing Fills
It is also possible to share a single fill instance between multiple design blocks. In that case, changing the properties of the fill will apply to all of the blocks that it’s attached to at once.
Destroying a block with a shared fill will not destroy the fill until there are no other design blocks left that still use that fill.
val sharedFillBlock = engine.block.create(DesignBlockType.Graphic)engine.block.setShape(sharedFillBlock, shape = engine.block.createShape(ShapeType.Rect))engine.block.setPositionX(sharedFillBlock, value = 350F)engine.block.setPositionY(sharedFillBlock, value = 400F)engine.block.setWidth(sharedFillBlock, value = 100F)engine.block.setHeight(sharedFillBlock, value = 100F)engine.block.appendChild(parent = page, child = sharedFillBlock)engine.block.setFill(sharedFillBlock, fill = engine.block.getFill(block))
Full Code
Here is the full code for working with fills:
import kotlinx.coroutines.*import ly.img.engine.*
fun usingFills( license: String, userId: String,) = CoroutineScope(Dispatchers.Main).launch { val engine = Engine.getInstance(id = "ly.img.engine.example") engine.start(license = license, userId = userId) engine.bindOffscreen(width = 100, height = 100)
val scene = engine.scene.create()
val page = engine.block.create(DesignBlockType.Page) engine.block.setWidth(page, value = 800F) engine.block.setHeight(page, value = 600F) engine.block.appendChild(parent = scene, child = page)
engine.scene.zoomToBlock( page, paddingLeft = 40F, paddingTop = 40F, paddingRight = 40F, paddingBottom = 40F, )
val block = engine.block.create(DesignBlockType.Graphic) engine.block.setShape(block, shape = engine.block.createShape(ShapeType.Rect)) engine.block.setWidth(block, value = 100F) engine.block.setHeight(block, value = 100F) engine.block.setFill(block, fill = engine.block.createFill(FillType.Color)) engine.block.appendChild(parent = page, child = block)
engine.block.supportsFill(scene) // Returns false engine.block.supportsFill(block) // Returns true
val colorFill = engine.block.getFill(block) val defaultRectFillType = engine.block.getType(colorFill) val allFillProperties = engine.block.findAllProperties(colorFill) engine.block.setColor( block = colorFill, property = "fill/color/value", value = Color.fromRGBA(r = 1.0F, g = 0.0F, b = 0.0F, a = 1.0F), )
engine.block.setFillEnabled(block, enabled = false) engine.block.setFillEnabled(block, enabled = !engine.block.isFillEnabled(block))
val imageFill = engine.block.createFill(FillType.Image) engine.block.setString( block = imageFill, property = "fill/image/imageFileURI", value = "https://img.ly/static/ubq_samples/sample_1.jpg", )
engine.block.destroy(colorFill) engine.block.setFill(block, fill = imageFill)
/* // The following line would also destroy imageFill engine.block.destroy(circle) */
val duplicateBlock = engine.block.duplicate(block) engine.block.setPositionX(duplicateBlock, value = 450F) val autoDuplicateFill = engine.block.getFill(duplicateBlock) engine.block.setString( block = autoDuplicateFill, property = "fill/image/imageFileURI", value = "https://img.ly/static/ubq_samples/sample_2.jpg", )
/* // We could now assign this fill to another block. val manualDuplicateFill = engine.block.duplicate(autoDuplicateFill) engine.block.destroy(manualDuplicateFill) */
val sharedFillBlock = engine.block.create(DesignBlockType.Graphic) engine.block.setShape(sharedFillBlock, shape = engine.block.createShape(ShapeType.Rect)) engine.block.setPositionX(sharedFillBlock, value = 350F) engine.block.setPositionY(sharedFillBlock, value = 400F) engine.block.setWidth(sharedFillBlock, value = 100F) engine.block.setHeight(sharedFillBlock, value = 100F) engine.block.appendChild(parent = page, child = sharedFillBlock) engine.block.setFill(sharedFillBlock, fill = engine.block.getFill(block))
engine.stop()}
In this example, we will show you how to use the CreativeEditor SDK’s CreativeEngine to modify strokes through the block
API. Strokes can be added to any shape or text and stroke styles are varying from plain solid lines to dashes and gaps of varying lengths and can have different end caps.
Strokes
fun supportsStroke(block: DesignBlock): Boolean
Query if the given block has a stroke property.
-
block
: the block to query. -
Returns true if the block has a stroke property, false otherwise.
fun setStrokeEnabled( block: DesignBlock, enabled: Boolean,)
Enable or disable the stroke of the given design block.
Required scope: “stroke/change”
-
block
: the block whose stroke should be enabled or disabled. -
enabled
: if true, the stroke will be enabled.
fun isStrokeEnabled(block: DesignBlock): Boolean
Query if the stroke of the given design block is enabled.
-
block
: the block whose stroke state should be queried. -
Returns true if the block’s stroke is enabled, false otherwise.
fun setStrokeColor( block: DesignBlock, color: Color,)
Set the stroke color of the given design block.
Required scope: “stroke/change”
-
block
: the block whose stroke color should be set. -
color
: the color to set.
fun getStrokeColor(block: DesignBlock): Color
Get the stroke color of the given design block.
-
block
: he block whose stroke color should be queried. -
Returns the stroke color.
fun setStrokeWidth( block: DesignBlock, width: Float,)
Set the stroke width of the given design block.
Required scope: “stroke/change”
-
block
: the block whose stroke width should be set. -
width
: the stroke width to be set.
fun getStrokeWidth(block: DesignBlock): Float
Get the stroke width of the given design block.
-
block
: the block whose stroke width should be queried. -
Returns the stroke’s width.
fun setStrokeStyle( block: DesignBlock, style: StrokeStyle,)
Set the stroke style of the given design block.
Required scope: “stroke/change”
-
block
: the block whose stroke style should be set. -
style
: the stroke style to be set.
fun getStrokeStyle(block: DesignBlock): StrokeStyle
Get the stroke style of the given design block.
-
block
: the block whose stroke style should be queried. -
Returns the stroke’s style.
fun setStrokePosition( block: DesignBlock, position: StrokePosition,)
Set the stroke position of the given design block.
Required scope: “stroke/change”
-
block
: the block whose stroke position should be set. -
position
: the stroke position to be set.
fun getStrokePosition(block: DesignBlock): StrokePosition
Get the stroke position of the given design block.
-
block
: the block whose stroke position should be queried. -
Returns the stroke position.
fun setStrokeCornerGeometry( block: DesignBlock, geometry: StrokeCornerGeometry,)
Set the stroke corner geometry of the given design block.
Required scope: “stroke/change”
-
block
: the block whose stroke join geometry should be set. -
geometry
: the stroke join geometry to be set.
fun getStrokeCornerGeometry(block: DesignBlock): StrokeCornerGeometry
Get the stroke corner geometry of the given design block.
-
block
: the block whose stroke join geometry should be queried. -
Returns the stroke join geometry.
In this example, we will show you how to use the CreativeEditor SDK’s CreativeEngine to modify a block’s fill through the block
API. The fill defines the visual contents within a block’s shape.
Creating a Fill
To create a fill simply use fun createFill(type: String): DesignBlock
.
val solidColor = engine.block.createFill(type = FillType.Color)
fun createFill(fillType: FillType): DesignBlock
Create a new fill, fails if type is unknown.
-
fillType
: the type of the fill object that shall be created. -
Returns the created fill’s handle.
We currently support the following fill types:
FillType.Color
FillType.LinearGradient
FillType.RadialGradient
FillType.ConicalGradient
FillType.Image
FillType.Video
FillType.PixelStream
val solidColor = engine.block.createFill(type = FillType.Color)
Functions
You can configure fills just like you configure design blocks. See Modify Properties for more detail.
engine.block.setColor( solidColor, property = "fill/color/value", value = Color.fromRGBA(r = 0.44F, g = 0.76F, b = 0.76F, a = 1F))
fun getFill(block: DesignBlock): DesignBlock
Returns the block containing the fill properties of the given block.
-
block
: the block whose fill block should be returned. -
Returns the block that currently defines the given block’s fill.
Remember to first destroy the previous fill if you don’t need it any more. A single fill can also be connected to multiple design blocks. This way, modifying the properties of the fill will apply the changes to all connected design blocks at once.
engine.block.destroy(previousFill)
fun setFill( block: DesignBlock, fill: DesignBlock,)
Sets the block containing the fill properties of the given block.
Note: The previous fill block is not destroyed automatically.
Required scopes: “fill/change”, “fill/changeType”
-
block
: the block whose fill should be changed. -
fill
: the new fill.
fun supportsFill(block: DesignBlock): Boolean
Query if the given block has fill color properties.
-
block
: the block to query. -
Returns true if the block has fill color properties, false otherwise.
fun setFillEnabled( block: DesignBlock, enabled: Boolean,)
Enable or disable the fill of the given design block.
Required scope: “fill/change”
-
block
: the block whose fill should be enabled or disabled. -
enabled
: if true, the fill will be enabled.
fun isFillEnabled(block: DesignBlock): Boolean
Query if the fill of the given design block is enabled.
-
block
: the block whose fill state should be queried. -
Returns true if the fill is enabled, false otherwise.