# Markup Editor Properties

A list of properties available to configure the markup editor.

| Property                                                              | Default value                                               | Description                                                                                                                                                                                                                         |
| --------------------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [markupEditorToolbar](#markupeditortoolbar)                           | undefined                                                   | An array of tools to render in the Markup Editor toolbar.                                                                                                                                                                           |
| [markupEditorToolStyles](#markupeditortoolstyles)                     | undefined                                                   | The default shape style definitions to use for each tool in the toolbar.                                                                                                                                                            |
| [markupEditorToolRetainStyles](#markupeditortoolretainstyles)         | undefined                                                   | Set to true to remember tool styles between edit sessions.                                                                                                                                                                          |
| markupEditorToolShareStyles                                           | undefined                                                   | Set to false to have each tool retain its own style settings.                                                                                                                                                                       |
| [markupEditorShapeStyleControls](#markupeditorshapestylecontrols)     | undefined                                                   | The style control options available to change the appearance of shapes.                                                                                                                                                             |
| [markupEditorTextInputMode](#markupeditortextinputmode)               | 'inline'                                                    | Set to 'modal' to offer text editing in a plain text modal instead of inline.                                                                                                                                                       |
| [markupEditorToolSelectRadius](#markupeditortoolselectradius)         | 0                                                           | The radius around a select action to select shapes in.                                                                                                                                                                              |
| [markupEditorWillStartInteraction](#markupeditorwillstartinteraction) | undefined                                                   | A function that receives the current interaction position and image rectangle, should return true if interaction is allowed and false if not.                                                                                       |
| [markupEditorInteractionMode](#markupeditorinteractionmode)           | 'auto'                                                      | Set to 'pan' to force pan mode (spacebar + drag), set back to 'auto' to switch to draw mode.                                                                                                                                        |
| [markupEditorZoomLevels](#markupeditorzoomlevels)                     | undefined                                                   | An array of zoom levels defined as fractions. Default value is \[0.25, 0.5, 1, 1.25, 1.5, 2, 3, 4, 6, 8, 16\].                                                                                                                      |
| [markupEditorZoomAdjustStep](#markupeditorzoomadjuststep)             | .25                                                         | The speed at which pressing the zoom buttons increases or decreases zoom.                                                                                                                                                           |
| [markupEditorZoomAdjustFactor](#markupeditorzoomadjustfactor)         | .1                                                          | The factor used to increase or decrease zoom speed when holding the zoom buttons. Increase speed is 1 + .1, decrease speed is 1 - .1.                                                                                               |
| [enableMultiSelect](#enablemultiselect)                               | false                                                       | When set to true enables seleting multiple shapes. Shapes can then be styled and translated simultaneously.                                                                                                                         |
| [enableSelectToolToAddShape](#enableselecttooltoaddshape)             | false                                                       | When set to true the editor will add a shape to the middle of the image when a shape tool is tapped.                                                                                                                                |
| [enableTapToAddText](#enabletaptoaddtext)                             | false                                                       | When set to true the editor will add an auto-width text shape when the text tool is active and an empty part of the canvas is tapped.                                                                                               |
| [enableViewTool](#enableviewtool)                                     | false                                                       | When set to true a view tool will be added to the tools list, this tool enables dragging the canvas without holding spacebar.                                                                                                       |
| [enableMoveTool](#enablemovetool)                                     | false                                                       | When set to true a move tool will be added to the tools list, making it easier to move shapes.                                                                                                                                      |
| [enableAutoSelectMoveTool](#enableautoselectmovetool)                 | \['path', 'line', 'arrow', 'rectangle', 'ellipse', 'text'\] | Set to false to disable automatically switching back to the move tool, set to true to enable auto switch back for all shape tools, set to a list of tool keys to pick which tools have this behaviour.                              |
| [markupEditorSnapThreshold](#markupeditorsnapthreshold)               | 0                                                           | The distance in pixels at which shapes snap to grid or other shapes. When set to 0 snapping is disabled.                                                                                                                            |
| [markupEditorSnapToContext](#markupeditorsnaptocontext)               | true                                                        | If enabled shapes snap to context edges and context center.                                                                                                                                                                         |
| [markupEditorGridSize](#markupeditorgridsize)                         | 0                                                           | The size of the grid cells in pixels, when set to 0 the grid is disabled.                                                                                                                                                           |
| [beforeSelectShape](#beforeselectshape)                               | undefined                                                   | Set to a function that runs before selecting a shape. Receives previously selected shape an targetted shape.                                                                                                                        |
| [beforeDeselectShape](#beforedeselectshape)                           | undefined                                                   | Set to a function that runs before deselecting a shape. Receives currently selected shape and targetted shape.                                                                                                                      |
| [beforeAddShape](#beforeaddshape)                                     | undefined                                                   | Set to a function that runs before adding a preset shape. Receives shape that is going to be added.                                                                                                                                 |
| [beforeRemoveShape](#beforeremoveshape)                               | undefined                                                   | Set to a function that runs before removing a shape. Receives shape that is going to be removed. Return true                                                                                                                        |
| [beforeUpdateShape](#beforeupdateshape)                               | undefined                                                   | Set to a function that runs before updating a shape. Receives shape that is going to be updated. Additionally receives the props object that will be applied to the shape and the context rectangle in which the shape is rendered. |
| [willRenderShapePresetToolbar](#willrendershapepresettoolbar)         | undefined                                                   | Can be set to a function to modify the markup editor preset toolbar.                                                                                                                                                                |
| [willRenderShapeControls](#willrendershapecontrols)                   | undefined                                                   | Allows to inject custom shape controls or to edit the shape control menu.                                                                                                                                                           |
| willRenderShapeTextControls                                           | undefined                                                   | Allows to inject custom shape text controls or to edit the shape text control menu.                                                                                                                                                 |

### markupEditorToolbar

Use the `markupEditorToolbar` property to update the tools in the Markup Editor toolbar. The property should be set to an array of tool item definitions.

By default the Markup Editor defines the following tools (in this order).

| Name        | Description                                                                                                             |
| ----------- | ----------------------------------------------------------------------------------------------------------------------- |
| 'sharpie'   | Draw fine lines, this is a path based tool.                                                                             |
| 'eraser'    | Erasing paths, lines, and arrows based lines. Does not have a default shape assigned.                                   |
| 'path'      | Draw multi corner path or polygon, hold shift key to snap. Tap start point to close polygon. Tap end point to end path. |
| 'line'      | For drawing straight lines, hold shift key to snap.                                                                     |
| 'arrow'     | For drawing arrows, hold shift key to snap.                                                                             |
| 'rectangle' | For drawing rectangles.                                                                                                 |
| 'ellipse'   | For drawing ellipses.                                                                                                   |
| 'text'      | For drawing text boxes.                                                                                                 |
| 'preset'    | For selecting presets / stickers, only shown if presets have been defined.                                              |

The `'eraser'` and `'preset'` tool are special. Where other tools have a default `shape` declaration, the `preset` and `eraser` tools do not.

The preset tool will show a list of preset stickers, if defined, if not, the preset tool won't be visible. The eraser tool can be used to erase line and path based shapes.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-38)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-38)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-38)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-38)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-38)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-38)

* [index.html](#index-html-panel-38)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        markupEditorToolbar: [
            ['sharpie', 'Sharpie', { disabled: true }],
            ['eraser', 'Eraser', { disabled: false }],
            [
                'rectangle',
                'Rectangle',
                { disabled: false, icon: '<g></g>', title: 'My Rectangle' },
            ],
        ],
    });
</script>
`

* [App.jsx](#App-jsx-panel-38)
* [App.css](#App-css-panel-38)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                markupEditorToolbar={[
                    ['sharpie', 'Sharpie', { disabled: true }],
                    ['eraser', 'Eraser', { disabled: false }],
                    [
                        'rectangle',
                        'Rectangle',
                        {
                            disabled: false,
                            icon: '<g></g>',
                            title: 'My Rectangle',
                        },
                    ],
                ]}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-38)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :markupEditorToolbar="markupEditorToolbar"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            markupEditorToolbar: [
                ['sharpie', 'Sharpie', { disabled: true }],
                ['eraser', 'Eraser', { disabled: false }],
                [
                    'rectangle',
                    'Rectangle',
                    { disabled: false, icon: '<g></g>', title: 'My Rectangle' },
                ],
            ],
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-38)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        markupEditorToolbar={[
            ['sharpie', 'Sharpie', { disabled: true }],
            ['eraser', 'Eraser', { disabled: false }],
            [
                'rectangle',
                'Rectangle',
                { disabled: false, icon: '<g></g>', title: 'My Rectangle' },
            ],
        ]}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-38)
* [app.component.html](#app-component-html-panel-38)
* [app.component.css](#app-component-css-panel-38)
* [app.module.ts](#app-module-ts-panel-38)

`import { Component } from '@angular/core';

import { getEditorDefaults } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    markupEditorToolbar: any = [
        ['sharpie', 'Sharpie', { disabled: true }],
        ['eraser', 'Eraser', { disabled: false }],
        [
            'rectangle',
            'Rectangle',
            { disabled: false, icon: '<g></g>', title: 'My Rectangle' },
        ],
    ];
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [markupEditorToolbar]="markupEditorToolbar"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-38)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            markupEditorToolbar: [
                ['sharpie', 'Sharpie', { disabled: true }],
                ['eraser', 'Eraser', { disabled: false }],
                [
                    'rectangle',
                    'Rectangle',
                    { disabled: false, icon: '<g></g>', title: 'My Rectangle' },
                ],
            ],
        });
    });
</script>
`

We can use the [createMarkupEditorToolbar](../exports/#createmarkupeditortoolbar) helper function to generate the default toolbar items and make it easier to add our own toolbar items.

If we want to reorder the items but want to retain all default settings we can only use the tool key. In the example below we'll move the Text tool to the first position and have removed the Sharpie and Eraser tools. For more information see the [createMarkupEditorToolbar](../exports/#createmarkupeditortoolbar) docs.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-39)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-39)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-39)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-39)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-39)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-39)

* [index.html](#index-html-panel-39)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import {
        appendDefaultEditor,
        createMarkupEditorToolbar,
    } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        markupEditorToolbar: createMarkupEditorToolbar([
            'text',
            'line',
            'arrow',
            'rectangle',
            'ellipse',
            'preset',
        ]),
    });
</script>
`

* [App.jsx](#App-jsx-panel-39)
* [App.css](#App-css-panel-39)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults, createMarkupEditorToolbar } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                markupEditorToolbar={createMarkupEditorToolbar([
                    'text',
                    'line',
                    'arrow',
                    'rectangle',
                    'ellipse',
                    'preset',
                ])}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-39)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :markupEditorToolbar="markupEditorToolbar"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults, createMarkupEditorToolbar } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            markupEditorToolbar: createMarkupEditorToolbar([
                'text',
                'line',
                'arrow',
                'rectangle',
                'ellipse',
                'preset',
            ]),
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-39)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import {
        getEditorDefaults,
        createMarkupEditorToolbar,
    } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        markupEditorToolbar={createMarkupEditorToolbar([
            'text',
            'line',
            'arrow',
            'rectangle',
            'ellipse',
            'preset',
        ])}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-39)
* [app.component.html](#app-component-html-panel-39)
* [app.component.css](#app-component-css-panel-39)
* [app.module.ts](#app-module-ts-panel-39)

`import { Component } from '@angular/core';

import { getEditorDefaults, createMarkupEditorToolbar } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    markupEditorToolbar: any = createMarkupEditorToolbar([
        'text',
        'line',
        'arrow',
        'rectangle',
        'ellipse',
        'preset',
    ]);
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [markupEditorToolbar]="markupEditorToolbar"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-39)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var { createMarkupEditorToolbar } = $.fn.pintura;

        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            markupEditorToolbar: createMarkupEditorToolbar([
                'text',
                'line',
                'arrow',
                'rectangle',
                'ellipse',
                'preset',
            ]),
        });
    });
</script>
`

The markup editor toolbar also supports tool groups.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-40)

* [index.html](#index-html-panel-40)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        markupEditorToolbar: [
            [
                'Draw',
                [
                    ['sharpie', 'Sharpie', { disabled: true }],
                    ['eraser', 'Eraser', { disabled: false }],
                ],
            ],
            [
                'Shape',
                [
                    ['rectangle', 'Rectangle', { disabled: false }][
                        ('ellipse', 'Ellipse', { disabled: false })
                    ],
                ],
            ],
        ],
    });
</script>
`

* [App.jsx](#App-jsx-panel-40)
* [App.css](#App-css-panel-40)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                markupEditorToolbar={[
                    [
                        'Draw',
                        [
                            ['sharpie', 'Sharpie', { disabled: true }],
                            ['eraser', 'Eraser', { disabled: false }],
                        ],
                    ],
                    [
                        'Shape',
                        [
                            ['rectangle', 'Rectangle', { disabled: false }][
                                ('ellipse', 'Ellipse', { disabled: false })
                            ],
                        ],
                    ],
                ]}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-40)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :markupEditorToolbar="markupEditorToolbar"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            markupEditorToolbar: [
                [
                    'Draw',
                    [
                        ['sharpie', 'Sharpie', { disabled: true }],
                        ['eraser', 'Eraser', { disabled: false }],
                    ],
                ],
                [
                    'Shape',
                    [
                        ['rectangle', 'Rectangle', { disabled: false }][
                            ('ellipse', 'Ellipse', { disabled: false })
                        ],
                    ],
                ],
            ],
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-40)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        markupEditorToolbar={[
            [
                'Draw',
                [
                    ['sharpie', 'Sharpie', { disabled: true }],
                    ['eraser', 'Eraser', { disabled: false }],
                ],
            ],
            [
                'Shape',
                [
                    ['rectangle', 'Rectangle', { disabled: false }][
                        ('ellipse', 'Ellipse', { disabled: false })
                    ],
                ],
            ],
        ]}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-40)
* [app.component.html](#app-component-html-panel-40)
* [app.component.css](#app-component-css-panel-40)
* [app.module.ts](#app-module-ts-panel-40)

`import { Component } from '@angular/core';

import { getEditorDefaults } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    markupEditorToolbar: any = [
        [
            'Draw',
            [
                ['sharpie', 'Sharpie', { disabled: true }],
                ['eraser', 'Eraser', { disabled: false }],
            ],
        ],
        [
            'Shape',
            [
                ['rectangle', 'Rectangle', { disabled: false }][
                    ('ellipse', 'Ellipse', { disabled: false })
                ],
            ],
        ],
    ];
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [markupEditorToolbar]="markupEditorToolbar"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-40)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            markupEditorToolbar: [
                [
                    'Draw',
                    [
                        ['sharpie', 'Sharpie', { disabled: true }],
                        ['eraser', 'Eraser', { disabled: false }],
                    ],
                ],
                [
                    'Shape',
                    [
                        ['rectangle', 'Rectangle', { disabled: false }][
                            ('ellipse', 'Ellipse', { disabled: false })
                        ],
                    ],
                ],
            ],
        });
    });
</script>
`

### markupEditorToolStyles

The `markupEditorToolStyles` property should be set to an object that describes the default styles for each tool. Each key in this object correlates with a tool key in the toolbar array.

We can use the [createMarkupEditorToolStyles](../exports/#createmarkupeditortoolstyles) helper function to create the default tool styles and to make it easier to generate custom style objects.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-41)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-41)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-41)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-41)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-41)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-41)

* [index.html](#index-html-panel-41)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import {
        appendDefaultEditor,
        createDefaultColorOptions,
        createMarkupEditorToolStyle,
        createMarkupEditorToolStyles,
    } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        markupEditorToolStyles: createMarkupEditorToolStyles({
            text: {
                // Increase default font size
                fontSize: '10%',

                // Set default font color to black
                color: createDefaultColorOptions().black,

                // Enable text background color
                backgroundColor: createDefaultColorOptions().transparent,
            },
            rectangle: {
                // Set default color for rectangle background to yellow
                backgroundColor: createDefaultColorOptions().yellow,
            },
        }),
    });
</script>
`

* [App.jsx](#App-jsx-panel-41)
* [App.css](#App-css-panel-41)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import {
    getEditorDefaults,
    createDefaultColorOptions,
    createMarkupEditorToolStyle,
    createMarkupEditorToolStyles,
} from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                markupEditorToolStyles={createMarkupEditorToolStyles({
                    text: {
                        // Increase default font size
                        fontSize: '10%',

                        // Set default font color to black
                        color: createDefaultColorOptions().black,

                        // Enable text background color
                        backgroundColor:
                            createDefaultColorOptions().transparent,
                    },
                    rectangle: {
                        // Set default color for rectangle background to yellow
                        backgroundColor: createDefaultColorOptions().yellow,
                    },
                })}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-41)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :markupEditorToolStyles="markupEditorToolStyles"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import {
    getEditorDefaults,
    createDefaultColorOptions,
    createMarkupEditorToolStyle,
    createMarkupEditorToolStyles,
} from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            markupEditorToolStyles: createMarkupEditorToolStyles({
                text: {
                    // Increase default font size
                    fontSize: '10%',

                    // Set default font color to black
                    color: createDefaultColorOptions().black,

                    // Enable text background color
                    backgroundColor: createDefaultColorOptions().transparent,
                },
                rectangle: {
                    // Set default color for rectangle background to yellow
                    backgroundColor: createDefaultColorOptions().yellow,
                },
            }),
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-41)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import {
        getEditorDefaults,
        createDefaultColorOptions,
        createMarkupEditorToolStyle,
        createMarkupEditorToolStyles,
    } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        markupEditorToolStyles={createMarkupEditorToolStyles({
            text: {
                // Increase default font size
                fontSize: '10%',

                // Set default font color to black
                color: createDefaultColorOptions().black,

                // Enable text background color
                backgroundColor: createDefaultColorOptions().transparent,
            },
            rectangle: {
                // Set default color for rectangle background to yellow
                backgroundColor: createDefaultColorOptions().yellow,
            },
        })}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-41)
* [app.component.html](#app-component-html-panel-41)
* [app.component.css](#app-component-css-panel-41)
* [app.module.ts](#app-module-ts-panel-41)

`import { Component } from '@angular/core';

import {
    getEditorDefaults,
    createDefaultColorOptions,
    createMarkupEditorToolStyle,
    createMarkupEditorToolStyles,
} from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    markupEditorToolStyles: any = createMarkupEditorToolStyles({
        text: {
            // Increase default font size
            fontSize: '10%',

            // Set default font color to black
            color: createDefaultColorOptions().black,

            // Enable text background color
            backgroundColor: createDefaultColorOptions().transparent,
        },
        rectangle: {
            // Set default color for rectangle background to yellow
            backgroundColor: createDefaultColorOptions().yellow,
        },
    });
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [markupEditorToolStyles]="markupEditorToolStyles"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-41)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var {
            createDefaultColorOptions,
            createMarkupEditorToolStyle,
            createMarkupEditorToolStyles,
        } = $.fn.pintura;

        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            markupEditorToolStyles: createMarkupEditorToolStyles({
                text: {
                    // Increase default font size
                    fontSize: '10%',

                    // Set default font color to black
                    color: createDefaultColorOptions().black,

                    // Enable text background color
                    backgroundColor: createDefaultColorOptions().transparent,
                },
                rectangle: {
                    // Set default color for rectangle background to yellow
                    backgroundColor: createDefaultColorOptions().yellow,
                },
            }),
        });
    });
</script>
`

### markupEditorToolRetainStyles

Set `markupEditorToolRetainStyles` to `true` to retain style settings between image editing sessions.

Note that when the editor is destroyed the tool styles are lost, this only works when editing and loading images in the same editor instance.

To retain tool styles accross editing sessions we can read out the current tool styles using the `'selectcontrol'` and `'selectstyle'` events and then set these as default styles using the [markupEditorToolStyles](#markupeditortoolstyles) property.

### markupEditorToolShareStyles

Set to `false` to have each tool retain its own style settings. Defaults to `undefined`.

### markupEditorShapeStyleControls

The `markupEditorShapeStyleControls` contains the definitions for the style controls to which are used to adjust the appearance of an active shape.

Each key in the object correlates with a shape style property. The value of the key is set to the component to render and the parameters to send to the component.

```js
{
    backgroundColor: [
        'ColorPicker',
        {
            enableInput: true,
            enableEyeDropper: true,
        }
    ],
    strokeDash: [
        'Dropdown',
        {
            title: 'Line style',
            options: [
                [undefined, 'Solid'],
                [[20, 20], 'Dashed'],
                [[5, 5], 'Dotted'],
            ],
        },
    ],
    // etc
};
```

Below we use the [createMarkupEditorShapeStyleControls](../exports/#createmarkupeditorshapestylecontrols) helper function to create the default controls.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-43)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-43)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-43)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-43)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-43)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-43)

* [index.html](#index-html-panel-43)

```html
<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import {
        appendDefaultEditor,
        createMarkupEditorShapeStyleControls,
    } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        markupEditorShapeStyleControls: createMarkupEditorShapeStyleControls({
            fontFamilyOptions: [
                ['arial', 'Arial'],
                ['open-sans', 'Open Sans'],
                ['courier', 'Courier'],
            ],
        }),
    });
</script>

```

* [App.jsx](#App-jsx-panel-43)
* [App.css](#App-css-panel-43)

```jsx
import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import {
    getEditorDefaults,
    createMarkupEditorShapeStyleControls,
} from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                markupEditorShapeStyleControls={createMarkupEditorShapeStyleControls(
                    {
                        fontFamilyOptions: [
                            ['arial', 'Arial'],
                            ['open-sans', 'Open Sans'],
                            ['courier', 'Courier'],
                        ],
                    }
                )}
            />
        </div>
    );
}

export default App;

```

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-43)

```html
<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :markupEditorShapeStyleControls="markupEditorShapeStyleControls"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import {
    getEditorDefaults,
    createMarkupEditorShapeStyleControls,
} from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            markupEditorShapeStyleControls:
                createMarkupEditorShapeStyleControls({
                    fontFamilyOptions: [
                        ['arial', 'Arial'],
                        ['open-sans', 'Open Sans'],
                        ['courier', 'Courier'],
                    ],
                }),
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>

```

* [App.svelte](#App-svelte-panel-43)

```svelte
<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import {
        getEditorDefaults,
        createMarkupEditorShapeStyleControls,
    } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        markupEditorShapeStyleControls={createMarkupEditorShapeStyleControls({
            fontFamilyOptions: [
                ['arial', 'Arial'],
                ['open-sans', 'Open Sans'],
                ['courier', 'Courier'],
            ],
        })}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>

```

* [app.component.ts](#app-component-ts-panel-43)
* [app.component.html](#app-component-html-panel-43)
* [app.component.css](#app-component-css-panel-43)
* [app.module.ts](#app-module-ts-panel-43)

```javascript
import { Component } from '@angular/core';

import {
    getEditorDefaults,
    createMarkupEditorShapeStyleControls,
} from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    markupEditorShapeStyleControls: any = createMarkupEditorShapeStyleControls({
        fontFamilyOptions: [
            ['arial', 'Arial'],
            ['open-sans', 'Open Sans'],
            ['courier', 'Courier'],
        ],
    });
}

```

```html
<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [markupEditorShapeStyleControls]="markupEditorShapeStyleControls"
></pintura-editor>

```

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-43)

```html
<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var { createMarkupEditorShapeStyleControls } = $.fn.pintura;

        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            markupEditorShapeStyleControls:
                createMarkupEditorShapeStyleControls({
                    fontFamilyOptions: [
                        ['arial', 'Arial'],
                        ['open-sans', 'Open Sans'],
                        ['courier', 'Courier'],
                    ],
                }),
        });
    });
</script>

```

When we use one of the default editor factories (`openDefaultEditor`, or `getEditorDefaults`) we can pass our shape style controls without calling `createMarkupEditorShapeStyleControls`

```js
openDefaultEditor({
    markupEditorShapeStyleControls: {
        // Disable a control
        strokeColor: undefined,

        // Only extend/overwrite options
        backgroundColor: {
            options: {
                enableInput: true,
                enableEyeDropper: true,
            },
        },

        // Add a custom control for a style property
        // These can also be custom shapePreprocessor style properties
        strokeDash: [
            'Dropdown',
            {
                title: 'Line style',
                options: [
                    [undefined, 'Solid'],
                    [[20, 20], 'Dashed'],
                    [[5, 5], 'Dotted'],
                ],
            },
        ],
    },
});
```

### willRenderShapePresetToolbar

Use to add custom buttons to the markup editor preset toolbar.

The hook receives 4 parameters:

* The list of `nodes` the editor is about to draw.
* The `addPreset` callback to add a shape to the current context.
* The `env` parameter containing the current environment state.
* The `redraw` callback to manually trigger redrawing of the editor UI.

In the example below we create a custom smile button, but this functionality can also be used to import images from third party sources like Dropbox, show modals with custom sticker sources, or open additional editors.

The `willRenderShapePresetToolbar` hook should always return an array of nodes or an empty array.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-45)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-45)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-45)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-45)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-45)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-45)

* [index.html](#index-html-panel-45)

```html
<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor, createNode, appendNode } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        willRenderShapePresetToolbar: (nodes, addPreset) => {
            // create smile button
            const smileButton = createNode('Button', 'smile-button', {
                label: 'Add smile',
                onclick: () => addPreset('😄'),
            });

            // add it to the node tree
            appendNode(smileButton, nodes);

            // return the new node tree
            return nodes;
        },
    });
</script>

```

* [App.jsx](#App-jsx-panel-45)
* [App.css](#App-css-panel-45)

```jsx
import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults, createNode, appendNode } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const willRenderShapePresetToolbar = (nodes, addPreset) => {
        // create smile button
        const smileButton = createNode('Button', 'smile-button', {
            label: 'Add smile',
            onclick: () => addPreset('😄'),
        });

        // add it to the node tree
        appendNode(smileButton, nodes);

        // return the new node tree
        return nodes;
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                willRenderShapePresetToolbar={willRenderShapePresetToolbar}
            />
        </div>
    );
}

export default App;

```

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-45)

```html
<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :willRenderShapePresetToolbar="willRenderShapePresetToolbar"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults, createNode, appendNode } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            willRenderShapePresetToolbar: (nodes, addPreset) => {
                // create smile button
                const smileButton = createNode('Button', 'smile-button', {
                    label: 'Add smile',
                    onclick: () => addPreset('😄'),
                });

                // add it to the node tree
                appendNode(smileButton, nodes);

                // return the new node tree
                return nodes;
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>

```

* [App.svelte](#App-svelte-panel-45)

```svelte
<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults, createNode, appendNode } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const willRenderShapePresetToolbar = (nodes, addPreset) => {
        // create smile button
        const smileButton = createNode('Button', 'smile-button', {
            label: 'Add smile',
            onclick: () => addPreset('😄'),
        });

        // add it to the node tree
        appendNode(smileButton, nodes);

        // return the new node tree
        return nodes;
    };
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        {willRenderShapePresetToolbar}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>

```

* [app.component.ts](#app-component-ts-panel-45)
* [app.component.html](#app-component-html-panel-45)
* [app.component.css](#app-component-css-panel-45)
* [app.module.ts](#app-module-ts-panel-45)

```javascript
import { Component } from '@angular/core';

import {
    getEditorDefaults,
    createNode,
    appendNode,
    PinturaNode,
    Sticker,
} from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    willRenderShapePresetToolbar = (
        nodes: PinturaNode[],
        addPreset: (sticker: Sticker) => void
    ): PinturaNode[] => {
        // create smile button
        const smileButton = createNode('Button', 'smile-button', {
            label: 'Add smile',
            onclick: () => addPreset('😄'),
        });

        // add it to the node tree
        appendNode(smileButton, nodes);

        // return the new node tree
        return nodes;
    };
}

```

```html
<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [willRenderShapePresetToolbar]="willRenderShapePresetToolbar"
></pintura-editor>

```

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-45)

```html
<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var { createNode, appendNode } = $.fn.pintura;

        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            willRenderShapePresetToolbar: (nodes, addPreset) => {
                // create smile button
                const smileButton = createNode('Button', 'smile-button', {
                    label: 'Add smile',
                    onclick: () => addPreset('😄'),
                });

                // add it to the node tree
                appendNode(smileButton, nodes);

                // return the new node tree
                return nodes;
            },
        });
    });
</script>

```

### markupEditorTextInputMode

Set to `'modal'` to offer text editing in a plain text modal instead of `'inline'`.

Please note that `'modal'` doesn't support html text style formatting.

### markupEditorWillStartInteraction

A function that receives the current interaction position and image rectangle, should return `true` if interaction is allowed and `false` if not.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-46)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-46)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-46)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-46)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-46)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-46)

* [index.html](#index-html-panel-46)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        markupEditorWillStartInteraction: (pointerPosition, imageRect) => {
            console.log(
                'markupEditorWillStartInteraction',
                pointerPosition,
                imageRect
            );
            return true;
        },
    });
</script>
`

* [App.jsx](#App-jsx-panel-46)
* [App.css](#App-css-panel-46)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const markupEditorWillStartInteraction = (pointerPosition, imageRect) => {
        console.log(
            'markupEditorWillStartInteraction',
            pointerPosition,
            imageRect
        );
        return true;
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                markupEditorWillStartInteraction={
                    markupEditorWillStartInteraction
                }
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-46)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :markupEditorWillStartInteraction="markupEditorWillStartInteraction"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            markupEditorWillStartInteraction: (pointerPosition, imageRect) => {
                console.log(
                    'markupEditorWillStartInteraction',
                    pointerPosition,
                    imageRect
                );
                return true;
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-46)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const markupEditorWillStartInteraction = (pointerPosition, imageRect) => {
        console.log(
            'markupEditorWillStartInteraction',
            pointerPosition,
            imageRect
        );
        return true;
    };
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        {markupEditorWillStartInteraction}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-46)
* [app.component.html](#app-component-html-panel-46)
* [app.component.css](#app-component-css-panel-46)
* [app.module.ts](#app-module-ts-panel-46)

```javascript
import { Component } from '@angular/core';

import { getEditorDefaults } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    markupEditorWillStartInteraction = (
        pointerPosition: Vector,
        imageRect: Rect
    ): boolean => {
        console.log(
            'markupEditorWillStartInteraction',
            pointerPosition,
            imageRect
        );
        return true;
    };
}

```

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [markupEditorWillStartInteraction]="markupEditorWillStartInteraction"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-46)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            markupEditorWillStartInteraction: (pointerPosition, imageRect) => {
                console.log(
                    'markupEditorWillStartInteraction',
                    pointerPosition,
                    imageRect
                );
                return true;
            },
        });
    });
</script>
`

### markupEditorInteractionMode

Deprecated, use [enablePanInput](../../ui/properties/#enablepaninput) instead.

Set to `'pan'` to force pan mode (spacebar + drag), set to `'auto'` to switch to draw mode.

### markupEditorToolSelectRadius

The radius around a select action to select shapes in, defaults to `0`.

### markupEditorZoomLevels

Deprecated, use [zoomPresetOptions](../../ui/properties/#zoompresetoptions) instead.

An array of zoom levels defined as fractions. Default value is `[0.25, 0.5, 1, 1.25, 1.5, 2, 3, 4, 6, 8, 16]`.

### markupEditorZoomAdjustStep

Deprecated, use [zoomAdjustStep](../../ui/properties/#zoomadjuststep) instead.

The speed at which pressing the zoom buttons increases or decreases zoom. Defaults to `.25`

### markupEditorZoomAdjustFactor

Deprecated, use [zoomAdjustFactor](../../ui/properties/#zoomadjustfactor) instead.

The factor used to increase or decrease zoom speed when holding the zoom buttons. Default value is `.1`, increase speed is `1 + .1`, decrease speed is `1 - .1`.

### enableMultiSelect

When set to `true` enables seleting multiple shapes. Shapes can then be styled and translated simultaneously.

Snapping, resizing, and rotating multiple shapes is currently not supported.

When a shape in the selection is not allowed to be moved (`disableMove` is `true`) the entire selection of shapes will be locked in place.

When a property of a shape in the selection cannot be changed (`disableStyle` is set) the property cannot be styled for other shapes in the collection.

### enableSelectToolToAddShape

When set to `true` the editor will add a shape to the middle of the image when a shape tool is tapped.

### enableTapToAddText

When set to `true` the editor will add an auto-width text shape when the text tool is active and an empty part of the canvas is tapped.

### enableViewTool

When set to `true` a view tool will be added to the tools list, this tool enables dragging the canvas without holding spacebar.

### enableMoveTool

When set to `true` a move tool will be added to the tools list, making it easier to move shapes.

### enableAutoSelectMoveTool

Set to `false` to disable automatically switching back to the move tool, set to `true` to enable auto switch back for all shape tools, set to a list of tool keys to pick which tools have this behaviour. Defaults to `['line', 'arrow', 'rectangle', 'ellipse', 'text']`.

### markupEditorSnapThreshold

The distance in pixels at which shapes snap to grid or other shapes. When set to `0` snapping is disabled.

### markupEditorSnapToContext

If enabled shapes snap to context edges and context center.

Use `annotateSnapToContext` and `decorateSnapToContext` to alter context snapping per util.

### markupEditorGridSize

The size of the grid cells in pixels, when set to `0` the grid is disabled.

Use `annotateGridSize` and `decorateGridSize` to alter the grid size per util.

### beforeSelectShape

Runs before a shape is selected. Return `false` to prevent selecting the shape. Receives `current` selected shape and about to be selected `target` shape.

If `current` is `undefined` it means no shape is currently selected.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-47)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-47)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-47)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-47)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-47)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-47)

* [index.html](#index-html-panel-47)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        beforeSelectShape: (current, target) => {
            console.log('beforeSelectShape', current, target);
            return true;
        },
    });
</script>
`

* [App.jsx](#App-jsx-panel-47)
* [App.css](#App-css-panel-47)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const beforeSelectShape = (current, target) => {
        console.log('beforeSelectShape', current, target);
        return true;
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                beforeSelectShape={beforeSelectShape}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-47)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :beforeSelectShape="beforeSelectShape"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            beforeSelectShape: (current, target) => {
                console.log('beforeSelectShape', current, target);
                return true;
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-47)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const beforeSelectShape = (current, target) => {
        console.log('beforeSelectShape', current, target);
        return true;
    };
</script>

<div>
    <PinturaEditor {...editorDefaults} src={'image.jpeg'} {beforeSelectShape} />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-47)
* [app.component.html](#app-component-html-panel-47)
* [app.component.css](#app-component-css-panel-47)
* [app.module.ts](#app-module-ts-panel-47)

`import { Component } from '@angular/core';

import { getEditorDefaults, Shape } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    beforeSelectShape = (current: Shape, target: Shape): boolean => {
        console.log('beforeSelectShape', current, target);
        return true;
    };
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [beforeSelectShape]="beforeSelectShape"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-47)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            beforeSelectShape: (current, target) => {
                console.log('beforeSelectShape', current, target);
                return true;
            },
        });
    });
</script>
`

We can use the `beforeSelectShape` hook combined with the `removeshape` event to prevent auto selection of the next shape when a shape was removed.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-48)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-48)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-48)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-48)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-48)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-48)

* [index.html](#index-html-panel-48)

```html
<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    let removedShape = undefined;

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        beforeSelectShape: (current) => {
            // if currently selected shape is the shape that was
            // just removed prevent selection of next shape
            return current === removedShape;
        },
    });

    editor.on('removeshape', (shape) => {
        removedShape = shape;
    });
