Comparison of AngularJS directives for image cropping
First of all, we specified the following requirements for our new Angular Image Cropping Directive:
- Easy-to-use, nice UX
- Quite popular and stable (measured by github stars/forks/contributors and issues)
- Extendable directive options / configurable settings
- Possible to change layout
- Plays well with e.g. angular-file-upload
- Touch support (mobile-friendly)
- Features: zoom in/out, set width at hight of cropped image, etc.
AngularJS Directives for image cropping
1. ngImgCropGithub / Demo
This is the most popular module, which offers 1 directive:
-crop image="imageUrlOrBase64" result-image="croppedImage">
Just place this directive anywhere you want the cropping to happen, e.g. after an user has uploaded a file. You can also set options for the cropping area. These option values can be provided by defining area-type, result-image-size, etc. as attributes on the same element. The img-crop HTML-Tag will create a canvas element, which makes styling via CSS impossible.
Conclusion: I've used this directive a really long time and also got it working nicely with angular-file-upload (blob upload solution). It also works on mobile, but I really don't like the layout, and I also got a scope inheritance problem - that's why I did a little more research if there is something 'better' out there. There is also a fork of this repository named ngImgCropFullExtended, which gives more options and also solves some bugfixes - but also didn't solve my inheritance problem.
2. ngCropper (uses $.fn.cropper)Github / Demo
This module is only a wrapper of a simple jQuery image cropping plugin with lots of options. It adds 1 service named 'Cropper' and 1 directive to your angular app:
imageUrlOrBase64}}" ng-cropper ng-cropper-show="showEvent" width="200" height="200" />
Conclusion: The demo of the jQuery (!) Plugin looks quite awesome. But when I tried out the directive, I found it unnecessary sending $broadcast events just to show/hide the cropping area. I defined the aspectRatio option, but it didn't work as expected. That's why I checked the source code and found that this module is using an old version of the jQuery plugin. This could work very well, if you write an own wrapper for this plugin and keep the jQuery version up-to-date!
3. imageCropper (= angular-image-cropper)Github / Demo
This module is inspired by the Guillotine jQuery plugin that allows to drag, zoom or rotate an image to select a cropping area. It offers 1 directive and an extensible API:
imageUrlOrBase64}}" width="200" height="200" show-controls="false" fit-on-init="true">
The image-cropper HTML-Tag will create 2 wrapper divs and an image tag - no canvas needed. There is no dynamic creation of the resulting cropped image - you need to execute the crop function from the given API. That seems fine because you don't need an extra preview image as the cropping area is basically the preview ;)
Conclusion: I really liked the demo so I tried it out with defining my own icons for zooming and rotating. Based on the documentation, I could not figure out which options are mandatory or get information about the default values for these attributes. At first I found it quite difficult to get working crop/zoomIn/zoomOut/rotate functions. But now it works like a charm! About UX: Unfortunately I have to say that I'm not sure if the user knows that the image is draggable after uploading an avatar. That's why I added an info text ("Drag image to set right position") and an icon (move/arrows) with opacity as overlay when hovering over the image.Github / Demo
That is why I tested this plugin with a directive I quickly created on my own.
The directive code basically just links the element to the original Croppie function and this creates some DIVs with the image, zoom slider etc. There is also no canvas needed - so CSS styling is possible!
Conclusion: I know this library is not as popular as the others, but I really like the UX. It is quite similar to the facebook profile picture upload, and this may also be a positive aspect because people are used to this kind of 'cropper'. It was very easy to create my own directive, which I probably will publish soon.
Other popular directivesAdditionally I also tested the demos (using Mac OS X 10.11 with Chrome v48) of these 3 directives:
- github.com/andyshora/angular-image-crop - Demo
- Swipe to move and drag handle to zoom
- Conclusion: Better mobile than desktop support - I don't like the dragging for zooming (on desktop) - sorry!
- github.com/AllanBishop/angular-img-cropper - Demo
- Features a rectangular crop area. The crop area's aspect ratio can be enforced during dragging. The crop image can either be 1:1 or scaled to fit an area.
- Conclusion: It may sound harsh: I really don't like the yellow border color and it was not possible to change this value (hardcoded canvas strokeColor)!
- github.com/andrefarzat/ng-jcrop - Demo
- Wrapper of jCrop jQuery plugin with lots of setting options.
- Conclusion: When uploading a bigger image on the demo page, the dragging of the cropping area lags.
Our winner among AngularJS Directives is … CroppieWe chose the Croppie JS library because it creates a better user experience compared to the beautiful (3.) imageCropper module. You don't have as many possibilities as with (2.) ngCropper or (3.) imageCropper. Sometimes it is better not to overwhelm users by lots of actions. That's true for our case as our solution is just used for cropping an avatar image. If you want to add more actions (e.g. like rotating) and possibilities I recommend writing an own custom directive using (2.) $.fn.cropper!
I really liked that Croppie was so easy to implement and use. After ~4 years working with AngularJS, I really prefer AngularJS Directives, which are either wrappers for (or inspired by) jQuery plugins because jQuery plugins are more stable and therefore have less bugs and issues on GitHub.
I hope this article will help you make the right decision finding your image cropping module among AngularJS directives for your special needs. If you want to see some of the results of my coding, check out LingoHub for your next app localization project.