You can use four different boolean operations on blocks to combine them into unique shapes. These operations are:
'Union'
: adds all the blocks’ shapes into one'Difference'
: removes from the bottom-most block the shapes of the other blocks overlapping with it'Intersection'
: keeps only the overlapping parts of all the blocks’ shapes'XOR'
: removes the overlapping parts of all the block’s shapes
Combining blocks allows you to create a new block with a customized shape.
Combining blocks with the union
, intersection
or XOR
operation will result in the new block whose fill is that of the top-most block and whose shape is the result of applying the operation pair-wise on blocks from the top-most block to the bottom-most block.
Combining blocks with the difference
operation will result in the new block whose fill is that of the bottom-most block and whose shape is the result of applying the operation pair-wise on blocks from the bottom-most block to the top-most block.
The combined blocks will be destroyed.
isCombinable(ids: DesignBlockId[]): boolean
Checks whether blocks could be combined. Only graphics blocks and text blocks can be combined. All blocks must have the “lifecycle/duplicate” scope enabled.
ids
: An array of block ids.- Returns Whether the blocks can be combined.
combine(ids: DesignBlockId[], op: BooleanOperation): DesignBlockId
Perform a boolean operation on the given blocks. All blocks must be combinable. See isCombinable
. The parent, fill and sort order of the new block is that of the prioritized block. When performing a Union
, Intersection
or XOR
, the operation is performed pair-wise starting with the element with the highest sort order. When performing a Difference
, the operation is performed pair-wise starting with the element with the lowest sort order. Required scopes: ‘lifecycle/duplicate’, ‘lifecycle/destroy’
ids
: The blocks to combine. They will be destroyed if “lifecycle/destroy” scope is enabled.op
: The boolean operation to perform.- Returns The newly created block or an error.
Here’s the full code:
// Create blocks and append to sceneconst star = engine.block.create('shapes/star');const rect = engine.block.create('shapes/rect');engine.block.appendChild(page, star);engine.block.appendChild(page, rect);
// Check whether the blocks may be combinedconst combinable = engine.block.isCombinable([star, rect]);if (combinable) { const combined = engine.block.combine([star, rect], 'Union');}
Combining three circles together
We create three circles and arrange in a recognizable pattern.
Combing them with 'Union'
result in a single block with a unique shape.
The result will inherit the top-most block’s fill, in this case circle3
’s fill.
const circle1 = engine.block.create('graphic'); engine.block.setShape(circle1, engine.block.createShape('ellipse')); engine.block.setFill(circle1, engine.block.createFill('color')); engine.block.setPositionX(circle1, 30); engine.block.setPositionY(circle1, 30); engine.block.setWidth(circle1, 40); engine.block.setHeight(circle1, 40); engine.block.appendChild(page, circle1);
const circle2 = engine.block.create('graphic'); engine.block.setShape(circle2, engine.block.createShape('ellipse')); engine.block.setFill(circle2, engine.block.createFill('color')); engine.block.setPositionX(circle2, 80); engine.block.setPositionY(circle2, 30); engine.block.setWidth(circle2, 40); engine.block.setHeight(circle2, 40); engine.block.appendChild(page, circle2);
const circle3 = engine.block.create('graphic'); engine.block.setShape(circle3, engine.block.createShape('ellipse')); engine.block.setFill(circle3, engine.block.createFill('color')); engine.block.setPositionX(circle3, 50); engine.block.setPositionY(circle3, 50); engine.block.setWidth(circle3, 50); engine.block.setHeight(circle3, 50); engine.block.appendChild(page, circle3);
const union = engine.block.combine([circle1, circle2, circle3], 'Union');
To create a special effect of text punched out from an image, we create an image and a text. We ensure that the image is at the bottom as that is the base block from which we want to remove shapes. The result will be a block with the size, shape and fill of the image but with a hole in it in the shape of the removed text.
const text = engine.block.create('text'); engine.block.replaceText(text, 'Removed text'); engine.block.setPositionX(text, 10); engine.block.setPositionY(text, 40); engine.block.setWidth(text, 80); engine.block.setHeight(text, 10); engine.block.appendChild(page, text);
const image = engine.block.create('graphic'); engine.block.setShape(image, engine.block.createShape('rect')); const imageFill = engine.block.createFill('image'); engine.block.setFill(image, imageFill); engine.block.setPositionX(image, 0); engine.block.setPositionY(image, 0); engine.block.setWidth(image, 100); engine.block.setHeight(image, 100); engine.block.setString( imageFill, 'fill/image/imageFileURI', 'https://img.ly/static/ubq_samples/sample_1.jpg' ); engine.block.appendChild(page, image);
engine.block.sendToBack(image); const difference = engine.block.combine([image, text], 'Difference');
Full Code
Here’s the full code:
import CreativeEngine from 'https://cdn.img.ly/packages/imgly/cesdk-engine/1.51.0/index.js';
const config = { license: 'mtLT-_GJwMhE7LDnO8KKEma7qSuzWuDxiKuQcxHKmz3fjaXWY2lT3o3Z2VdL5twm', userId: 'guides-user', baseURL: 'https://cdn.img.ly/packages/imgly/cesdk-engine/1.51.0/assets',};
CreativeEngine.init(config).then(async engine => { document.getElementById('cesdk_container').append(engine.element);
const scene = engine.scene.create();
const page = engine.block.create('page'); engine.block.setWidth(page, 800); engine.block.setHeight(page, 600); engine.block.appendChild(scene, page);
const circle1 = engine.block.create('graphic'); engine.block.setShape(circle1, engine.block.createShape('ellipse')); engine.block.setFill(circle1, engine.block.createFill('color')); engine.block.setPositionX(circle1, 30); engine.block.setPositionY(circle1, 30); engine.block.setWidth(circle1, 40); engine.block.setHeight(circle1, 40); engine.block.appendChild(page, circle1);
const circle2 = engine.block.create('graphic'); engine.block.setShape(circle2, engine.block.createShape('ellipse')); engine.block.setFill(circle2, engine.block.createFill('color')); engine.block.setPositionX(circle2, 80); engine.block.setPositionY(circle2, 30); engine.block.setWidth(circle2, 40); engine.block.setHeight(circle2, 40); engine.block.appendChild(page, circle2);
const circle3 = engine.block.create('graphic'); engine.block.setShape(circle3, engine.block.createShape('ellipse')); engine.block.setFill(circle3, engine.block.createFill('color')); engine.block.setPositionX(circle3, 50); engine.block.setPositionY(circle3, 50); engine.block.setWidth(circle3, 50); engine.block.setHeight(circle3, 50); engine.block.appendChild(page, circle3);
const union = engine.block.combine([circle1, circle2, circle3], 'Union');
const text = engine.block.create('text'); engine.block.replaceText(text, 'Removed text'); engine.block.setPositionX(text, 10); engine.block.setPositionY(text, 40); engine.block.setWidth(text, 80); engine.block.setHeight(text, 10); engine.block.appendChild(page, text);
const image = engine.block.create('graphic'); engine.block.setShape(image, engine.block.createShape('rect')); const imageFill = engine.block.createFill('image'); engine.block.setFill(image, imageFill); engine.block.setPositionX(image, 0); engine.block.setPositionY(image, 0); engine.block.setWidth(image, 100); engine.block.setHeight(image, 100); engine.block.setString( imageFill, 'fill/image/imageFileURI', 'https://img.ly/static/ubq_samples/sample_1.jpg', ); engine.block.appendChild(page, image);
engine.block.sendToBack(image); const difference = engine.block.combine([image, text], 'Difference');});