</script>

```

* [App.jsx](#App-jsx-panel-48)
* [App.css](#App-css-panel-48)

```jsx
import '@pqina/pintura/pintura.css';
import './App.css';
import { useState } from 'react';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const [removedShape, setRemovedShape] = useState(undefined);

    const beforeSelectShape = (current) => {
        // if currently selected shape is the shape that was
        // just removed prevent selection of next shape
        return current === removedShape;
    };

    const handleEditorRemoveshape = (shape) => {
        setRemovedShape(shape);
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                beforeSelectShape={beforeSelectShape}
                onRemoveshape={handleEditorRemoveshape}
            />
        </div>
    );
}

export default App;

```

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-48)

```html
<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :beforeSelectShape="beforeSelectShape"
            v-on:pintura:removeshape="handleEditorRemoveshape($event)"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            removedShape: undefined,

            beforeSelectShape: (current) => {
                // if currently selected shape is the shape that was
                // just removed prevent selection of next shape
                return current === this.removedShape;
            },
        };
    },

    methods: {
        handleEditorRemoveshape: function (shape) {
            this.removedShape = shape;
        },
    },
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>

```

* [App.svelte](#App-svelte-panel-48)

```svelte
<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    let removedShape = undefined;

    const beforeSelectShape = (current) => {
        // if currently selected shape is the shape that was
        // just removed prevent selection of next shape
        return current === removedShape;
    };

    const handleEditorRemoveshape = (event) => {
        const shape = event.detail;

        removedShape = shape;
    };
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        {beforeSelectShape}
        on:removeshape={handleEditorRemoveshape}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>

