v8.38.0

Markup Editor Properties

A list of properties available to configure the markup editor.

Property Default value Description
markupEditorToolbar
undefined
An array of tools to render in the Markup Editor toolbar.
markupEditorToolStyles
undefined
The default shape style definitions to use for each tool in the toolbar.
markupEditorShapeStyleControls
undefined
The style control options available to change the appearance of shapes.
markupEditorTextInputMode
'inline'
Set to 'modal' to offer text editing in a plain text modal instead of inline.
markupEditorInteractionMode
'auto'
Set to 'pan' to force pan mode (spacebar + drag), set back to 'auto' to switch to draw mode.
markupEditorToolSelectRadius
0
The radius around a select action to select shapes in.
markupEditorWillStartInteraction
undefined
A function that receives the current interaction position and image rectangle, should return true if interaction is allowed and false if not.
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
.25
The speed at which pressing the zoom buttons increases or decreases zoom.
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.
enablePan
true
Set to false to disable the panning the image.
enableZoom
true
Set to false to disable the zooming the image.
enableZoomControls
true
Set to false to disable the zoom controls.
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
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
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
false
When set to true a move tool will be added to the tools list, making it easier to move shapes.
enableAutoSelectMoveTool
['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.
beforeSelectShape
undefined
Set to a function that runs before selecting a shape. Receives previously selected shape an targetted shape.
beforeDeselectShape
undefined
Set to a function that runs before deselecting a shape. Receives currently selected shape and targetted shape.
beforeAddShape
undefined
Set to a function that runs before adding a preset shape. Receives shape that is going to be added.
beforeRemoveShape
undefined
Set to a function that runs before removing a shape. Receives shape that is going to be removed. Return true
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
undefined
Can be set to a function to modify the markup editor preset toolbar.
willRenderShapeControls
undefined
Allows to inject custom shape controls, or edit the shape 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.
'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.

<!DOCTYPE html>

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

<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 }],
        ],
    });
</script>

We can use the 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 docs.

<!DOCTYPE html>

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

<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>

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 createMarkupEditorToolStyle and createMarkupEditorToolStyles helper function to set the default tool styles and to make it easier to generate custom style objects.

<!DOCTYPE html>

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

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

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

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

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        markupEditorToolStyles: createMarkupEditorToolStyles({
            // create the text tool style and override fontSize property
            text: createMarkupEditorToolStyle('text', {
                fontSize: '10%',
            }),
        }),
    });
</script>

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.

{
    backgroundColor: [
        ColorPicker,
        {
            // settings
        },
    ],
    fontFamily: [
        Dropdown,
        {
            // settings
        },
    ],
    // etc
};

Below we use the createMarkupEditorShapeStyleControls helper function to create the default controls.

<!DOCTYPE html>

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

<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>

willRenderShapePresetToolbar

This is an experimental feature, the API isn't final yet and might be changed in a future release.

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.

<!DOCTYPE html>

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

<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>

markupEditorTextInputMode

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

markupEditorInteractionMode

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

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

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

markupEditorZoomAdjustFactor

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.

enablePan

Set to false to disable panning the image in the markup editor.

enableZoom

Set to false to disable zooming the image in the markup editor.

enableZoomControls

Set to false to disable the zoom controls. true

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'].

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.

<!DOCTYPE html>

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

<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>

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

<!DOCTYPE html>

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

<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>

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.

<!DOCTYPE html>

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

<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>

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 and sticker items using the disabled property.

This hook only runs when adding shape presets / stickers.

<!DOCTYPE html>

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

<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>

beforeRemoveShape

Runs before a shape is removed.

Return false to prevent removal of a shape.

<!DOCTYPE html>

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

<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>

beforeUpdateShape

Runs before a shape is updated.

Return adjusted props to make changes to shape update.

<!DOCTYPE html>

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

<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>

willRenderShapeControls

This is an experimental feature, the API isn't final yet and might be changed in a future release.

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 helper function.

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

<!DOCTYPE html>

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

<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>