This is the archived documentation for Doka Image Editor v7.
Please visit pqina.nl/pintura/docs/ to see documentation for the latest version of Pintura Image Editor.
Editor properties
Doka Image Editor exposes a set of properties that enable us to update the editor state.
Editor properties
These read only properties are available on the editor instance.
Property | Default value | Description |
---|---|---|
element |
|
The root element of the editor. |
modal |
|
The root element of the modal. Only available when the editor was created with the openEditor method.
|
These read/write properties are available on the editor instance.
Property | Default value | Description |
---|---|---|
id |
|
The id attribute set to the editor root element.
|
class |
|
The class attribute set to the editor root element.
|
src |
|
The image source to load, can be of type File , Blob , DataURL , URL , HTMLCanvasElement , or HTMLImageElement .
|
locale |
|
The locale object to use for the editor labels. |
utils |
|
The enabled utils and their order in the menu. |
util |
|
The active util, is automatically set to first util in utils array.
|
layoutDirectionPreference |
|
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.
|
animations |
|
Control if and when animations are shown. |
elasticityMultiplier |
|
Controls the elasticity force of the interface. |
previewUpscale |
|
Should the image preview be upscaled to fit the editor stage. |
previewImageDataMaxSize |
|
Maximum texture size to use for the preview image. Will default to browser max texture size. |
imageSourceToImageData |
|
The function to use for preview reading image data. |
imageOrienter |
|
The object to use to correctly orient preview image data. |
imageReader |
|
The imageReader to use for reading image data.
|
imageWriter |
|
The imageWriter to use for writing image data.
|
enableToolbar |
|
Set to false to disable the toolbar.
|
enableUtils |
|
Set to false to disable the util tabs.
|
enableButtonClose |
|
Set to true to show a close button, automatically set to true when using openModal .
|
enableButtonExport |
|
Set to false to disable the export button.
|
enableButtonRevert |
|
Set to false to disable the history revert button.
|
enableNavigateHistory |
|
Set to false to disable the undo and redo buttons.
|
enableDropImage |
|
Set to true to allow loading a new image by dropping it on the editor.
|
handleEvent |
|
A function that is called for each event. Receives event type and detail. |
willRenderCanvas |
|
Inject shapes or adjust shapes in the image preview. |
willRenderToolbar |
|
Inject custom buttons into the editor toolbar. |
willRevert |
|
Prevent revert action. |
src
The source image to load. Update to load a new image.
Accepts:
File
Blob
DataURL
URL
HTMLCanvasElement
HTMLImageElement
Due to browser security restrictions loading remote URLs is only possible if the remote location has properly configured CORS headers.
import { openEditor } from './doka.js';
openEditor({
src: './my-image.jpeg',
});
locale
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.
import { openEditor, locale_en_gb, plugin_crop_locale_en_gb } from 'doka.js';
// Merge the locale objects
const myLocale = {
...locale_en_gb,
...plugin_crop_locale_en_gb,
};
// Assign locale to editor
openEditor({
src: 'my-image.jpeg',
locale: myLocale,
});
See below for an example 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';
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_resize_locale_en_gb,
plugin_sticker_locale_en_gb,
// markup editor locale
markup_editor_locale_en_gb,
} from './doka.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,
});
modal
A reference to the modal wrapping the editor. This property is only available when the editor is created with openEditor
.
util
Updates the current active util and will trigger the editor to show the corresponding view.
doka.util = 'finetune';
utils
Use to set which utils are shown and in what order they appear in the editor menu.
doka.utils = ['crop', 'filter', 'finetune'];
animations
Toggle if and when the editor runs animations.
|
Will enable animations if user hasn't specified prefers reduced motion in system settings. |
---|---|
|
Disables all animations. |
|
Will set the editor to ignore user preferences and always run animations. |
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.
imageSourceToImageData
A helper method to correctly read custom preview image data.
The image formats that Doka 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.
const app = openEditor({
// Custom imageSourceToImageData method
imageSourceToImageData: (src) =>
fetch(src)
.then((res) => res.blob())
.then((blob) => {
return new Promise((resolve, reject) => {
// Turn blob into image data here
// resolve with ImageData object
resolve(imageData);
});
}),
});
imageOrienter
Can be set to a helper object to correctly orient image data. This is useful for older browsers where interpretation of the EXIF orientation header is done incorrectly and images appear upside down or mirrored.
The property expects an object with an read
and an apply
function.
- The
read
function is used to read the EXIF orientation header from the image preview data. - The
apply
function is used to apply the EXIF orientation header to the image preview.
We can import the createDefaultImageOrienter
method and use it to set the imageOrienter
property to automatically orient images.
import { createDefaultImageOrienter } from './doka.js';
const app = openEditor({
imageOrienter: createDefaultImageOrienter(),
});
imageReader
Expects an array of read steps to step through when reading the src
input image data.
We can import the createDefaultImageReader
method and use it to set the imageReader
property to read preview images.
import { openEditor, createDefaultImageReader } from './doka.js';
openEditor({
imageReader: createDefaultImageReader(),
});
The imageReader
property has to be set for the editor to be able to show image previews, without it the editor won't run.
imageWriter
Expects an array of write steps to step through when writing the output image data.
We can import the createDefaultImageWriter
method and use it to set the imageWriter
property to write output images.
import { openEditor, createDefaultImageWriter } from './doka.js';
openEditor({
imageWriter: createDefaultImageWriter(),
});
If we don't need to output image data, for example when we're only storing the original image and the editor state, we don't have to set the imageWriter
property.
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.
import { openEditor } from './doka.js';
openEditor({
handleEvent: (type, detail) => {
// log all editor events to console
console.log(type, detail);
},
});
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.
import { openEditor } from './doka.js';
openEditor({
willRevert: () =>
new Promise((resolve) => {
/* determine if should revert */
resolve(false); // false will cancel revert action
}),
});
willRenderCanvas
We can use the willRenderCanvas
hook to alter what Doka 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.
import { openEditor } from './doka.js';
openEditor({
// this method is synchronouse,
// it's called before each render
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,
],
};
},
});
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.
The method should always return the received toolbar
. If an empty array is returned the toolbar is hidden.
import { openEditor } from './doka.js';
openEditor({
willRenderToolbar: (toolbar, env, redraw) => {
console.log(toolbar);
// logs: [ Array(4), Array(4), Array(4) ]
console.log(env);
// logs: { orientation: "landscape", verticalSpace: "short", … }
return toolbar;
},
});
A toolbar item can either be a tag or a Svelte component. Each item needs to have a unique id. Children are only supported on the tag descriptor.
// tag
const toolbarItems = [
// html tag item
[
'div', // only div is supported
'my-unique-id',
{
class: 'my-class-name',
},
[
// Svelte component item
[
SvelteComponent,
'my-unique-id',
{
label: 'Label',
},
],
// other children
],
],
// other top level items
];
Image properties
Readonly image properties
Property | Description |
---|---|
imageFile |
The image source as a File object.
|
imageSize |
The natural size of the image. |
imageLoadState |
The load state of the image. |
imageProcessState |
The processing state of the image. |
imageAspectRatio |
The aspect ratio of the image. |
imageCropRectAspectRatio |
The aspect ratio of the crop rectangle. |
imageCropSize |
The size of the crop rectangle. |
imageRotationRange |
The min and max rotation of the image. |
Image properties to update image state
Property | Default value | Description |
---|---|---|
imageCrop |
|
A Rect describing the crop relative to the bounding box of the rotated image.
|
imageRotation |
|
The rotation of the image in radians. |
imageCropAspectRatio |
|
Set the aspect ratio of the crop as a number. |
imageCropLimitToImage |
|
Set to true to limit the crop to the image edges.
|
imageCropMinSize |
|
A Size describing The minimum size of the crop.
|
imageCropMaxSize |
|
An array [width, height] describing the maximum size of the crop. By default the editor determines the max size based on the browser.
|
imageFlipX |
|
Flip image over X axis. |
imageFlipY |
|
Flip image over Y axis. |
imageTargetSize |
|
A Size describing the output size of the image.
|
imageAnnotation |
|
Set to an array of shapes to apply to the image. |
imageDecoration |
|
Set to an array of shapes to apply to the crop. |
imageBackgroundColor |
|
The background color to use for the output image, defaults to transparent. Will render black for non-transparent image formats. |
imageColorMatrix |
|
A color matrix to apply to the image. |
imageGamma |
|
The image gamma adjustment. |
imageVignette |
|
Vignette to apply to the image -1 to 1 .
|
imageState |
|
The current state of the image, this contains all information to recreate the current image state. |
imageLoadState
The imageLoadState
contains the load state of the current image as it is passed through the imageReader
.
imageProcessState
The imageProcessState
contains the process state of the current image as it is passed through the imageWriter
.
imageCrop
The current crop rectangle is relative to the (optionally rotated) bounding box of the image.
In the diagram below we can see how this works. We've defined a 64 x 64
crop in the top left corner of the image.
- The dashed line illustrates the bounding box of the rotated image.
- The magenta square represents our 64 × 64 crop positioned relative to the image bounding box.
We can see how the crop rectangle updates when we rotate the image using the range input.
If we assign options to the editor creation command the crop will be set first and then the rotation. In the example below, no matter the order of the properties, the crop will be set first and then the image will be rotated.
import { openEditor, degToRad } from './doka.js';
openEditor({
// 2. Rotate the image
imageRotation: degToRad(45),
// 1. Crop 64 x 64 image from top left corner
imageCrop: {
x: 0,
y: 0,
width: 64,
height: 64,
},
});
imageCropAspectRatio
Set the aspect ratio of the crop as a number. Set to undefined
to not enforce a crop aspect ratio.
import { openEditor } from './doka.js';
openEditor({
imageCropAspectRatio: 16 / 9,
});
imageCropLimitToImage
When set to true
Doka will prevent cropping outside of the image edges.
When set to false
we can make a crop outside of the image edges. This also means we can zoom out further and rotate the image without auto zoom. To control the background color of pixels outside of the image we can set the imageBackgroundColor
prop.
imageBackgroundColor
Set the background color to use for the output image and the image preview in the editor.
import { degToRad } from './doka.js';
openEditor({
// set to red
imageBackgroundColor: [1, 0, 0],
});
If we like a more familiar way of setting colors we can use the colorStringToColorArray
method exported by the Doka Image Editor module.
Transparent background colors are supported in the output image but the preview isn't rendered correctly in the editor.
imageState
The imageState
property describes the current image state.
See below for an example:
{
// transforms
flipX: false,
flipY: false,
rotation: 0,
crop: { x: 0, y: 0, width: 1024, height: 768 },
cropAspectRatio: undefined,
cropMinSize: { width: 1, height: 1 },
cropMaxSize: { width: 32767, height: 32767 },
cropLimitToImage: true,
// shapes
annotation: [
{
id: 'lme6159vp',
x: 32,
y: 64,
width: 320,
height: 256,
backgroundColor: [1, 0, 0],
strokeColor: [1, 1, 1, 0],
strokeWidth: 0,
cornerRadius: 0,
}
],
decoration: [],
// filters
colorMatrix: undefined,
convolutionMatrix: undefined,
gamma: undefined,
vignette: undefined,
// output
backgroundColor: [0, 0, 0, 0],
targetSize: undefined,
}
Markup editor properties
Property | Default value | Description |
---|---|---|
markupEditorToolbar |
|
An array of tools to render in the Markup Editor toolbar. |
markupEditorToolStyles |
|
The default shape style definitions to use for each tool in the toolbar. |
markupEditorShapeStyleControls |
|
The style control options available to change the appearance of shapes. |
markupEditorToolSelectRadius |
|
The radius around a select action to select shapes in. |
beforeSelectShape |
|
Set to a function that runs before selecting a shape. Receives previously selected shape an targetted shape. |
beforeDeselectShape |
|
Set to a function that runs before deselecting a shape. Receives currently selected shape and targetted shape. |
beforeAddShape |
|
Set to a function that runs before adding a preset shape. Receives shape that is going to be added. |
beforeRemoveShape |
|
Set to a function that runs before removing a shape. Receives shape that is going to be removed. Return true
|
beforeUpdateShape |
|
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 |
|
Can be set to a function to modify the markup editor preset toolbar. |
willRenderShapeControls |
|
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.
We can use the createMarkupEditorToolbar
helper function to generate the default toolbar items and make it easier to add our own toolbar items.
import { openEditor } from './doka.js';
openEditor({
markupEditorToolbar: [
['sharpie', 'Sharpie', { disabled: true, icon: '<g></g>' }],
['eraser', 'Eraser', { disabled: false, icon: '<g></g>' }],
['rectangle', 'Rectangle', { disabled: false, icon: '<g></g>' }],
],
});
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.
import {
openEditor,
createMarkupEditorToolStyles,
createMarkupEditorToolStyle,
} from './doka.js';
openEditor({
// create the default tool styles
markupEditorToolStyles: createMarkupEditorToolStyles({
// create the text tool style and override fontSize property
text: createMarkupEditorToolStyle('text', {
fontSize: '10%',
}),
}),
});
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.
We can use the createMarkupEditorShapeStyleControls
helper function to generate the default controls and to make it easier to generate custom style control objects.
import { openEditor } from './doka.js';
openEditor({
markupEditorShapeStyleControls: {
backgroundColor: [
ColorPicker, // component
{}, // settings
],
fontFamily: [
Dropdown, // component
{}, // settings
],
// ...
},
});
willRenderShapePresetToolbar
Use to add custom buttons to the markup editor preset toolbar.
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.
import { openEditor, createNode } from './doka.js';
openEditor({
willRenderShapePresetToolbar: (nodes, addPreset, env) => {
// create smile button
const smileButton = createNode('Button', 'smile-button', {
label: 'Add smile',
onclick: () => addPreset('😄'),
});
// add it to the node tree
appendNode(smileButton, menu);
// return the new node tree
return nodes;
},
});
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.
import { openEditor } from './doka.js'
openEditor({
beforeSelectShape = (current, target) => {
console.log('beforeSelectShape', target);
return true;
}
});
We can use the beforeSelectShape
hook combined with the removeshape
event to prevent auto selection of the next shape when a shape was removed.
import { openEditor } from './doka.js'
let removedShape;
const editor = openEditor({
beforeSelectShape = (current, target) => {
// if currently selected shape is the
// shape that was just removed prevent selection
// of next shape
if (current === removedShape) return false;
return true;
}
});
editor.on('removeshape', (shape) => {
removedShape = shape;
})
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.
import { openEditor } from './doka.js'
openEditor({
beforeDeselectShape = (current, target) => {
console.log('beforeDeselectShape', current);
return true;
}
});
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.
import { openEditor } from './doka.js'
openEditor({
beforeAddShape = (shape) => {
console.log('beforeAddShape', shape);
return true;
}
});
beforeRemoveShape
Runs before a shape is removed.
Return false
to prevent removal of a shape.
import { openEditor } from './doka.js'
openEditor({
beforeRemoveShape = (shape) => {
console.log('beforeRemoveShape', shape);
return true;
}
});
beforeUpdateShape
Runs before a shape is updated.
Return adjusted props
to make changes to shape update.
import { openEditor } from './doka.js'
openEditor({
beforeUpdateShape = (shape, props, context) => {
console.log('beforeUpdateShape', shape, props, context);
return props;
}
});
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.
import { openEditor } from './doka.js'
openEditor({
willRenderShapeControls = (controls, selectedShapeId) => {
// manipulate shape controls here
return controls;
}
});