```

* [app.component.ts](#app-component-ts-panel-48)
* [app.component.html](#app-component-html-panel-48)
* [app.component.css](#app-component-css-panel-48)
* [app.module.ts](#app-module-ts-panel-48)

```javascript
import { Component } from '@angular/core';

import { getEditorDefaults, Shape } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    removedShape?: Shape = undefined;

    beforeSelectShape = (current: Shape): boolean => {
        // if currently selected shape is the shape that was
        // just removed prevent selection of next shape
        return current === this.removedShape;
    };

    handleEditorRemoveshape(shape: Shape): void {
        this.removedShape = shape;
    }
}

```

```html
<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [beforeSelectShape]="beforeSelectShape"
    (removeshape)="handleEditorRemoveshape($event)"
></pintura-editor>

```

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-48)

```html
<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var removedShape = undefined;

        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            beforeSelectShape: (current) => {
                // if currently selected shape is the shape that was
                // just removed prevent selection of next shape
                return current === removedShape;
            },
        });

        editor.on('pintura:removeshape', function (event) {
            const shape = event.detail;
            removedShape = shape;
        });
    });
</script>

```

### beforeDeselectShape

Runs before a shape is deselected. Return `false` to prevent deselecting the shape. Receives `current` selected shape and about to be selected `target` shape.

If `target` is `undefined` it means no shape is targetted.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-49)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-49)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-49)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-49)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-49)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-49)

* [index.html](#index-html-panel-49)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        beforeDeselectShape: (current, target) => {
            console.log('beforeDeselectShape', current, target);
            return true;
        },
    });
</script>
`

