This is the archived documentation for Doka Image Editor v6.

Please visit pqina.nl/pintura/docs/ to see documentation for the latest version of Pintura Image Editor.

Doka Instance

The Doka instance is the object returned when Doka.create method is used. It's an object linked to a DOM element. The Doka instance can be used to edit an image file.

Properties

The Doka instance exposes the following properties.

Property Default Description
element null The root element of the Doka instance. This is the only property that has no setter.
id null The id to use on the Doka container.
className null Additional CSS class to add to the root element.
src null The source data to load when creating the instance. This is automatically populated when instantiating Doka on an image or canvas element.
util null Set to a util id to activate that util. If set to null Doka will use first available util in utils list.
utils ['crop', 'filter', 'color', 'markup'] Set the available utils. Set to ['crop', 'filter', 'color', 'markup', 'resize'] to enable the "resize" utility. Add 'sticker' to enable the stickers util.
storageName 'doka' The key Doka uses for storing information in localStorage.
maxImagePreviewWidth 1500 Maximum width of the image preview.
maxImagePreviewHeight 1500 Maximum height of the image preview.
imagePreviewScaleMode 'stage' How to scale the image preview. Set to 'crop' to show actual crop pixels. Set to 'image' to scale preview to max image size.

Toggle functionality

Property Default Description
allowButtonClose
allowButtonCancel
true Renders the cancel button.
allowButtonConfirm true Renders the confirm button.
allowDropFiles true Allow dropping files on the editor window.
allowAutoClose true The editor will close automatically when in fullscreen or preview mode
allowAutoDestroy false The editor will remove itself from the DOM automatically when closed
allowPreviewFitToView
true Set to false to prevent upscaling of the preview image. Most likely you want to use imagePreviewScaleMode instead.

Output format

Property Default Description
outputData false Output the modifications made as an object representing the changes.
outputFile true Output the modifications made as a file object.
outputWidth null The target width of the output image, of only outputHeight is set, will automatically be set to the same value.
outputHeight null The target height of the output image, if only outputWidth is set, will automatically be set to the same value.
outputFit 'cover' The method used to resize images. Choose between 'force', 'cover', or 'contain'. Force will ignore the image aspect ratio. Cover will respect the aspect ratio and will scale to fill the target dimensions. Contain also respects the aspect ratio and will fit the image inside the set dimensions. All three settings will upscale images when there are smaller then the given target dimensions.
outputUpscale true Set to false to prevent upscaling of images smaller than the target size.
outputType null The file type of the output image. Can be either 'image/jpeg' or 'image/png' as those are the formats the HTML5 Canvas element can output to. If not defined, will default to the input file type, and fallback to 'image/jpeg'.
outputQuality null The quality of the output image supplied as a value between 0 and 100. Where 100 is best quality and 0 is worst. When not supplied it will use the browser default quality which averages around 94.
outputStripImageHead true Will remove EXIF data from outputted JPEGs. If set to false will still remove the orientation tag.
outputCanvasBackgroundColor null The image color to use as background when creating the output image.
outputCorrectImageExifOrientation true Whether to auto correct for EXIF image orientation header.
outputCanvasSyncTarget null Set to a canvas element and Doka will sync the current preview image with the canvas set to this property.

Crop configuration

Property Default Description
crop null Update the current crop configuration by passing a crop object
cropZoomTimeout null Automatically zoom to center after a given amount of milliseconds, null is disabled.
cropAllowResizeRect true Toggle crop resize controls on and off.
cropAllowImageTurnRight false Toggle turn right button on and off.
cropAllowImageTurnLeft true Toggle turn left button on and off.
cropAllowImageFlipHorizontal true Toggle flip horizontal button on and off.
cropAllowImageFlipVertical true Toggle flip vertical button on and off.
cropAllowRotate true Toggle bottom rotation control.
cropResizeKeyCodes [18, 91, 92, 93] The key codes used to toggle mouse move resizing, CMD or ALT by default. Set to empty array to disable this functionality.
cropResizeScrollRectOnly false Set to true to only handle scroll events when the pointer is over the crop rectangle, useful to prevent scroll hijacking
cropAspectRatio null The default aspect ratio to use when cropping.
cropAspectRatioOptions null A list of aspect ratios available for the user to choose from. As an alternative can contain a list of width and height options to serve as output size presets.
cropMinImageWidth 1 The minimum width of the output image
cropMinImageHeight 1 The minimum height of the output image
cropMask null A mask to render on top of the crop area
cropMaskInset 0 Distance in pixels from the edge of the image to offset the mask
cropShowSize false Set to true to show the current crop size in the bottom right corner of the crop rectangle
cropAllowToggleLimit false Enables button to toggle crop limiting on and off
cropLimitToImageBounds true When set to true the crop is limited to the image pixels, if is set to false crops can be made outside of the image.
cropResizeMatchImageAspectRatio false When set to true the crop will automatically match the preview image aspect ratio if the user zooms out. This only works if the crop aspect ratio is set to "free" and cropLimitToImageBounds is set to true.
cropAllowInstructionZoom false Show a short message instructing the user to use scrollwheel or touchpad to zoom in and out. Only shown once and only shown when the user has access to a mouse or touchpad.

