A JavaScript Image Editor for your Website

High-performance cropping, flipping, rotating, resizing, and transforming of images.

Buy now Learn more
pqina.nl/doka

Everything you expect from an image cropper

Doka packs everything your customers need when cropping images, because of its beautiful device agnostic design it fits in everywhere.

That's not all…

  • Bright and dark theme defined with CSS Custom Properties
  • Control image brightness, contrast, exposure, and saturation.
  • Set a minimum output image size
  • Enable the resize tool to allow customisation of the output size
  • Full screen and modal layout mode
  • Set to preview mode to render on top of an existing image
  • Render as editor mode right in the webpage
  • Load file objects, URLs, and dataURLs
  • Load canvas elements and image tags
  • An intuitive user experience on all platforms
  • Load raster images like GIFs, PNGs, JPEGs and Bitmaps
  • Load, transform, and save SVGs
  • Automatically corrects photo orientation
  • Copy JPEG EXIF data to output image
  • Transform input images to other image formats
  • Compress JPEG images
  • Easily integrate with third party libraries
  • Change locale of all labels
  • Enable additonal rotate right button
  • Enable or disable aspect ratio dropdown
  • Customize aspect ratio dropdown options
  • Load images by dropping files on editor

What's on the Roadmap for the near future

  • Letterbox cropping
  • Auto color correction
  • Auto sharpen
  • Web component

Missing a feature? Let us know here

A user-friendly approach to image cropping

Empower your users to personalize their profile pages.

On big viewports we can use preview mode to help the user edit an image in place. This makes it possible to judge the result before confirming the crop.

Editing the profile picture in place would be cumbersome because of the limited space. By switching Doka to full view mode and enabling a crop mask we create more room for the editing experience and still allow previewing the result.

Hit the ground running with FilePond

Use Doka and FilePond together to create a streamlined editing and uploading experience.

Before

After

Easily integrate Doka with your project

Doka weighs around 40 Kb gzipped, is written in native JavaScript (it includes a TypeScript definition file), and has zero dependencies, therefore, it can be combined with any framework or library. Whether your project is based on React, Vue, Angular, jQuery, or something else, as long as it's based on JavaScript, Doka will fit right in.

Ships with React and Vue adapter components

With the newly added React and Vue components it's now even easier to integrate Doka in your web application.

React

{/* Render an in-page Doka editor */}
<Doka
    style={{ width: '640px', height: '480px' }}
    src={ src }
    crop={ crop }
    onConfirm={ this.handleDokaConfirm }
    onCancel={ this.handleDokaCancel }/>

{/* Toggle a fullscreen Doka modal */}
{ enabled && <DokaModal 
    src={ src }
    crop={ crop }
    onConfirm={ this.handleDokaConfirm }
    onCancel={ this.handleDokaCancel }/> }

{/* Overlay Doka on top of another element */}
<DokaOverlay 
    crop={ crop }
    src={ src }
    enabled={ enabled }
    onConfirm={ this.handleDokaConfirm }
    onCancel={ this.handleDokaCancel }>
    <img src={ image } alt=""/>
</DokaOverlay>

Vue

<!-- Render an in-page Doka editor -->
<Doka 
    ref="doka"
    style="height:400px"
    crop-aspect-ratio="1"
    :crop-aspect-ratio-options="cropOptions"
    :src="src"
    @confirm="handleDokaConfirm"
    @cancel="handleDokaCancel"/>

<!-- Toggle a fullscreen Doka modal -->
<DokaModal 
    crop-aspect-ratio="1"
    :src="src" 
    v-if="enabled"
    @confirm="handleDokaConfirm"
    @cancel="handleDokaCancel"
    @close="enabled=false"/>

<!-- Overlay Doka on top of another element -->
<DokaOverlay 
    :enabled="enabled"
    :src="imageSource" 
    :crop="imagePreviewCrop"
    @confirm="handleDokaConfirm"
    @cancel="handleDokaCancel">
    <img :src="imagePreviewSource" alt="">
