# CanvasTools library for VoTT-dot

`CanvasTools` is one of the UI modules used in the [VoTT-dot project](https://github.com/Digital-Maritime-Consultancy/VoTT-dot). The library implements the following core features:

* Region (box, point, polyline & polygon) selection & manipulation
* Filters pipeline for underlaying canvas element
* Toolbar for all available tools

## Dependencies

* `CanvasTools` heavily uses the [Snap.Svg](https://github.com/adobe-webplatform/Snap.svg) library. In the webpack-eged version it is bundled with `CanvasTools` into one `ct.js` file, including also styles.
* Current version of the library depends on some features (e.g., masks-support in SVG) that are not fully cross-browser, but are targeting Electron (Chromium).

## How to use

### Install npm package

Install package from npm:

```node
npm i @jinkijung/vott-dot-ct
```

The package structure:

```txt
dist/
    ct.d.ts -- bundled typings
    ct.dev.js -- webpack bundle for development (incl source map)
    ct.js -- webpack bundle for production ({tsc->commonjs, snapsvg, styles} -> umd)
    ct.js.map -- source map for ct.js
    ct.min.js -- webpack minimized bundle for production
    ct.min.js.map -- source map for ct.min.js
lib/
    css/
        canvastools.css
    icons/
        {*.png, *.svg} - collection of icons for toolbar and cursor
    js/
        ct.d.ts -- typings generated by tcs
        ct.js -- AMD module generated by tcs
        ct.js.map -- map file generated by tcs
        snapsvg-cjs.d.ts -- typings for the snapsvg-cjs package
        CanvasTools/
            {*.js, *.d.ts} -- compilied js and typings files
```

### Add library to the app

1. Add the `ct.js` file to your web-app (e.g., an Electron-based app).

    ```html
    <script src="ct.js"></script>
    <!-- OR -->
    <script src="ct.min.js"></script>

    ```

2. Copy toolbar icons from the [`src` folder](https://github.com/Digital-Maritime-Consultancy/CanvasTools-for-VOTT-dot/tree/master/src/canvastools/icons) to your project.

### Add Editor to the page

1. Add container elements to host SVG elements for the toolbar and the editor.

    ```html
    <div id="canvasToolsDiv">
        <div id="toolbarDiv"></div>
        <div id="selectionDiv">
            <div id="editorDiv"></div>
        </div>
    </div>
    ```

2. Initiate the `Editor`-object from the `CanvasTools`.

    ```js
    var editorContainer = document.getElementById("editorDiv");
    var toolbarContainer = document.getElementById("toolbarDiv");

    var editor = new CanvasTools.Editor(editorContainer).api;
    editor.addToolbar(toolbarContainer, CanvasTools.Editor.FullToolbarSet, "./images/icons/");
    ```

    The editor will auto-adjust to available space in provided container block.
    `FullToolbarSet` icons set is used by default and exposes all available tools. The `RectToolbarSet` set contains only box-creation tools. Correct the path to toolbar icons based on the structure of your project.

### Add callbacks to the Editor

1. Add a callback for the `onSelectionEnd` event to define what should happen when a new region is selected (created). Usually at the end of processing the new `regionData` you also want to add it to the screen with some tags applyed. Use the `addRegion` method for that.

    ```js
    // Create some ID for regions
    let incrementalRegionID = 100;

    // Set callback for onSelectionEnd
    editor.onSelectionEnd = (regionData) => {
        let id = (incrementalRegionID++).toString();
        let tags = getTagsDescriptor();            
        editor.addRegion(id, regionData, tags);
    };        

    const Color = CanvasTools.Core.Colors.Color;
    const LABColor = CanvasTools.Core.Colors.LABColor;
    const Tag = CanvasTools.Core.Tag;
    const TagsDescriptor = CanvasTools.Core.TagsDescriptor;

    // Generate tags
    function getTagsDescriptor() {
        // Use the Color class to specify color
        let primaryTag = new Tag("Awesome", new Color("#c48de7"));
        // Use a string color to specify color
        let secondaryTag = new Tag("Yes", "#f94c48");
        // Use one of the color spaces classes (e.g., LABColor) to specify color
        let ternaryTag = new Tag("one", new Color(new LABColor(0.62, 0.50, -0.55)));
        return new TagsDescriptor(primaryTag, [secondaryTag, ternaryTag]);
    }
    ```

2. Add a callback for the `onRegionMove` event to track region changes.

    ```js
    editor.onRegionMove = (id, regionData) => {
        console.log(`Moved ${id}: {${regionData.x}, ${regionData.y}} x {${regionData.width}, ${regionData.height}}`);
    };
    ```

### Update background
Once the background image for tagging task is loaded (or a video element is ready, or a canvas element is created), pass it to the editor as a new content source.

```js
let imagePath = "./../images/background-forest-v.jpg";
let image = new Image();
image.addEventListener("load", (e) => {
    editor.addContentSource(e.target);
});
image.src = imagePath;
```

### Examples
Samples on the usage of the library are located at [`samples` folder](https://github.com/Digital-Maritime-Consultancy/CanvasTools-for-VOTT-dot/tree/master/samples).
To view the sample CanvasTools UI module, load the index.html present in one of the samples folder. Eg. [`samples/editor/index.html` folder](https://github.com/Digital-Maritime-Consultancy/CanvasTools-for-VOTT-dot/blob/master/samples/editor/index.html)


## Changelog
Moved to a new file: [CHANGELOG.md](https://github.com/Digital-Maritime-Consultancy/CanvasTools-for-VOTT-dot/blob/master/CHANGELOG.md).