Command System
The command system allows you to execute arbitrary operation against a design. Under the hood our workflow experience is built using composed commands. But at any time you can break out of this and execute commands directly. This is a great way to add custom functionality to your workflow experience. After building a workflow experience you can obtain a command context from it using the following.
Usage
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontColorCommand(elementId, "#FFFFFF"))
Undo & Redo
The command context supports undo and redo operations. This allows you to give your customers the power to quickly jump back and forth between changes.
const ctx = workflowExperience.getCommandContext();
ctx.undo();
ctx.redo();
Commands
Generic
Generic commands apply to all elements that we provide. These commands relate to functionality that is common to all elements or to the design itself.
MoveCommand
The move command allows you to set a new position for an element. After being dispatched the target element will have its x, y properties updated to reflect the new position.
- This command is affected by limitations imposed by configuration such as editable areas.
- Movements are absolute, not relative. Passing x = 100, y = 100 will not be relative to the current position.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new MoveCommand(targetElementID, 100, 100))
RotateCommand
The rotate command allows you to set a new rotation for an element in degrees. After being dispatched the target element will have its rotation property updated to reflect the new rotation.
- This command is affected by limitations imposed by configuration such as editable areas.
- Rotations are in degrees.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new RotateCommand(targetElementID, 45))
ResizeCommand
The resize command allows you to set a new size for an element. After being dispatched the target element will have its width, height properties updated to reflect the new size.
- This command is affected by limitations imposed by configuration such as editable areas.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new ResizeCommand(targetElementID, 100, 100))
BringToFrontCommand
This command allows you to shift an element to the top index in accordance to the layering system. After being dispatched the target element will have its layerIndex property updated to reflect the new position.
- If the element is already on the top index within its current layer, this command will have no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new BringToFrontCommand(targetElementID))
BringForwardCommand
This command allows you to shift an element forward by one index in accordance to the layering system. After being dispatched the target element will have its layerIndex property updated to reflect the new position.
- If the element is already on the top index within its current layer, this command will have no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new BringForwardCommand(targetElementID))
BringToBackCommand
This command allows you to shift an element to the bottom index in accordance to the layering system. After being dispatched the target element will have its layerIndex property updated to reflect the new position.
- If the element is already on the bottom index within its current layer, this command will have no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new BringToBackCommand(targetElementID))
SendBackwardsCommand
This command allows you to shift an element backwards by one index in accordance to the layering system. After being dispatched the target element will have its 'layerIndex' property updated to reflect the new position.
- If the element is already on the bottom index within its current layer, this command will have no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new SendBackwardsCommand(targetElementID))
LayerCommand
With the layering command you can change the layer group of a specific element in accordance to the layering system. After being dispatched the target element will have its 'layer' property updated to reflect the new position.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new LayerCommand(targetElementID, 3))
GroupCommand
The group command allows you to batch multiple commands into a single undoable/redoable group. Undo / Redo behavior is explained in further detail above.
This command will be renamed to 'CompositeCommand' in the future. The GroupCommand will then be used to group elements together within a container element. Please keep this in mind when upgrading versions as it will be a breaking change. The interface typing will change so adapting your code should be easy.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new GroupCommand([
new MoveCommand(targetElementID, 100, 100),
new RotateCommand(targetElementID, 45)
]))
CreateElementCommand
Creating arbitrary elements is also achieved with the CreateElementCommand. This command allows you to create a new element and add it to the design. You may express all of the properties of the element you wish to create. If you do not provide a given property, sensible defaults will be used.
To ease the creation of elements, we provide a set of helper functions that will create elements with the correct properties for you. These are static methods on the LayoutElementFactory class. For example to create an Illustration element you could use the following.
await LayoutElementFactory.getIllustration(layout, { src: link })
This will load an SVG asset from the provided link and return an Illustration element with the correct properties set. Width and height would be inferred from the 'viewbox' attribute.
- If no explicit region is provided, the element will be positioned at the center of the editable area if defined, otherwise it will be positioned at the center of the layout.
const { state, uiDispatcher } = useEditorState();
const { getLayoutById } = useLayouts();
const layout = getLayoutById(state.layoutId);
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new CreateElementCommand({ ...elementProperties }, layout.layoutState.layout))
DeleteElementCommand
The delete element command allows you to remove an element from the design.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new DeleteElementCommand(targetElementID))
CloneElementCommand
Cloning elements can be achieved with a target element & layout. All properties from the original element will be copied across, the original ID will be replaced with a new one.
const { state, uiDispatcher } = useEditorState();
const { getLayoutById } = useLayouts();
const layout = getLayoutById(state.layoutId);
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new CloneElementCommand(targetElementID, , layout.layoutState.layout))
Text
Text commands only work with Textbox elements. They provide functionality specific to the rendering of text.
FontColorCommand
Text elements can have their color changed with the FontColorCommand. This command will update the color property of the target element.
Color profiles are a topic on their own. Our system allows you to upload & embed color profiles into illustrations & on text. You can learn more about them on their support page. You'll find an example of setting color with a profile below.
// Set the color to black
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontColorCommand(targetElementID, '#000000'))
// To use a color profile, you can pass in a profile name and a named color
ctx.commandDispatcher(new FontColorCommand(targetElementID, '#000000', {profileName: "my-color-profile", namedColor: "Gold"}))
FontSizeCommand
You may change the font size of a textbox element with the FontSizeCommand. This command will update the 'fontSize' property of the target element.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontSizeCommand(targetElementID, 16))
FontAlgorithmCommand
Updates the algorithm used to render text. Use the TextAlgorithm enumeration to specify. There are two algorithms to choose from
- Traditional - This is favored in any case where user manipulates text in an 'editor' style. It renders a sentence out to the width of the element and then breaks to a new line.
- Autosize - This algorithm computes the size of the text to fit the element. It will not break to a new line unless configured to do so.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontAlgorithmCommand(targetElementID, TextAlgorithm.Traditional))
FontSourceCommand
Changes the font family used to render a text element. Fonts can be loaded from an asset link. The asset must be of type 'Font' and have a 'cdn' rel. The font will be loaded from the provided link and then the font family will be updated on the target element.
const src = asset.links.find((l) => l.rel === "cdn")?.href;
const font = await loadFontFromExternalUrl(src!);
const fontData = {
assetUrl: src!,
name: font.names.fullName["en"],
};
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontSourceCommand(targetElementID, fontData))
FontAlignmentCommand
Changes the alignment of text within a text element. The available values are "left", "center", "right".
- The alignment is computed base on the width of a rendered line and the size of the textbox element itself. If the line matches the width of the element, there will be no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontAlignmentCommand(targetElementID, "right"))
TextChangeCommand
Modifies the text within a textbox element. This command will update the 'text' property of the target element. As an example you may dispatch this event from a text input field.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new TextChangeCommand(targetElementID, "The quick brown fox jumps over the lazy dog."))