</DokaOverlay>

JavaScript

// Render an in-page Doka editor
const root = document.querySelector('.my-element > div');
Doka.create(root, {
  src: './my-image.jpeg',
  onconfirm: (output) => {
    // Handle output image here
  }
});

// Toggle a fullscreen Doka modal 
Doka.create({
  src: './my-image.jpeg',
  cropAspectRatio: '16:9',
  onconfirm: (output) => {
    // Handle output image here
  }
});

// Overlay Doka on top of another element
Doka.create(root, {
  src: './my-image.jpeg',
  styleLayoutMode: 'preview',
  outputData: true,
  onconfirm: (output) => {
    // Handle output image here
  }
});

Compatible with a wide range of browsers and devices

Doka is compatible with browsers going back as far as Internet Explorer 11 and performs fine on older Android and iOS devices as well. Check the list below to make sure Doka runs on the most common browsers used by your target audience.

Desktop

  • Chrome latest
  • Firefox latest
  • Opera latest
  • Microsoft Edge 12+
  • Safari 9+ Mac
  • Internet Explorer 11

Mobile

  • Safari 9+ iOS
  • Chrome Android
  • Firefox Android

Integration with familiar File Upload libraries

The Doka API is set up to integrate beautifully with all kinds of file upload solutions. Whether you're using FilePond, Dropzone, Uppy or jQuery File Upload, installation will be a breeze.

The product package includes example integrations and helper functions for all the plugins above.

FilePond

// With FilePond we do the actual file transformation outside
// of Doka, as that allows for faster image previews
FilePond.registerPlugin(
  FilePondPluginImageExifOrientation,
  FilePondPluginImagePreview,
  FilePondPluginImageEdit,
  FilePondPluginImageCrop,
  FilePondPluginImageResize,
  FilePondPluginImageTransform
);

FilePond.create(document.querySelector('input'), {

  // Set the Doka editor as editor to use
  imageEditEditor: Doka.create({
    cropAspectRatioOptions: [
      { label: 'Free', value: null },
      { label: 'Portrait', value: 1.25 },
      { label: 'Landscape', value: .75 }
    ]
  })

  // Set other FilePond properties here
  server: '/post'

});

Dropzone

// Create a Doka Dropzone, the "useDokaWithDropzone" function automatically
// creates a "transformFile" function for use of Doka with Dropzone
Dropzone.options.dokaDropzone = {

  // Link up Dropzone with Doka using our custom "transformFile" function
  transformFile: useDokaWithDropzone({
    cropAspectRatioOptions: [
      { label: 'Free', value: null },
      { label: 'Portrait', value: 1.25 },
      { label: 'Landscape', value: .75 }
    ]
  }),

  // Set other Dropzone properties here
  url: '/post'

};

Uppy

// Create a Doka Uppy, the "useDokaWithUppy" function automatically
// creates a "onBeforeFileAdded" function for use of Doka with Uppy
const uppy = Uppy({

  // Link up Uppy with Doka using our custom "onBeforeFileAdded" function
  onBeforeFileAdded: useDokaWithUppy({
    cropAspectRatioOptions: [
      { label: 'Free', value: null },
      { label: 'Portrait', value: 1.25 },
      { label: 'Landscape', value: .75 }
    ]
  }),

  // Set other Uppy properties here
  id: 'uppy'

});

jQuery File Upload

// Link up a Doka and jQuery File Upload, the "useDokaWithJQueryFileUpload" function automatically
// adds a doka processQueue action to use Doka with jQuery File Upload
useDokaWithJQueryFileUpload({
  cropAspectRatioOptions: [
    { label: 'Free', value: null },
    { label: 'Portrait', value: 1.25 },
    { label: 'Landscape', value: .75 }
  ]
});

