v8.38.0

Interface properties

A list of properties to read from and write to the current state of the editor UI.

Editor properties

These read only properties are available on the editor instance.

Property Description
element The root element of the editor.
history Used to access history state. See history methods for more information.

These read/write properties are available on the editor instance.

Property Default value Description
id
undefined
The id attribute set to the editor root element.
class
undefined
The class attribute set to the editor root element.
locale
undefined
The locale object to use for the editor labels.
utils
undefined
The enabled utils and their order in the menu.
util
undefined
The active util, is automatically set to first util in utils array.
layoutDirectionPreference
'auto'
The direction preference of the editor layout, when is 'auto' the editor will automatically set it to 'vertical' for when the editor root is in portrait aspect ratio and 'horizontal' for landscape aspect ratio.
layoutHorizontalUtilsPreference
'left'
The horizontal location of the utils menu, set to either 'left' or 'right' to move the main navigation to the that side of the image preview.
layoutVerticalUtilsPreference
'bottom'
The vertical location of the utils menu, set to either 'bottom' or 'top' to move the main navigation to the that side of the image preview. Will not affect mobile presentation where the menu will always stick to the bottom.
animations
'auto'
Control if and when animations are shown.
disabled
false
Set to true to disable any interaction with the editor.
status
undefined
Set to a string to show a status message.
elasticityMultiplier
10
Controls the elasticity force of the interface.
previewUpscale
false
Should the image preview be upscaled to fit the editor stage.
previewPad
false
Should the image preview add padding around the image when a frame is rendered on the outside of the image bounds.
previewMaskOpacity
.95
The opacity of the overlay applied to frames when rendered outside of the image bounds.
previewImageData
undefined
The current data used for the image preview. Can be an ImageBitmap, ImageData, or HTMLCanvasElement. Available after 'loadpreview' event.
previewImageDataMaxSize
undefined
Maximum texture size to use for the preview image. Will default to browser max texture size.
previewImageTextPixelRatio
undefined
The pixel density to use for rendering text shapes, will default to window.devicePixelRatio
imageSourceToImageData
undefined
The function the editor uses to read preview image data.
enableToolbar
true
Set to false to disable the toolbar.
enableUtils
true
Set to false to disable the util tabs.
enableButtonClose
false
Set to true to show a close button, automatically set to true when using openModal.
enableButtonExport
true
Set to false to disable the export button.
enableButtonRevert
true
Set to false to disable the history revert button.
enableNavigateHistory
true
Set to false to disable the undo and redo buttons.
enableDropImage
false
Set to true to allow loading a new image by dropping it on the editor.
enablePasteImage
false
Set to true to allow pasting a new image. Editor will accept a pasted image if it's at least 75% in view.
enableBrowseImage
false
Set to true to allow clicking the editor to browse for an image when the editor is in "waiting for image" state.
handleEvent
undefined
A function that is called for each event. Receives event type and detail.
willRenderCanvas
undefined
Inject shapes or adjust shapes in the image preview.
willRenderToolbar
undefined
Inject custom buttons into the editor toolbar.
willClose
undefined
Prevent close action from user. Only available when using modal.
willRevert
undefined
Prevent revert action from user.
willProcessImage
undefined
Prevent image processing action from user.
willRequest
undefined
Called before requesting a resource.
willRequestResource
undefined
Called before requesting a remote resource. Deprecated use willRequest instead.
willSetHistoryInitialState
undefined
Receives initial history state that is about to be set, return modified state.

locale

When not using one of the default factories the editor requires the locale property to be set to a valid locale object.

In the example below we assign the core editor locale and the crop plugin locale object.

<!DOCTYPE html>

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

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

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

<script type="module">
    import {
        appendEditor,
        createDefaultImageReader,
        createDefaultImageWriter,
        createDefaultImageOrienter,
        setPlugins,
        plugin_crop,
        locale_en_gb,
        plugin_crop_locale_en_gb,
    } from './pintura.js';

    setPlugins(plugin_crop);

    const editor = appendEditor('#editor', {
        imageReader: createDefaultImageReader(),
        imageWriter: createDefaultImageWriter(),
        imageOrienter: createDefaultImageOrienter(),
        locale: {
            ...locale_en_gb,
            ...plugin_crop_locale_en_gb,
        },
        src: 'image.jpeg',
    });