* [App.jsx](#App-jsx-panel-49)
* [App.css](#App-css-panel-49)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const beforeDeselectShape = (current, target) => {
        console.log('beforeDeselectShape', current, target);
        return true;
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                beforeDeselectShape={beforeDeselectShape}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-49)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :beforeDeselectShape="beforeDeselectShape"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            beforeDeselectShape: (current, target) => {
                console.log('beforeDeselectShape', current, target);
                return true;
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-49)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const beforeDeselectShape = (current, target) => {
        console.log('beforeDeselectShape', current, target);
        return true;
    };
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        {beforeDeselectShape}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-49)
* [app.component.html](#app-component-html-panel-49)
* [app.component.css](#app-component-css-panel-49)
* [app.module.ts](#app-module-ts-panel-49)

`import { Component } from '@angular/core';

import { getEditorDefaults, Shape } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    beforeDeselectShape = (current: Shape, target: Shape): boolean => {
        console.log('beforeDeselectShape', current, target);
        return true;
    };
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [beforeDeselectShape]="beforeDeselectShape"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-49)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            beforeDeselectShape: (current, target) => {
                console.log('beforeDeselectShape', current, target);
                return true;
            },
        });
    });
</script>
`

### beforeAddShape

Runs before a shape preset is added. Return `false` to prevent adding the shape.

Instead of using this hook, consider instead disabling the [shape tools](../../markup-editor/properties/#markupeditortoolbar) and [sticker](../../markup-editor/stickers/#configuration-object) items using the `disabled` property.

This hook only runs when adding shape presets / stickers.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-50)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-50)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-50)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-50)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-50)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-50)