$('#fileupload').fileupload({

  // We'll disable image resizing, Doka will handle that
  disableImageResize: true,
  previewMaxWidth: 100,
  previewMaxHeight: 100,
  previewCrop: true,

  // Set other jQuery File Upload properties here...
  url: '/post'

});

JavaScript

// We create a Doka editor instance. Now we can use this instance
// to load file objects, it will automatically open them fullscreen
const doka = Doka.create({
  cropAspectRatioOptions: [
    { label: 'Free', value: null },
    { label: 'Portrait', value: 1.25 },
    { label: 'Landscape', value: .75 }
  ]
});

// Listen for changes on a file input element
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', e => {

  // Edit the loaded file with Doka
  doka.edit(input.files[0])
    .then(({ file }) => {
      // "file" is the transformed file object
    });

});

A word from our customers

PQINA serves over 8000 customers and is rated 4.93 out of 5 stars based on 425+ customer reviews

Package & pricing

After purchasing Doka you receive a unique license key and a package containing the license and library files. See the file tree below for a full overview of the package contents.

Package contents

The package contains various integration examples with popular file upload libraries and contains basic Doka setups for JavaScript, React, and Vue. These can all be used as a development starting point.

  • license.pdf
  • README.md
  • CHANGELOG.md
  • src
    • doka.mjs
    • doka.scss
  • bin
    • doka.min.js
    • doka.min.css
    • doka.esm.min.js
    • doka.polyfill.min.js
    • doka.esm.min.d.ts
    • react-doka
    • vue-doka
  • examples
    • native
    • react
    • vue
  • integrations
    • filepond
    • dropzone
    • uppy
    • jquery-fileupload
    • file-input

License options

Doka subscriptions start from $79/year, active subscriptions receive all the latest features and updates as well as high-quality, personal support.

  • Domain

    $79 year

    • 1 domain

      Unlimited subdomains

    • Personal support
    • Free updates
    • 30-day money-back guarantee
    • Not suitable for SaaS
  • Bundle

    $199 year

    • 5 domains

      Unlimited subdomains

    • Personal support
    • Free updates
    • 30-day money-back guarantee
    • Not suitable for SaaS
  • SaaS or App

    $749 year

    • Use in single SaaS solution…

      Single, centrally hosted, SaaS solution. Unlimited domains.

    • …or distributed application

      Application for use on mobile or desktop devices.

    • Priority support
    • Free updates
    • 30-day money-back guarantee
  • Enterprise

    $2499 year

    • Use in single organization

      Implement Doka on unlimited projects for use within a single organisation.

    • Priority support
    • Free updates
    • 30-day money-back guarantee

Should you decide not to renew your yearly subscription you may continue to use your version of Doka for life, but will receive no further updates.

If you are interested in an OEM or custom Enterprise license, or have other plans that the default license doesn’t cover, please contact us at [email protected] to get started.

Customer questions & answers

Use on different environments

Aside from the production environment, the software license covers use of Doka on developer, test, and staging environments.

Requesting a refund

30-day money-back guaranteed for any purchase under the conditions detailed in the License Agreement.

Contacting support

All licenses include support as long as the subscription has not expired. Use the support form to submit a ticket. If your license has expired, please renew the license to receive further support.

Payment options

Transactions are handled by Gumroad. The Gumroad store accepts credit cards or PayPal. For more information read the Gumroad FAQ entry on payment methods

Cancelling the subscription

When you cancel your subscription you may continue to use your current version of Doka for life, but will receive no further updates or support after the yearly term has ended.

Generating an invoice

You'll find a link to generate an invoice in the purchase confirmation email. For more information read the Gumroad FAQ entry on invoices

VAT

VAT is automatically handled by Gumroad. If you have a VAT ID you can enter it on your invoice, if you're not required to pay VAT, Gumroad will automatically issue a refund.

Other questions?

Feel free to contact us directly at [email protected]

Didn't find what you were looking for? Ask us here