Size configuration

Property Default Description
size null Update the current output size by setting a size object, for example {width: 640, height: 480}
sizeMin {width: 1, height: 1} Minimum output size the user can enter
sizeMax {width: 9999, height: 9999} Maximum output size the user can enter

Filter configuration

Property Default Description
filter null The default filter to select, can be either the name of a filter, or a ColorMatrix
filters {} An object describing the filter options

Color controls configuration

Property Default Description
colorBrightness 0 Controls the initial value of the brightness control.
colorContrast 1 Controls the initial value of the contrast control.
colorExposure 1 Controls the initial value of the exposure control.
colorSaturation 1 Controls the initial value of the saturation control.
colorBrightnessRange [-.25, .25] Controls the minimum and maximum values that can be input into the brightness control.
colorContrastRange [.5, 1.5] Controls the minimum and maximum values that can be input into the contrast control.
colorExposureRange [.5, 1.5] Controls the minimum and maximum values that can be input into the exposure control.
colorSaturationRange [0, 2] Controls the minimum and maximum values that can be input into the saturation control.

Markup configuration

Property Default Description
markup null Optional array of markup shapes to render
markupUtil 'select' The selected util
markupAllowAddMarkup true Allow the user to add markup to the image
markupAllowCustomColor true Allow the user to pick custom colors for markup shapes
markupFilter (markupShape) => true Allows filtering of the markup shapes to show in the editor.
markupDrawDistance 4 The distance to draw from the mouse pointer, the further the distance the smoother the line.
markupColor #000 The initial color to select in the color options list
markupColorOptions [] The available color options
markupFontSize .1 The initial font size to select in the font size options list
markupFontSizeOptions [] The available font size options
markupFontFamily 'Helvetica, Arial, Verdana' The initial font family to select in the font family options list
markupFontFamilyOptions [] The available font family options
markupShapeStyle [.015, null] The initial shape style to select in the shape style options list
markupShapeStyleOptions [] The available shape style options
markupLineStyle [.015, null] The initial line style to select in the line style options list
markupLineStyleOptions [] The available line style options
markupLineDecoration ['arrow-end'] The initial line decoration to select in the line decoration options list
markupLineDecorationOptions [] The available line decoration options
markupAutoSelectNextOnRemove true Set to false to prevent auto selection of next markup item on removal

The markupFontSizeDefault, markupFontFamilyDefault, markupShapeStyleDefault, markupLineStyleDefault, and markupLineDecorationDefault properties have been deprecated as of Doka version 6.0.0.

Sticker configuration

Property Default Description
stickers [] An array of valid sticker items.

Labels