* [index.html](#index-html-panel-50)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        beforeAddShape: (shape) => {
            console.log('beforeAddShape', shape);
            return true;
        },
    });
</script>
`

* [App.jsx](#App-jsx-panel-50)
* [App.css](#App-css-panel-50)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const beforeAddShape = (shape) => {
        console.log('beforeAddShape', shape);
        return true;
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                beforeAddShape={beforeAddShape}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-50)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :beforeAddShape="beforeAddShape"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            beforeAddShape: (shape) => {
                console.log('beforeAddShape', shape);
                return true;
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-50)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const beforeAddShape = (shape) => {
        console.log('beforeAddShape', shape);
        return true;
    };
</script>

<div>
    <PinturaEditor {...editorDefaults} src={'image.jpeg'} {beforeAddShape} />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-50)
* [app.component.html](#app-component-html-panel-50)
* [app.component.css](#app-component-css-panel-50)
* [app.module.ts](#app-module-ts-panel-50)

`import { Component } from '@angular/core';

import { getEditorDefaults, Shape } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    beforeAddShape = (shape: Shape): boolean => {
        console.log('beforeAddShape', shape);
        return true;
    };
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [beforeAddShape]="beforeAddShape"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-50)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            beforeAddShape: (shape) => {
                console.log('beforeAddShape', shape);
                return true;
            },
        });
    });
