Canvas
=====

A widget which integrates Customer's Canvas 4 to the editor. As usual, it is the most important widget of the editor and it is heavily parametrized using the [dynamic configs](../dynamic-configs.md).

Note, to be able to use it, you should be familiar with [Customer's Canvas IFrame API](https://customerscanvas.com/docs/cc/IframeApi-introduction.htm) and [basics of its configuration](https://customerscanvas.com/docs/cc/client-config.htm).

## General info

- **type**: `canvas`

## Config structure

This widget is a bit outstanding compared to other widgets. It does not have its own properties. Instead, all its properties are organized in so-called _commands_. 

A command is a first-level property of a `canvas` config. The following commands are supported:

- [`initial` - initialization (required)](canvas-commands/initial.md)
- [`changeMockup` - replaces mockups stored in CC backend](canvas-commands/change-mockup.md)
- [`setRemoteMockup` - replaces mockups by specified URL](canvas-commands/set-remote-mockup.md)
- [`changeLayout` - reapplies another template as a layout](canvas-commands/change-layout.md)
- [`setPrintArea` - loads another template on a specific surface](canvas-commands/set-print-area.md)
- [`setBackground` - replaces background image](canvas-commands/set-background.md)
- [`setTheme` - changes a theme](canvas-commands/set-theme.md)
- [`modifyItems` - modifies elements inside the editor](canvas-commands/modify-items.md)

You may omit any command except `initial`.

Each command has its own properties you are supposed to make dynamic. As soon as the editor detects changes in a widget you are referring to in a particular command, only this command is executed. For example, you may have the following commands:

``` json
{
    "name": "editor",
    "type": "canvas",
    "params": {
        "initial": { ... },
        "setBackground": {
            "url": "{{$['gallery']._.url}}"
        },
        "changeMockup": {
            "data": {
                "mockup": {
                    "down": "{{$['color']._.mockupName}}"
                }
            }
        }
    }
}
```

Imagine that the user chooses an alternative background in the **gallery** widget. In this case, only the `setBackground` command will work, neither `initial` nor `changeMockup` will be re-applied (which would happen cause it to reload all the design and do unnecessary flickering). 

This way you are using these commands to associate Customer's Canvas with different widgets and perform various actions when you change anything.

## How to have Customer's Canvas to generate a result

The most typical scenario is to organize the editor into several steps, where, for example, the first step is the Customer's Canvas and the next step is an approval page where you need to display the result and pass the hi-res PDF out of the editor.

To accomplish this, you need to tell Customer's Canvas to generate a result when you leave the design step and grab the output in the config of the approval step. 

To save the result, you can call these methods:

- `getHiResImages(previewWidth, previewHeight)` - an equivalent to [editor.finishProductDesign](https://customerscanvas.com/docs/cc/customerscanvas.iframeapi.editor.finishproductdesign.htm) from IFrame API.
- `getProofImages(previewWidth, previewHeight)` - an equivalent to [editor.getProofImages](https://customerscanvas.com/docs/cc/customerscanvas.iframeapi.editor.getproofimages.htm) from IFrame API.
- `saveProduct()` - an equivalent to [editor.saveProduct](https://customerscanvas.com/docs/cc/customerscanvas.iframeapi.editor.saveproduct.htm) from IFrame API. 

After they finish working, they will return the results to the following properties of the widget: 

- `proofImageUrls`
- `hiResUrls`
- `stateId`
- `userId`
- `userChanges`

The `getHiResImages` changes all these properties, the `getProofImages` - only the `proofImageUrls` and `saveProduct` - only the `stateId` and `userId`.

The `proofImageUrls` and `hiResUrls` are arrays of the same structure as returned by IFrame API. See the documentation for the appropriate methods in Customer's Canvas for more details. 

You may wonder where to call the `getHiResImages` method. As usual, you can do it in the `onActivate` of a step where you need to use the results or in `onClick` of a [button widget](button.md).

## Example

``` json
{
    "widgets": [
        {
            "name": "editor",
            "type": "canvas",
            "params": {
                "initial": { ... },
                ... // other commands
            }
        },
        {
            "name": "preview-image",
            "type": "static-image",
            "params": {
                "url": "{{$['editor'].proofImageUrls[0][0]}}"
            }
        }
    ],
    "steps": [
        {
            "name": "design",
            "title": "Design",
            "mainPanel": {"name":"editor"} 
        },
        {
            "name": "approve",
            "title": "Preview",
            "mainPanel": {"name":"preview-image"},
            "onActivate": "{{#function $['editor'].getHiResImages(800,800)}}" 
        },
    ]
}
```


## Other methods and properties 

For most use cases, the methods and properties described above are enough. However, for more complicated configs (e.g. related to the Variable Data Printing), you may be interested to use additional members: 

- `getTags()`/`setTags()` methods and `tags` property - to read/write custom data (such as Variable Data) to the state file
- `getVariableData()` method and `variableData` property - to detect what particular variable fields are used in the design. It is used to build a list of variable fields. 
- `getAllItems()` method and `allItems` property - to read info about items in Customer's Canvas

Note, due to the declarative nature of a JSON config, the `get`_`XXX`_ methods do not return any usable results. Instead, they tell Customer's Canvas to initialize the appropriate property. When it happens, the dynamic config engine is notified about changes and the config is re-applied.
