Properties

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.
src
undefined
The image source to load, can be of type File, Blob, DataURL, URL, HTMLCanvasElement, or HTMLImageElement.
locale
undefined
The locale object to use for the editor labels.
element
HTMLElement
The root element of the editor.
modal
HTMLElement
The root element of the modal. Only available when the editor was created with the openEditor method.
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.
animations
'auto'
Control if and when animations are shown.
elasticityMultiplier
10
Controls the elasticity force of the interface.
previewUpscale
false
Should the image preview be upscaled to fit the editor stage.
previewImageDataMaxSize
undefined
Maximum texture size to use for the preview image. Will default to browser max texture size.
imageSourceToImageData
undefined
The function to use for preview reading image data.
imageOrienter
undefined
The object to use to correctly orient preview image data.
imageReader
undefined
The imageReader to use for reading image data.
imageWriter
undefined
The imageWriter to use for writing image data.
enableToolbar
true
Set to false to disable the toolbar.
enableUtils
true
Set to false to disable the util tabs.
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.
handleEvent
undefined
Set to a function that is called for each event.
willRenderCanvas
undefined
Allows to inject shapes or adjust shapes in the preview render.
willRevert
undefined
Allows to prevent revert of the user actions.

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
undefined
A Rect describing the crop relative to the bounding box of the rotated image.
imageRotation
0
The rotation of the image in radians.
imageCropAspectRatio
undefined
Set the aspect ratio of the crop as a number.
imageCropLimitToImage
true
Set to true to limit the crop to the image edges.
imageCropMinSize
{ width:1, height:1 }
A Size describing The minimum size of the crop.
imageCropMaxSize
undefined
An array [width, height] describing the maximum size of the crop. By default the editor determines the max size based on the browser.
imageFlipX
false
Flip image over X axis.
imageFlipY
false
Flip image over Y axis.
imageTargetSize
undefined
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
undefined
The background color to use for the output image, defaults to transparent. Will render black for non-transparent image formats.
imageColorMatrix
undefined
A color matrix to apply to the image.
imageGamma
undefined
The image gamma adjustment.
imageVignette
undefined
Vignette to apply to the image -1 to 1.
imageState
undefined
The current state of the image properties.

Shape editor related properties

Property Default value Description
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

Editor core and interface

src

The source image to load.

Accepts:

  • File
  • Blob
  • DataURL
  • URL
  • HTMLCanvasElement
  • HTMLImageElement

locale

Expects a locale object.

See below for an example of the locale_en_gb object.

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

    // etc...
}

The code below logs all locale properties to the developer console.

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,

    // shape editor locale
    component_shape_editor_locale_en_gb,
} from './doka.js';

console.log(
    Object.assign(
        {},
        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,
        component_shape_editor_locale_en_gb
    )
);

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.

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

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 and return promise
                });
            }),
});

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.

Overview of all editor events

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

openEditor({
    handlEvent: (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,
    },

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

    // 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 example below we draw a circular overlay on top of the crop selection.

// index.js
import { openEditor } from './doka.js';

openEditor({
    // this method is synchronouse,
    // it's called before each render
    willRenderCanvas: (shapes, state) => {
        const { utilVisibility, selectionRect } = 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: [0, 0, 0, 0.5],
                    strokeWidth: 1,
                    strokeColor: [0, 0, 0],
                },
                ...shapes.interfaceShapes,
            ],
        };
    },
});
<!-- index.html -->
<link href="./doka.css" rel="stylesheet" />
<script src="./index.js" type="module"></script>

Image manipulation

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.

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.

Shape manipulation

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 ook 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;
    }
});