</script>
`

### beforeRemoveShape

Runs before a shape is removed.

Return `false` to prevent removal of a shape.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-51)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-51)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-51)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-51)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-51)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-51)

* [index.html](#index-html-panel-51)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        beforeRemoveShape: (shape) => {
            console.log('beforeRemoveShape', shape);
            return true;
        },
    });
</script>
`

* [App.jsx](#App-jsx-panel-51)
* [App.css](#App-css-panel-51)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const beforeRemoveShape = (shape) => {
        console.log('beforeRemoveShape', shape);
        return true;
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                beforeRemoveShape={beforeRemoveShape}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-51)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :beforeRemoveShape="beforeRemoveShape"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            beforeRemoveShape: (shape) => {
                console.log('beforeRemoveShape', shape);
                return true;
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-51)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const beforeRemoveShape = (shape) => {
        console.log('beforeRemoveShape', shape);
        return true;
    };
</script>

<div>
    <PinturaEditor {...editorDefaults} src={'image.jpeg'} {beforeRemoveShape} />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-51)
* [app.component.html](#app-component-html-panel-51)
* [app.component.css](#app-component-css-panel-51)
* [app.module.ts](#app-module-ts-panel-51)

`import { Component } from '@angular/core';

import { getEditorDefaults, Shape } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    beforeRemoveShape = (shape: Shape): boolean => {
        console.log('beforeRemoveShape', shape);
        return true;
    };
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [beforeRemoveShape]="beforeRemoveShape"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-51)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            beforeRemoveShape: (shape) => {
                console.log('beforeRemoveShape', shape);
                return true;
            },
        });
    });
</script>
`

### beforeUpdateShape

Runs before a shape is updated.

Return adjusted `props` to make changes to shape update.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-52)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-52)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-52)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-52)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-52)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-52)