</script>

See below for example content of the locale_en_gb object exported by the editor module.

{
    labelDefault: 'Default',
    labelReset: 'Reset',
    labelAuto: 'Auto',
    labelNone: 'None',
    labelEdit: 'Edit',
    labelClose: 'Close',

    // etc...
}

To change a label we can update one of the properties in the locale object.

// Merge the locale objects
const myLocale = {
    ...locale_en_gb,
    ...plugin_crop_locale_en_gb,
};

// Change label of export button to 'Save'
myLocale.labelButtonExport = 'Save';

When we're using one of the default factories we can set the label directly on the locale property.

<!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',
        locale: { labelButtonExport: 'Save' },
    });
</script>

The code below logs all locale properties to the developer console so we can easily see which property to edit if we need to change labels or icons.

import {
    // core locale
    locale_en_gb,

    // plugin locale
    plugin_crop_locale_en_gb,
    plugin_finetune_locale_en_gb,
    plugin_filter_locale_en_gb,
    plugin_annotate_locale_en_gb,
    plugin_decorate_locale_en_gb,
    plugin_redact_locale_en_gb,
    plugin_resize_locale_en_gb,
    plugin_sticker_locale_en_gb,
    plugin_frame_locale_en_gb,

    // markup editor locale
    markup_editor_locale_en_gb,
} from './pintura.js';

// log merged objects to console
console.log({
    ...locale_en_gb,
    ...plugin_crop_locale_en_gb,
    ...plugin_finetune_locale_en_gb,
    ...plugin_filter_locale_en_gb,
    ...plugin_annotate_locale_en_gb,
    ...plugin_decorate_locale_en_gb,
    ...plugin_resize_locale_en_gb,
    ...plugin_sticker_locale_en_gb,
    ...markup_editor_locale_en_gb,
});

The product package includes additional locale files for other languages.

To load one of the other locales, copy the package locale folder to your project directory and import the locale like shown below.

import { openEditor } from './pintura.js';

import locale_de_DE from './locale/de_DE/core/de_DE.js';
import locale_annotate_de_DE from './locale/de_DE/annotate/de_DE.js';

openEditor({
    src: 'my-image.jpeg',
    locale: {
        ...locale_de_DE,
        ...locale_annotate_de_DE,
    },
});

util

Updates the current active util and will trigger the editor to show the corresponding view.

<!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',
        util: 'finetune',
    });
</script>

utils

Use to set which utils are shown and in what order they appear in the editor menu.

<!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',
        utils: [
            'crop',
            'filter',
            'finetune',
            'annotate',
            'decorate',
            'sticker',
            'frame',
            'redact',
            'resize',
        ],
    });
</script>

animations

Toggle if and when the editor runs animations.

'auto'
Will enable animations if user hasn't specified prefers reduced motion in system settings.
'never'
Disables all animations.
'always'
Will set the editor to ignore user preferences and always run animations.

status

Set to a string to show a custom status message.

<!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' });

    editor.on('load', () => {
        editor.status = 'Doing something...';
    });
</script>

Pass a number between 0 and 1 as second argument to show and update a progress indicator. Pass Infinity to show a spinning progress indicator.

<!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' });

    editor.on('load', () => {
        editor.status = ['Busy bee', Infinity];
    });
</script>

Set second argument to false to switch to error state.

<!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' });

    editor.on('load', () => {
        editor.status = ['Something went wrong', false];
    });
</script>

Pass function as third argument to handle click on error state close button.

<!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' });

    editor.on('load', () => {
        editor.status = [
            'Something went wrong',
            false,
            () => {
                /* clicked close button */
            },
        ];
    });
</script>

previewUpscale

If set to true the preview image will be scaled to fit the editor stage.

If false the preview image will only be scaled down to fit the stage, if the preview image is smaller than the stage it will not be upscaled.

This only affects the preview of the image in the editor, this won't affect the size of the output image.

previewImageDataMaxSize

Set to an object with a width and height value. Pintura will scale down the preview image (respecting the image aspect ratio) to fit the defined size.

<!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',
        previewImageDataMaxSize: { width: 1024, height: 1024 },
    });
</script>

imageSourceToImageData

A helper method to correctly read custom preview image data.