Property Default Description
labelButtonReset 'Reset' Reset button label, uses icon by default.
labelButtonClose
labelButtonCancel
'Cancel' Label shown on grey cancel button.
labelButtonConfirm 'Done' Label shown on yellow confirm button.
labelStatusAwaitingImage 'Waiting for image…' Label shown while waiting for input.
labelStatusLoadingImage 'Loading image…' Label shown while loading an image.
labelStatusLoadImageError 'Error loading image…' Label shown when image failed to load. You can set this to a function instead of a string. The function will receive detailed image error information, the string returned by your function will be used as the error message.
labelStatusProcessingImage 'Processing image…' Label shown while processing an image to generate an output file.
labelColorBrightness 'Brightness' Label shown on the brightness control.
labelColorContrast 'Contrast' Label shown on the contrast control.
labelColorExposure 'Exposure' Label shown on the exposure control.
labelColorSaturation 'Saturation' Label shown on the saturation control.
labelResizeWidth 'Width' Label used for the resize width input.
labelResizeHeight 'Height' Label used for the resize height input.
labelResizeApplyChanges 'Apply' Hidden label used for the confirm size button next to the width and height input fields.
labelCropInstructionZoom 'Zoom in and out with your scroll wheel or touchpad.' Text used for the zoom in and out instruction info.
labelButtonCropZoom 'Zoom' Label used for the zoom button. This button uses an icon by default.
labelButtonCropRotateLeft 'Rotate left' Label shown on the rotate left button.
labelButtonCropRotateRight 'Rotate right' Label shown on the rotate right button. This button is hidden by default.
labelButtonCropRotateCenter 'Center rotation' Label used for the center rotation button. This label is invisible by default
labelButtonCropFlipHorizontal 'Flip horizontal' Label shown on the flip horizontal button.
labelButtonCropFlipVertical 'Flip vertical' Label shown on the flip vertical button.
labelButtonCropAspectRatio 'Aspect ratio' Label shown on the select aspect ratio dropdown.
labelButtonCropToggleLimit 'Crop selection' Label shown on the crop toggle limit dropdown.
labelButtonCropToggleLimitEnable 'Limit to image' Label used for the enable limiting option in the crop toggle limit dropdown.
labelButtonCropToggleLimitDisable 'Select outside image' Label used for the disable limiting option in the crop toggle limit dropdown.
labelButtonUtilCrop 'Crop' Label shown below the crop util tab
labelButtonUtilFilter 'Filter' Label used for the filter util tab
labelButtonUtilColor 'Colors' Label used for the color util tab
labelButtonUtilResize 'Resize' Label used for the resize util tab
labelButtonUtilMarkup 'Markup' Label used for the markup util tab
labelButtonUtilSticker 'Stickers' Label used for the sticker util tab
labelMarkupTypeRectangle 'Square' Label shown in the rectangle tool button
labelMarkupTypeEllipse 'Circle' Label shown in the ellipse tool button
labelMarkupTypeText 'Text' Label shown in the text tool button
labelMarkupTypeLine 'Arrow' Label shown in the line tool button
labelMarkupSelectFontSize 'Size' Label shown in the markup tool font size select
labelMarkupSelectFontFamily 'Font' Label shown in the markup tool font family select
labelMarkupSelectLineDecoration 'Decoration' Label shown in the markup tool line decoration select
labelMarkupSelectLineStyle 'Style' Label shown in the markup tool line style select
labelMarkupSelectShapeStyle 'Style' Label shown in the markup tool shape style select
labelMarkupRemoveShape 'Remove' Label shown in the markup remove button
labelMarkupToolSelect 'Select' Label shown in the select tool button
labelMarkupToolDraw 'Draw' Label shown in the draw tool button
labelMarkupToolLine 'Arrow' Label shown in the line/arrow tool button
labelMarkupToolText 'Text' Label shown in the text tool button
labelMarkupToolRect 'Square' Label shown in the square/rectangle tool button
labelMarkupToolEllipse 'Circle' Label shown in the circle/ellipse tool button

Callbacks

Property Function Description
oninit () Fired when Doka has initialised
onconfirm (output) Output is an object containing the processed file and the data object describing the edit information.
oncancel () The edit operation was cancelled.
onclose () A fullscreen Doka editor was closed.
onloadstart (source) Firend when an image starts loading. Receives the image source.
onload (image) Fired when an image is loaded. Receives images object containing information about the image.
onloaderror (error) Fired when an image fails to load, either because it can't be found, the image size is not valid or an unknown error occurs.
ondestroy () Fired when doka is removed from the DOM.
onupdate (state) Fired when the crop rectangle is updated, receives current crop object and width and height of output image.
onselectmarkup (markupItem) Fired when a markup item has been selected.
onremovemarkup (markupItem) Fired when a markup item has been removed.
onaddmarkup (markupItem) Fired when a markup item has been added.

Hooks

Property Function Description
beforeReset null Called when the user taps the reset button. Set to a function that returns a Promise that resolves with true or false, if resolves with true the state will be reset.
beforeLoadImage null Can be used to validate source files. Receives a file object, should return a Promise that resolves with a file object or rejects with an error message. When labelStatusLoadImageError is set to a function this function will receive the error code and you can return a custom error label.
beforeCreateBlob null Can be used to modify the canvas data before the output file object is created. If set to a function, this function will receive a canvas element as parameter. The function has to return a Promise that resolves with an updated (or new) canvas element.
afterCreateBlob null Can be used to modify the Blob before the output file is returned by Doka. If set to a function, this function will receive a Blob object as parameter. The function has to return a Promise that resolves with an updated (or new) Blob.
afterCreateOutput null Can be used to modify the output object and update the "processing" label. If set to a function, this function will receive the output object and a callback as parameters. The function has to return a Promise that resolves with a new output object. Reject the Promise with an error message to show an error message on the screen.
afterUpdateStickerItem null Is called when Doka updates the sticker thumbnail. Receives button and data to render the button. Allows updating the sticker thumbnail HTML.
beforeAddMarkup null Is called before a markup item is added, receives markupItem, return markupItem to add or false to prevent adding the item.
beforeRemoveMarkup null Is called before a markup item is removed, receives markupItem, return markupItem to remove or false to prevent removing the item.
beforeDeselectMarkup null Receives currentItem and nextItem, is called when a markup item is deselected, return false to prevent deselection, return true to allow deselection.
beforeMarkupUpdateManipulatorHitbox null Can be used to control the hitboxes rendered for the markup control points.