* [index.html](#index-html-panel-52)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        beforeUpdateShape: (shape, props, context) => {
            console.log('beforeUpdateShape', shape, props, context);
            return props;
        },
    });
</script>
`

* [App.jsx](#App-jsx-panel-52)
* [App.css](#App-css-panel-52)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const beforeUpdateShape = (shape, props, context) => {
        console.log('beforeUpdateShape', shape, props, context);
        return props;
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                beforeUpdateShape={beforeUpdateShape}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-52)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :beforeUpdateShape="beforeUpdateShape"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            beforeUpdateShape: (shape, props, context) => {
                console.log('beforeUpdateShape', shape, props, context);
                return props;
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-52)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const beforeUpdateShape = (shape, props, context) => {
        console.log('beforeUpdateShape', shape, props, context);
        return props;
    };
</script>

<div>
    <PinturaEditor {...editorDefaults} src={'image.jpeg'} {beforeUpdateShape} />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-52)
* [app.component.html](#app-component-html-panel-52)
* [app.component.css](#app-component-css-panel-52)
* [app.module.ts](#app-module-ts-panel-52)

`import { Component } from '@angular/core';

import { getEditorDefaults, Shape } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    beforeUpdateShape = (shape: Shape, props: any, context: Rect): any => {
        console.log('beforeUpdateShape', shape, props, context);
        return props;
    };
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [beforeUpdateShape]="beforeUpdateShape"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-52)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            beforeUpdateShape: (shape, props, context) => {
                console.log('beforeUpdateShape', shape, props, context);
                return props;
            },
        });
    });
