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 |
---|---|---|
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 |
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. |
'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.
- The name of the color.
- The value of the color.
- 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.
- The name to show in the dropdown.
- 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.
- The name to show in the dropdown.
- 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.
- The name to show in the dropdown.
- The stroke width to use.
- The stroke style to use (dashed or not).
- 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.
- The name to show in the dropdown.
- The line width to use.
- The line style to use (dashed or not).
- 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.
- The name to show in the dropdown.
- 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 }],
},
],
});