Styles

Property Default Description
styleLayoutMode null The current layout mode, will automatically be set to fullscreen when the editor is in fullscreen mode. Can be set to 'preview' if you want to render in preview mode. Can be set to 'modal' to show a modal in fullscreen mode.
styleCropCorner 'circle' The style of the crop corner controls. 'circle' or 'line'.

Events

Doka exposes the following events, they're mostly the same as the callback methods. The event detail property will contain the relevant event information. We can subscribe to them by listing on the root node.

const doka = document.querySelector('.doka--root');
doka.addEventListener('Doka:confirm', (e) => {
    console.log('Image edited', e.detail);
});
Option Description
Doka:init Doka instance has been created and is ready.
Doka:destroy Doka instance has been destroyed.
Doka:confirm Confirmed image editing
Doka:cancel Cancelled image editing
Doka:close Closed a fullscreen Doka popup
Doka:load An image was loaded

Methods

Method Params Description
setOptions object Override multiple options at once
open source [, options] Opens an image for editing and resolves when the image has been loaded correctly
edit source [, options] Opens an image for editing and resolves when the image has been processed
setData object Set new edit data object for an active file
getData object Retrieve data object and or file for an active file
save object Same as getData
close Close a full screen Doka editor
clear Remove active image from editor
destroy Destroys this Doka instance

DOM manipulation

Method Params Description
insertAfter element Inserts the Doka instance after the supplied element
insertBefore element Inserts the Doka instance before the supplied element
appendTo element Appends Doka to the given element
isAttachedTo element Returns true if the current instance is attached to the supplied element
replaceElement element Replaces the supplied element with Doka
restoreElement element If Doka replaced the original element, this restores the original element to its original glory.

Event Methods

Doka provides the on, onOnce and off methods as an alternative way to listen for events. We can listen for the same events but can do so without adding the 'Doka:' prefix. Parameters received by the handler functions are the same as defined on the callback methods.

// 'confirm' instead of 'Doka:confirm'
const doka = Doka.create();
doka.on('confirm', (output) => {
    console.log('Image edited', output);
});
Method Params Description
on event, fn Listen to an event with name
onOnce event, fn The handler will only be called once and will then automatically be removed
off event, fn Remove event listener with supplied name and function

Setting options

To override already set options on a Doka instance we can either use the setOptions method or adjust the properties directly. Updating options might not always result in an update to the editor.

const doka = Doka.create();
doka.setOptions({
    outputQuality: 70,
});

Adjusting individual properties:

const doka = Doka.create();
doka.outputQuality = 70;

Loading an image

To load an image to Doka we can set the src property while initialising or use the edit or open method.

All three options (src, edit(), and load()) accept the following data formats:

  • Blobs or File objects
  • Local URLs
  • DataURLs
  • Image or canvas elements
// Load image from a File object or Blob
doka.open(file);

// Load image from a local URL
doka.open('./path/to/selfie.jpeg');

// Load image from a dataURI
doka.open('data:image/png;base64,SGVsbG8sIFdvcmxkIQ...');

// Load image from an image tag
doka.open(document.querySelector('img'));

// Load image from an canvas tag
doka.open(document.querySelector('canvas'));

As Blobs and DataURLs don't supply any filename information Doka sets the file name to the current date.

Both the edit and load method return a Promise.

  • The Promise returned by the edit method resolves when the user is done editing.
  • The Promise returned by the load method resolves when the image has successfully loaded.
doka.open('./path/to/selfie.jpeg').then((data) => {
    // Called when the source has been loaded to the editor
    // Receives the current editor state
});

doka.edit('./path/to/selfie.jpeg').then((output) => {
    // Called when the source image has been edited
    // Receives the output file and optionally, if `outputData`
    // is set to true, the editor state
});

The second argument to both these methods can be an option object describing the editor state. The following examples will only show the load method as both methods have the same signature.