The image formats that Pintura Image Editor can read and write depend on which images are supported by the clients browser. In general these image types are supported by all major browsers.

  • image/gif
  • image/png
  • image/jpeg
  • image/webp
  • image/bmp
  • image/svg

If we want to be able to read additional image formats (for example HEIC/HEIF) inside the editor we can supply our own image reader using the imageSourceToImageData property.

Please note that this function is used for all image resources inside the editor, if we only need to load additional image formats for editing it's better to set the preprocessImageFile hook of the imageReader property.

<!DOCTYPE html>

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

<button type="button" id="buttonOpenEditor">Open editor</button>

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

    const buttonOpenEditor = document.querySelector('#buttonOpenEditor');

    buttonOpenEditor.addEventListener('click', () => {
        const editor = openDefaultEditor({
            src: 'image.jpeg',
            imageSourceToImageData: (src) => {
                return fetch(src)
                    .then((res) => res.blob())
                    .then(
                        (blob) =>
                            new Promise((resolve, reject) => {
                                // Turn blob into image data here

                                // resolve with ImageData object
                                resolve(imageData);
                            })
                    );
            },
        });
    });
</script>

handleEvent

Set to a function to route events. The handleEvent callback runs for each public event the editor dispatches, it receives the event type and detail.

<!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',
        handleEvent: (type, detail) => {
            // Log all editor events to console
            console.log(type, detail);
        },
    });
</script>

willClose

Set to an async method.

Resolve with false to prevent closing the modal, resolve with true to continue closing the modal.

<!DOCTYPE html>

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

<button type="button" id="buttonOpenEditor">Open editor</button>

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

    const buttonOpenEditor = document.querySelector('#buttonOpenEditor');

    buttonOpenEditor.addEventListener('click', () => {
        const editor = openDefaultEditor({
            src: 'image.jpeg',
            willClose: async () => {
                // return false to prevent closing modal
                return false;
            },
        });
    });
</script>

willRevert

Set to an async method.

Resolve with false to prevent the revert of all user actions, resolve with true to revert the editor to the initial state.

<!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',
        willRevert: async () => {
            // return false to prevent revert action
            return false;
        },
    });
</script>

willProcessImage

Set to an async method.

Resolve with false to prevent the image processing action, resolve with true to continue processing the image.

<!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',
        willProcessImage: async () => {
            // return false to prevent image processing action
            return false;
        },
    });
</script>

Optionally use the status property to update the editor status text.

<!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',
        willProcessImage: async () => {
            // show a status message
            editor.status = 'waiting for user input';

            // wait for a second before showing dialog
            await new Promise((r) => setTimeout(r, 1000));

            // show some sort of dialog to request user input
            const shouldProcess = confirm('Should we process the image?');

            // hide the status after we got user input
            editor.status = undefined;

            // ready to process?
            return shouldProcess;
        },
    });
</script>

willRequest

Use to alter request objects or prevent requests. Requests include images like the main images and images used to render shapes, additionally the editor loads stylesheets to determine font resources.

Receives request url and request info object.

<!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',
        willRequest: (url, info) => {
            const { resourceType } = info;

            // add custom request header to image requests
            if (resourceType === 'image') {
                return {
                    headers: {
                        myRequestHeader: 'Hello World',
                    },
                };
            }

            // only load stylesheets if is absolute URL to pqina.nl
            if (resourceType === 'stylesheet' && !url.includes('pqina.nl')) {
                return false;
            }

            // don't alter other requests
        },
    });
</script>

willRequestResource

Deprecated, use willRequest instead.

Use to prevent loading remote resources. Receives remote stylesheet URL, return false to prevent loading the resource.

willRenderCanvas

We can use the willRenderCanvas hook to alter what Pintura Image Editor renders to the screen.

The willRenderCanvas hook receives two parameters, the shapes that are about to be drawn, and the current state.

Example draw state object.

