---
title: "Working with Design Editor | Customer's Canvas On-Premises"
canonical: "https://customerscanvas.com/docs/on-premises/ui-framework/design-editor-tutorial/"
---

# Working with Design Editor

> You may be already familiar with the [IFrame API](https://customerscanvas.com/docs/on-premises/design-editor/iframe-api/reference.md) which allows for integrating the Customer's Canvas editor to a page. It exposes a JavaScript API that enables you to extend the functionality of the editor. However, it requires additional JavaScript programming which may be challenging.

To reduce the amount of work, you need to do to implement the typical scenarios, we have created a UI Framework. It helps you to define the behavior of the editor by modifying a JSON config + writing a few one-liner JavaScripts instead of diving into a full-fledged JS development.

In this tutorial, we will show you how you can use the UI Framework to create an editor with the following functionality:

- Edit product designs.
- Change a design, e.g. by selecting a product option.
- Set a background, e.g. by selecting a thumbnail in an image list.
- When the user changes a background, you don't want to lose the progress the user made.
- Change both canvas mockups and preview mockups.
- Render the design and use the result in other widgets.

## Prerequisites

This tutorial assumes that you have already [installed the UI Framework](https://customerscanvas.com/docs/on-premises/ui-framework/getting-started.md) and have a general idea of [parametrized configs](https://customerscanvas.com/docs/on-premises/ui-framework/writing-configs/parametrizing-configs.md) and [dynamic expressions](https://customerscanvas.com/docs/on-premises/ui-framework/writing-configs/dynamic-expressions.md).

You can use examples of this tutorial in the **config** constant in the sample.

## DesignEditor Widget

As you might learn by using the demo, to manipulate the Customer's Canvas editor content, you need to configure the editor and use so-called "commands" in a widget config. Commands are the first-level elements of a widget's **params**, for example, for [design-editor](https://customerscanvas.com/docs/on-premises/ui-framework/widgets/design-editor.md), this config looks as follows: 

```json
{
    "widgets": [{
        "type": "design-editor",
        "name": "my-editor",
        "params": {
            "command1": { ... /* command1 params */ ... },
            "command2": { ... /* command2 params */ ... },
            // ... other commands.
        }
    }]
}
```

A command is triggered when the UI Framework detects changes in the config, i.e. if you refer to some option in one of its parameters. Other commands where no changes are detected are not triggered. If changes in several commands are detected, they are called in the same order as they go in the config.

## Initializing the Editor

To load and initialize the editor, you must use the  [initial](https://customerscanvas.com/docs/on-premises/ui-framework/widgets/design-editor-commands/initial.md) command. In this command, you specify a product design through the name of a state file, or an IDML/PSD file if you prefer to work with them directly. You can open the `bbq-invitation.psd` design and enable a simple editor mode as follows:

```json
{
    "type": "design-editor",
    "name": "my-editor",
    "params": {
        "initial": {
            "productDefinition": {
                "surfaces": [{
                    "printAreas": [{
                        "designFile": "bbq-invitation"
                    }]
                }]
            },
            "editorConfig": {
                "initialMode": "SimpleOnly"
            }
        }
    }
}
```

Now, try to load the editor using this config. If everything is done correctly, you will see your design in the editor.

Let's take a look at other commands that you need to achieve the goal described above.

## Replacing a Product Page

You may want to not only edit the template but also allow your users to change it, for example, by switching the orientation using the radio buttons in the **Tool Panel**.

To implement this, you need to prepare your templates for different product orientations. They should have a similar structure and the same elements with the same names. This will allow the editor to save the user changes when switching the templates.

Now, let's add an [option](https://customerscanvas.com/docs/on-premises/ui-framework/widgets/option.md) button, which will switch the templates.

```json
{
    "type": "option",
    "name": "orientation",
    "title": "orientation",
    "params": {
        "type": "radio",
        "title": "Orientation",
        "values": [
            { "title": "vertical" },
            { "title": "horizontal" }
        ]
    }
}
```

To change a template, you can use the [setPrintArea](https://customerscanvas.com/docs/on-premises/ui-framework/widgets/design-editor-commands/set-print-area.md) command. This command is equivalent to IFrame API's [setPrintAreas](https://customerscanvas.com/docs/on-premises/design-editor/iframe-api/reference/design-editor-iframe/classes/ObjectModel.Surface.md#setprintareas) method. It takes the same input structure as you pass to the `initial` command to describe a design (e.g. another state ID name or an IDML/PSD file name) and loads it to the current or specified page (surface) without updating other surfaces.

In the editor's config, you can refer to the value of this option through its name (`orientation` in our case) as follows:

```json
{
    "type": "design-editor",
    "name": "my-editor",
    "params": {
        "initial": { ... }, 
        "setPrintArea": {
            "data": {
                "designFile": "{{'cards/' + $['orientation']._.title}}"
            },
            "options": {
                "preserveUserChanges": true
            }
        }
    }
}
```

This command has `options` defining whether you want Customer's Canvas to merge new designs with the changes the user made or discard them. If you want to keep changes, then it runs some code under the hood that copies all new items to the new design, and if it detects items with the same names, it will copy their values to the appropriate items. You can refer to the description of [options here](https://customerscanvas.com/docs/on-premises/design-editor/iframe-api/reference/design-editor-iframe/classes/ObjectModel.Surface.md#setprintareas).

The `setPrintArea` command allows you to either change a single product page or replace the entire product in the editor. When you need to change a single page, use the `surfaceIndex` parameter. 

:::note
The `0` index corresponds to the first page.
:::

```json
{
    "type": "design-editor",
    "name": "my-editor",
    "params": {
        "initial": { ... }, 
        "setPrintArea": {
            "data": {
                "designFile": "{{'menu/' + $['weekday']._.title}}"
            },
            "surfaceIndex": 2,
            "options": {
                "preserveUserChanges": true
            }
        }
    }
}
```

This way, you can reload the template and transfer all changes made by the user.

The `setPrintArea` command transfers all layers, including the background. When you only need to change an image in the background, you can use the following command.

## Changing a Background Image

Unlike the previous command, instead of changing the entire design, `setBackground` receives a single image (JPEG, PDF, PNG) as an input. Under the hood, this command runs a code that finds a Background Container on a surface, removes the original image item from it, and replaces it with the specified image. It automatically enlarges it to fill the entire design. 

```json
{
    "type": "design-editor",
    "name": "my-editor",
    "params": {
        "initial": { ... },
        "setBackground": 
            "url": "{{ $['bg']._.url }}"
        }
    }
}
```

The `url` property can be either a URL to the image or a path in the Customer's Canvas gallery. In the latter case, use the **public:** prefix as explained in [user-info](https://customerscanvas.com/docs/on-premises/design-editor/iframe-api/howto/user-info.md). You can also use the `autoResize` or `toTile` properties to make the background image fill the entire design.

```json
{
    "type": "design-editor",
    "name": "my-editor",
    "params": {
        "initial": { ... },
        "setBackground": 
            "url": "{{ 'public:' + 'themes/' + $['colors']._.props.themeName + '.pdf' }}",
            "autoResize": true
        }
    }
}
```

Since this command only affects the background item, no other elements are affected and the user's progress remains intact.

## Changing Mockups

In the UI Framework, you can define two mockup types:
- _Canvas Mockups_ appear while editing a design. These mockups can be overlaying (so-called `Up` mockups) or represent the background (`Down` mockups).
- _Preview Mockups_ appear when approving the design.

You enable these mockups, you can define a product in the `initial` command as follows:

```json
{
    "widgets": [{
        "type": "design-editor",
        "name": "my-editor",
        "params": {
            "initial": {
                "productDefinition": {
                    "surfaces": [
                        {
                            "stateId": "5fe423ee2510eb0cfd293042",
                            "mockup": {
                                "down": "608cf7c90a5afd7e9198106f"
                            },
                            "location": { "X": "500", "Y": "400" },
                            "previewMockups": [{
                                "down": "5fe339382510eb0cfd292f97"
                            }]
                        }
                    ]
                }
            }
        // other widgets
}
```

Here, we defined the design and mockup images by using their IDs in Asset Storage.

Now, let's look at how you can change these mockups based on the user's choice. First, define an `option` widget with available mockups.

```json
{
    "type": "option",
    "name": "mockups",
    "title": "T-shirt color",
    "params": {
        "type": "radio",
        "values": [
            {
                "title": "White",
                "props": {
                    "mockup": "608cf7c90a5afd7e9198106f"
                }
            },
            {
                "title": "Red",
                "props": {
                    "mockup": "1f42a938251ccb0cf3492f11"
                }
            }
        ]
    }
}
```

After that, you can refer to this `mockups` widget when defining the [changeMockup](https://customerscanvas.com/docs/on-premises/ui-framework/widgets/design-editor-commands/change-mockup.md) command. This binding allows you to change mockups dynamically. When the user clicks the `Red` option, an image with a red T-shirt appears. When they click `White` again, the initial image will appear.

```json
{
    "widgets": [{
        "type": "design-editor",
        "name": "my-editor",
        "params": {
            "initial": { ... },
            "changeMockup": {
                "data": [{
                    "mockup": {
                        "down": "{{ $['mockups']._.props.mockup }}"
                    }
                }]
            }
        // other widgets
}
```

## Rendering Designs

UI Framework provides the following methods for rendering products loaded to the `design-editor` widget:

- [getHiResImages](https://customerscanvas.com/docs/on-premises/ui-framework/widgets/reference/au-widget-design-editor.au-widget-design-editor.md#getHiResImages) - renders print files.
- [getProofImages](https://customerscanvas.com/docs/on-premises/ui-framework/widgets/reference/au-widget-design-editor.au-widget-design-editor.md#getProofImages) - renders proof images in JPG and PNG formats.
- [getProofPdf](https://customerscanvas.com/docs/on-premises/ui-framework/widgets/reference/au-widget-design-editor.au-widget-design-editor.md#getProofPdf) - renders proof images in PDF format.

Usually, you can call these methods from `onActivate` and `onLeave` handlers of `steps` as well as from `onClick` handlers of buttons, for example:

```json
{
    "type": "button",
    "name": "finish-button",
    "params": {
        "text": "Finish",
        "onClick": [
            "{{#function main.showPreloader(true, 'Creating print files...')}}",
            "{{#function $['my-editor'].getHiResImages(800,800)}}",
            "{{#function main.showPreloader(false)}}",
            "{{#function cart.submit()}}"
        ]
    }
}
```

Here, we enable a preloader, render the product loaded to the `my-editor` widget, disable the preloader when `getHiResImages` finishes, and submit the order.

When you call these methods in `onActivate`, you can initialize widgets defined in the step. For example, you can generate proof images when activating the approval step.

```json
"steps": [
    {
        "name": "Editor",
        "mainPanel": {
            "name": "my-editor"
        }
    },
    {
        "name": "Approve",
        "onActivate": [
            "{{#function $['my-editor'].getProofImages() }}"
        ],
        "mainPanel": {
            "name": "preview"
        }
    }
]
```

Then, use those images in the preview widget.

```json
{
    "type": "image-carousel",
    "name": "preview",
    "params": {
        "images": {
            "{{ #each $['my-editor'].proofImageUrls as item }}": {
                "url": "{{ item[index]}}"
            }
        }
    }
}
```

---
For more details, you can refer to the [widget reference](https://customerscanvas.com/docs/on-premises/ui-framework/widgets/design-editor.md).