doka.open('./path/to/selfie.jpeg', {
    crop: {
        center: {
            x: 0.5,
            y: 0.5,
        },
        flip: {
            horizontal: false,
            vertical: false,
        },
        zoom: 1,
        rotation: 0,
        aspectRatio: null,
    },
});

Updating the editor

We can use the setData method to pass new view instructions to the Doka editor. Doka will then update the view accordingly.

The following example sets the zoom level to 2.

doka.setData({
    crop: {
        zoom: 2,
    },
});

An alternative way to update the view is to set a new crop property.

doka.crop = {
    center: {
        x: 0.5,
        y: 0.5,
    },
    flip: {
        horizontal: false,
        vertical: false,
    },
    zoom: 1,
    rotation: 0,
    aspectRatio: 1,
};

Retrieving data from the editor

We can get the current state of the editor using the getData method.

doka.getData().then((output) => {
    // Called when the source image has been edited
    // Receives the output file and optionally, if `outputData`
    // is set to true, the editor state
});

We can override the output contents by supplying an options object to the getData method.

doka.getData({
    file: true,
    data: true
}.then(output => {
    // output will now contain both file and output data
})

Setting crop aspect ratio options

The aspect ratio option dropdown is populated by a list of label, value pairs.

The label is what the text shown in the aspect ratio dropdown, the value is either the aspect ratio to use or the width and height values to use for the given label.

The value can be one of the following:

Value Description
null For free input mode
'1:1' A human readable aspect ratio
1.25 A numeric aspect ratio
{ width: 400, height: 300 } An object describing a width and height

If the value is set to a size object the aspect ratio is derived from the given width and height.

The snippet below creates a crop options dropdown.

Doka.create({
    cropAspectRatioOptions: [
        {
            label: 'Free',
            value: null,
        },
        {
            label: 'Portrait',
            value: 1.5,
        },
        {
            label: 'Square',
            value: '1:1',
        },
        {
            label: 'Landscape',
            value: 0.75,
        },
    ],
});

This creates a size preset dropdown, in this situation we'd probably also want to change the label of the crop aspect ratio dropdown to something like "presets", we can do this by setting our label text to the labelButtonCropAspectRatio property.

Doka.create({
    cropAspectRatioOptions: [
        {
            label: 'Profile Picture',
            value: {
                width: 180,
                height: 180,
            },
        },
        {
            label: 'Profile Header Image',
            value: {
                width: 1200,
                height: 600,
            },
        },
        {
            label: 'Timeline Photo',
            value: {
                width: 800,
                height: 400,
            },
        },
    ],
});

Setting filters

By default the filters property contains the following filter configuration.

{
    'original': {
        label: 'Original',
        matrix: () => null
    },
    'chrome': {
        label: 'Bright',
        matrix: () => [
            1.398,-0.316, 0.065,-0.273, 0.201,
            -0.051, 1.278,-0.080,-0.273, 0.201,
            -0.051, 0.119, 1.151,-0.290, 0.215,
                0.000, 0.000, 0.000, 1.000, 0.000
        ]
    },
    'fade': {
        label: 'Dark',
        matrix: () => [
            1.073,-0.015, 0.092,-0.115,-0.017,
            0.107, 0.859, 0.184,-0.115,-0.017,
            0.015, 0.077, 1.104,-0.115,-0.017,
            0.000, 0.000, 0.000, 1.000, 0.000
        ]
    },
    'mono': {
        label: 'Mono',
        matrix: () => [
            0.212, 0.715, 0.114, 0.000, 0.000,
            0.212, 0.715, 0.114, 0.000, 0.000,
            0.212, 0.715, 0.114, 0.000, 0.000,
            0.000, 0.000, 0.000, 1.000, 0.000
        ]
    },
    'noir': {
        label: 'Noir',
        matrix: () => [
            0.150, 1.300,-0.250, 0.100,-0.200,
            0.150, 1.300,-0.250, 0.100,-0.200,
            0.150, 1.300,-0.250, 0.100,-0.200,
            0.000, 0.000, 0.000, 1.000, 0.000
        ]
    }
}

Each filter is defined by a key, the internal id of the filter. This key can also be used to select the filter with the filter property.

The filter object has a label and a matrix property. The label value is shown below the filter item in the filters list. The matrix should be set to a function that returns a ColorMatrix (an array with 20 numbers). Read this article on the SVG feColorMatrix filter for more details. Doka does not use the SVG color matrix to create the output image but the matrix format happens to be the same.

You can add additional filters by copying the filter object above.

Doka.create({
    filters: {
        // make sure the original style is in the list
        original: {
            label: 'Original',
            matrix: () => null,
        },

        // the default filters
        chrome: {
            label: 'Bright',
            matrix: () => [
                1.398, -0.316, 0.065, -0.273, 0.201, -0.051, 1.278, -0.08,
                -0.273, 0.201, -0.051, 0.119, 1.151, -0.29, 0.215, 0.0, 0.0,
                0.0, 1.0, 0.0,
            ],
        },
        fade: {
            label: 'Dark',
            matrix: () => [
                1.073, -0.015, 0.092, -0.115, -0.017, 0.107, 0.859, 0.184,
                -0.115, -0.017, 0.015, 0.077, 1.104, -0.115, -0.017, 0.0, 0.0,
                0.0, 1.0, 0.0,
            ],
        },
        mono: {
            label: 'Mono',
            matrix: () => [
                0.212, 0.715, 0.114, 0.0, 0.0, 0.212, 0.715, 0.114, 0.0, 0.0,
                0.212, 0.715, 0.114, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
            ],
        },
        noir: {
            label: 'Noir',
            matrix: () => [
                0.15, 1.3, -0.25, 0.1, -0.2, 0.15, 1.3, -0.25, 0.1, -0.2, 0.15,
                1.3, -0.25, 0.1, -0.2, 0.0, 0.0, 0.0, 1.0, 0.0,
            ],
        },

        // add your own filters
        sepia: {
            label: 'Sepia',
            matrix: () => [
                0.394, 0.769, 0.189, 0.0, 0.0, 0.349, 0.686, 0.168, 0.0, 0.0,
                0.272, 0.534, 0.131, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
            ],
        },
    },
});

For now no value is passed to the function but a future version of Doka might supply a user defined value between 0 and 1 which could be used to determine the intensity of the filter.

Markup Options

Each markup option item is defined as an array.

Color Options

The default selection of colors available to the user.

The color item has 2 to 3 indexes.

  1. The name of the color.
  2. The value of the color.
  3. The value of the color to show in the color palette.
[
    // [ name, color, option color ]
    ['White', '#fff', '#f6f6f6'],
    ['Silver', '#9e9e9e'],
    ['Black', '#000', '#333'],
    ['Red', '#f44336'],
    ['Orange', '#ff9800'],
    ['Yellow', '#ffeb3b'],
    ['Green', '#4caf50'],
    ['Blue', '#2196f3'],
    ['Violet', '#3f51b5'],
    ['Purple', '#9c27b0'],
];

Font Family Options

The default selection of font families available to the user.

The font family item has 2 indexes.

  1. The name to show in the dropdown.
  2. The CSS font stack.
[
    // [ name, value ]
    ['Serif', "Palatino, 'Times New Roman', serif"],
    ['Sans Serif', 'Helvetica, Arial, Verdana'],
    ['Monospaced', "Monaco, 'Lucida Console', monospaced"],
];

Font Size Options

The default selection of font sizes available to the user.

Each font size item has 2 indexes.

  1. The name to show in the dropdown.
  2. The relative size to the image.
[
    // name, value
    ['XL', 0.15],
    ['L', 0.125],
    ['M', 0.1],
    ['S', 0.075],
    ['XS', 0.05],
];

Shape Style Options

The default selection of shape styles available to the user.

Each shape style item has 4 indexes.

  1. The name to show in the dropdown.
  2. The stroke width to use.
  3. The stroke style to use (dashed or not).
  4. The stroke width to use in the preview icon.
// [ name, stroke width, dash style, option stroke width ]
[
    ['Fill', 0, null, 0],
    ['Outline thick', 0.025, null, 4],
    ['Outline default', 0.015, null, 2],
    ['Outline thin', 0.005, null, 1],
    ['Outline dashed', 0.005, [0.01], 1],
];

Line Style Options

The default selection of line styles available to the user.

Each line style item has 4 indexes.

  1. The name to show in the dropdown.
  2. The line width to use.
  3. The line style to use (dashed or not).
  4. The line width to use in the preview icon.
// [ name, line width, dash style, option line width ]
[
    ['Thick', 0.025, null, 4],
    ['Default', 0.015, null, 2],
    ['Thin', 0.005, null, 1],
    ['Dashed', 0.005, [0.01], 1],
];

Line Decoration Options

The default selection of line decorations available to the user.

Each line style item has 4 indexes.

  1. The name to show in the dropdown.
  2. An array describing the line being and end decorations to use, currently only arrows are supported.
// [ name, decorations ]
[
    ['None', []],
    ['Single arrow', ['arrow-end']],
    ['Double arrow', ['arrow-begin', 'arrow-end']],
];

Adding a Caption to the Image

Using the beforeCreateBlob property we intercept the canvas data before Doka creates the final output file. This is useful when we want to modify the data, for instance, to add a watermark or caption to the image.

The example code below will print Hello World in the top left corner of the image.

Doka.create({
    beforeCreateBlob: (canvas) =>
        new Promise((resolve) => {
            var ctx = canvas.getContext('2d');
            ctx.font = '48px serif';
            ctx.fillText('Hello world', 10, 50);
            resolve(canvas);
        }),
});

Setting The Crop Mask

Using the cropMask settings we can render a mask on top of the crop area. We can define this mask using SVG. SVG has three advantages, one, it's fast, two, it always renders razor sharp, and three, it allows for a lot of flexibility.

You'll notice the cropMask property expects a function. This function receives two arguments. The root element of the mask, and the setInnerHTML function.

We can either choose to define the SVG using the setInnerHTML function or manually build an SVG three using document.createElementNS. In the examples below we'll use the setInnerHTML function.

The setInnerHTML function is only there to help with IE11 and early version of Edge compatibility. These browsers don't have support for the innerHTML property so a custom function is required to set the value.

A Circular Crop Mask

Doka.create({
    cropMask: (root, setInnerHTML) => {
        // This sets the SVG inner HTML
        // 1. It defines a <mask> (white background, black circle on top)
        // 2. Then it fills the screen with transparent white, the mask is applied to this layer
        // 3. Finally it draws a one pixel line around the masked circular area
        setInnerHTML(
            root,
            `
            <mask id="my-mask">
                <rect x="0" y="0" width="100%" height="100%" fill="white"/>
                <circle cx="50%" cy="50%" r="50%" fill="black"/>
            </mask>
            <rect fill="rgba(255,255,255,.3125)" x="0" y="0" width="100%" height="100%" mask="url(#my-mask)"/>
            <circle cx="50%" cy="50%" r="50%" fill="transparent" stroke-width="1" stroke="#fff"/>
        `
        );
    },
});

A Rectangular Bleed Mask

A bleed is used in print to indicate what area of a print might be cut of when the print is sliced.

The bleed can be set using the cropMaskInset property. It's supplied in pixels.

Doka.create({
    // We define a 40 pixel inset for the mask
    cropMaskInset: 40,

    // We supply Doka with the function to render and update the mask
    cropMask: (root, setInnerHTML) => {
        // This sets the SVG inner HTML
        // 1. It defines a <mask> (white background, black rect cutout)
        // 2. Then it fills the screen with transparent white, the mask is applied to this layer
        // 3. Finally it draws a one pixel line around the masked rectangular area
        setInnerHTML(
            root,
            `
            <mask id="my-mask">
                <rect x="0" y="0" width="100%" height="100%" fill="white"/>
                <rect fill="black"/>
            </mask>
            <rect fill="rgba(255,255,255,.3125)" x="0" y="0" width="100%" height="100%" mask="url(#my-mask)"/>
            <rect fill="transparent" stroke-width="1" stroke="rgba(255,255,255,.85)"/>
        `
        );

        // Select the mask element (area that is still visible)
        const bleedMask = root.querySelector('mask rect[fill="black"]');

        // Select the edge element (one pixel white line)
        const bleedEdge = root.querySelector('rect[fill="transparent"]');

        // Return a function that Doka will use to update the mask positions based on the current zoom level
        return (rect) => {
            // update the mask positions
            bleedMask.setAttribute('x', rect.x);
            bleedMask.setAttribute('y', rect.y);
            bleedMask.setAttribute('width', rect.width);
            bleedMask.setAttribute('height', rect.height);

            // update the edge positions, notice the .5s, this is to render sharp 1 pixel wide lines
            bleedEdge.setAttribute('x', Math.round(rect.x) - 0.5);
            bleedEdge.setAttribute('y', Math.round(rect.y) - 0.5);
            bleedEdge.setAttribute('width', rect.width + 0.5);
            bleedEdge.setAttribute('height', rect.height + 0.5);
        };
    },
});

Using an Image as a Mask

Doka.create({
    cropMask: (root, setInnerHTML) => {
        // This sets the SVG inner HTML
        // 1. It simply loads an image that is rendered on top of the crop area
        setInnerHTML(
            root,
            `
            <image xlink:href="mask.png" x="0%" y="0%" width="100%" height="100%"/>
        `
        );
    },
});

Intercepting the output object

The output object returned by Doka can be intercepted modified and returned to Doka right before Doka returns it through its API.

This allows you to do file uploads or further processing while keeping the "Doka is busy" UI in place.

Doka.create({
    outputFile: true,
    afterCreateOutput: (output, setLabel) =>
        new Promise((resolve, reject) => {
            const { file, data } = output;

            // set Doka status to uploading, the `setLabel` call will return a function to update the label progress indicator
            const updateProgress = setLabel('Uploading image…');

            // create a formdata object to send to the server
            const formData = new FormData();
            formData.append('doka', file, file.name);

            // create our request object
            const request = new XMLHttpRequest();
            request.open('POST', 'url/to/upload/location');

            // update the label progress indicator while uploading
            request.upload.onprogress = (e) => {
                updateProgress(e.lengthComputable ? e.loaded / e.total : null);
            };

            // called when the upload was successful
            request.onload = function () {
                if (request.status >= 200 && request.status < 300) {
                    // done! resolve with the output object
                    resolve(output);
                } else {
                    // something went wrong
                    reject('oh no!');
                }
            };

            // start uploading the output image
            request.send(formData);
        }),
});

Adjusting markup hitboxes

beforeMarkupUpdateManipulatorHitbox receives the object below that describes the hitboxes layout.

{ type: 'rect', radius: 22, offset: 5, hideEdges: true, rect: MarkupRect }

Adjust the object to change the position and size of the hitboxes.

radius describes the radius in pixels of each hitboxes. offset describes the offset in pixels from the visual control point towards the outside of the shape. hideEdges is true when the shape is small and edge control points are hidden. rect is the rect of the markup item.

Preview layout mode

With preview layout mode we can render Doka on top of an image. This makes it easier for the user to determine how the image will look in the website once edited.

To get this operational we need to set up the HTML and CSS in a specific way.

In this example we'll assume we have both the cropped image and the original image. If we should only have the cropped image we can replace the URL in the edit call with the original URL and don't need to pass crop coordinates.

First, let's set up the HTML. We'll load the cropped image preview and add a location for the Doka editor to render.

<div class="panel">
    <!-- The current image -->
    <img src="./path/to/selfie.jpeg" />

    <!-- Our editor -->
    <div class="doka"></div>
</div>
/* Position child elements relative to the `.panel` container */
.panel {
    position: relative;
}

/* Scale the image to be the same size as the `.panel` container */
.panel img {
    display: block;
    width: 100%;
}

/* Draw the Doka editor on top of the image. */
.panel .doka--root {
    position: absolute;
    left: 0;
    top: 0;
}
const doka = Doka.create(document.querySelector('.panel .doka'), {

    // Tell Doka to render in preview mode
    styleLayoutMode: 'preview',

    // Tell Doka to also output crop coordinates
    outputData: true,

    // Set crop aspect ratio to the aspect ratio of the preview image.
    // Suppose the preview image size is 800 by 300 pixels, divide
    // height by width to calculate the aspect ratio
    cropAspectRatio: 300 / 800

});

// The crop coordinates of the currently visible image on the page, let's assume it's a slightly of center crop.
const crop = {
    center: {
        x: .5,
        y: .4
    }
}

// Let's now tell Doka to edit the original image and pass the crop coordinates so Doka shows the correct preview.
doka.edit('./path/to/selfie-original.jpeg', { crop })
    .then({ file, data } => {
        // We can now upload the resulting `file` object
        // and/or the crop information contained in the `data` object
    })

Using Stickers

When the sticker util is enabled you can use the stickers property to supply Doka with stickers.

Stickers can be defined in 4 different ways:

  • An emoji
  • An image source
  • A markup object
  • A sticker object

See below for an example using multiple sticker types:

Doka.create({
    stickers: [
        // emoji
        '👍',

        // url
        './my-image.jpeg',

        // markup
        ['text', { fontSize: '20px', text: 'Hello World' }],

        // sticker with sole `sticker` property, same as shorthand examples above
        {
            sticker: './my-image.jpeg',
        },

        // sticker with additional `markup` property
        {
            // use this in the sticker list
            sticker: './my-image-thumb.jpeg',

            // use this markup when adding the sticker to the canvas
            markup: './my-image.jpeg',
        },
    ],
});

If the sticker object is used and both sticker and markup props are Markup objects, Doka will merge the sticker and the markup property to create the markup that is added to the canvas.

In the example below the resulting markup will have the "Hello World" text and a fontSize of .5.

Doka.create({
    stickers: [
        {
            // use this in the sticker list
            sticker: ['text', { fontSize: 0.125, text: 'Hello World' }],

            // use this markup when adding the sticker to the canvas
            markup: ['text', { fontSize: 0.5 }],
        },
    ],
});