{
    // is user currently interacting
    isInteracting: false,

    // will animate from 0 to 1 when interacting
    isInteractingFraction: 0,

    // opacity of the image from 0 to 1
    opacity: 1,

    // rotation of image
    rotation: {
        x: 0,
        y: 0,
        z: 0,
    },

    // scale of image
    scale: 0.615625,

    // size of canvas
    size: {
        width: 1040,
        height: 510,
    },

    // foreground color of canvas
    foregroundColor: [0, 0, 0],

    // background color of canvas
    backgroundColor: [1, 1, 1],

    // line color used in canvas
    lineColor: [0, 0, 0],

    // rectangle of editor root
    rootRect: {
        x: 0,
        y: 0,
        width: 1040,
        height: 510,
    },

    // rectangle of crop selection
    selectionRect: {
        x: 322,
        y: 60,
        height: 394,
        width: 522,
    },

    // rectangle of util
    stageRect: {
        x: 144,
        y: 60,
        width: 880,
        height: 394,
    },

    // opacity of each util, from 0 to 1
    utilVisibility: {
        annotate: 0,
        crop: 1,
        decorate: 0,
        filter: 0,
        finetune: 0,
        resize: 0,
        sticker: 0,
    },
};

Example shapes object.

{
    // these are drawn relative to the preview image
    annotationShapes: [
        {
            backgroundColor: [0, 1, 1],
            cornerRadius: 0,
            disableErase: true,
            height: 200,
            id: 'dgyf5b4cu',
            opacity: 1,
            rotation: 0,
            strokeColor: [0, 0, 0],
            strokeWidth: 0,
            width: 200,
            x: 20,
            y: 20,
        },
    ],

    // these are drawn relative to the crop selection
    decorationShapes: [],

    // these are drawn on top of the user interface
    interfaceShapes: [
        {
            id: 'image-selection-guide-row-0',
            opacity: 1,
            points: [
                { x: 322.475, y: 60 },
                { x: 844.525, y: 60 },
            ],
            strokeColor: [0, 0, 0],
            strokeWidth: 1,
        },
        // ...and some more shapes
    ],
};

In the snippet below we draw a circular overlay on top of the crop selection, see crop overlay example for a live preview.

<!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',
        willRenderCanvas: (shapes, state) => {
            const {
                utilVisibility,
                selectionRect,
                backgroundColor,
                lineColor,
            } = state;

            // exit if crop utils is not visible
            if (utilVisibility.crop <= 0) return shapes;

            // shortcuts to selection rect
            const { x, y, width, height } = selectionRect;

            // return updated shapes
            return {
                // copy props from shapes param
                ...shapes,

                // add an 'ellipse' shape
                interfaceShapes: [
                    {
                        x: x + width * 0.5,
                        y: y + height * 0.5,
                        rx: width * 0.5,
                        ry: height * 0.5,
                        opacity: utilVisibility.crop,
                        inverted: true,
                        backgroundColor: [...backgroundColor, 0.5],
                        strokeWidth: 1,
                        strokeColor: [...lineColor],
                    },
                    ...shapes.interfaceShapes,
                ],
            };
        },
    });
</script>

willRenderToolbar

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

The willRenderToolbar hook receives the current toolbar definition and editor environment parameters. The hook allows injecting custom controls into the toolbar using the createNode helper function.

The willRenderToolbar hook should always return an array. If the returned array is empty the toolbar is hidden.

<!DOCTYPE html>

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

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

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

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

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        willRenderToolbar: (toolbar, env, redraw) => {
            console.log(toolbar);
            // logs: [ Array(4), Array(4), Array(4) ]

            console.log(env);
            // logs: { orientation: "landscape", verticalSpace: "short", … }

            // call redraw to trigger a redraw of the editor state

            // insert your item
            return [
                createNode('div', 'my-div', { textContent: 'Hello world' }),
                ...toolbar,
            ];
        },
    });
</script>

Additional to the default editor properties these read only properties are available on an editor instance opened with openEditor or openDefaultEditor.

Property Description
modal The root element of the modal. Only available when the editor was created with the openEditor method.

Additional to the default editor properties these read/write properties are available on an editor instance opened with openEditor or openDefaultEditor.

Property Default value Description
enableAutoDestroy
true
Set to false to prevent the modal from cleaning up its HTML elements after hiding.
enableAutoHide
true
Set to false to prevent the modal from automatically hiding after processing an image.
preventScrollBodyIfNeeded
true
Set to false to prevent adding iOS document lock. Isn't needed in mobile app context.
preventFooterOverlapIfNeeded
true
Set to false to prevent adding iOS footer spacing. Isn't needed in mobile app context.

A reference to the modal wrapping the editor. This property is only available when the editor is created with openEditor.