</script>
`

### willRenderShapeControls

Runs before the shape controls popup is rendered above a selected shape. Allows manipulating the shape controls popup element tree.

The `willRenderShapeControls` hook receives the current structure of the shape controls popup. The hook allows injecting custom controls into the toolbar using the [createNode](../../ui/exports/#createnode) helper function.

The `willRenderShapeControls` hook should always return an array. If the returned array is empty the controls are hidden.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-53)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-53)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-53)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-53)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-53)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-53)

* [index.html](#index-html-panel-53)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        willRenderShapeControls: (controls, selectedShapeId) => {
            console.log('willRenderShapeControls', selectedShapeId);

            // Manipulate or add controls here

            return controls;
        },
    });
</script>
`

* [App.jsx](#App-jsx-panel-53)
* [App.css](#App-css-panel-53)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const willRenderShapeControls = (controls, selectedShapeId) => {
        console.log('willRenderShapeControls', selectedShapeId);

        // Manipulate or add controls here

        return controls;
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                willRenderShapeControls={willRenderShapeControls}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-53)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :willRenderShapeControls="willRenderShapeControls"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            willRenderShapeControls: (controls, selectedShapeId) => {
                console.log('willRenderShapeControls', selectedShapeId);

                // Manipulate or add controls here

                return controls;
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-53)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const willRenderShapeControls = (controls, selectedShapeId) => {
        console.log('willRenderShapeControls', selectedShapeId);

        // Manipulate or add controls here

        return controls;
    };
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        {willRenderShapeControls}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-53)
* [app.component.html](#app-component-html-panel-53)
* [app.component.css](#app-component-css-panel-53)
* [app.module.ts](#app-module-ts-panel-53)

```javascript
import { Component } from '@angular/core';

import { getEditorDefaults, PinturaNode } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    willRenderShapeControls = (
        controls: PinturaNode[],
        selectedShapeId: string
    ): PinturaNode[] => {
        console.log('willRenderShapeControls', selectedShapeId);

        // Manipulate or add controls here

        return controls;
    };
}

```

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [willRenderShapeControls]="willRenderShapeControls"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-53)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            willRenderShapeControls: (controls, selectedShapeId) => {
                console.log('willRenderShapeControls', selectedShapeId);

                // Manipulate or add controls here

                return controls;
            },
        });
    });
</script>
`