9

I want to let the user crop an image, I found this JQuery plugin - http://deepliquid.com/content/Jcrop.html

I tried to use it with Angular-ui's Jquery passthrough option, adding the ui-jq=Jcrop directive to the <img>

The problem is that If I use ng-src to dynamically change the image it doesn't work and nothing is seen. If I change it to src and put a static url I can see the image and Jcrop.

how can I fix that ? also, how can I listen to Jcrop's callbacks to know what is the user's selection ?

is there a better / simpler way to add image cropping functionality to AngularJS ?

Gal Ben-Haim
  • 17,433
  • 22
  • 78
  • 131
  • BTW, Angular UI's jQuery Passthru Directive has been moved to https://github.com/angular-ui/ui-utils/tree/master/modules/jq – Pascal Aug 23 '13 at 12:18
  • I updated the plnkr which shows the cropped image here:http://plnkr.co/edit/Iizykd7UORy3po1h5mfm?p=preview. and look at the post for more details on using the directive for image cropping: http://coding-issues.blogspot.in/2013/10/angularjs-directive-for-image-cropping.html – Ranadheer Reddy Oct 11 '13 at 09:20
  • I think there is a better way to add image cropping functionality, because the angular directive for Jcrop is not up-to-date. I wrote a blog post about comparing image crop AngularJS directives: https://lingohub.com/blog/2016/03/angularjs-directives-image-cropping/ – Betty St Mar 10 '16 at 09:10

3 Answers3

9

Here is my solution:

I've written a directive that create img element and apply plugin on it. When src is changed, this img is removed and content that was created by plugin is also destroyed and then re-created new img with new src and again applied plugin on it.

Also provided 'selected' callback to be able to get coordinated that were selected (wrapped in $apply so you can modify your scope values in it).

Check my solution at Plunker

Valentyn Shybanov
  • 19,331
  • 7
  • 66
  • 59
  • if I use your solution with setSelect for JCrop option it result in `Error: $digest already in progress` even if I try to wrap the `scope.$apply` statement with `if (!scope.$$phase)` how can I fix this ? – Gal Ben-Haim Jan 16 '13 at 17:16
  • Can you fork my Plunker and add how you use setSelect? – Valentyn Shybanov Jan 17 '13 at 00:02
  • setSelect is working fine, I'm inserting an image from a url that is given in an input text, and I have another directive on the textbox to validate that the url is an image. this is too confused and causing problems. how can I add image validation to your directive like 'imageOK' that will say if the src url is indeed an image. also I want to hide the element in case its invalid so that small missing image icon won't show. I'm new to directives and its very confusing me :-) – Gal Ben-Haim Jan 17 '13 at 08:38
  • I propose to do just way: bind 'url' to input where user can input his url. Then at controller addd `$watch('url',...)` and there do validation and upon successfull validation update `$scope.imageUrl` and bing directive to `imageUrl` (not `url`) – Valentyn Shybanov Jan 17 '13 at 21:41
  • I have some issues with the directive, if you please look at http://stackoverflow.com/questions/14504393/how-to-fix-this-angularjs-jcrop-directive – Gal Ben-Haim Jan 24 '13 at 15:04
  • @ValentynShybanov, sorry for asking this, could you change your code to file upload? E.g instead of the click event which send the src of the img to the img-cropped src, the src now will be fetched from the uploaded file. Something like preview. – Wondering Coder Oct 24 '13 at 06:26
6

I've built a demo using AngularJS and Jcrop here:

Demo: https://coolaj86.github.com/angular-image-crop

On Github: https://github.com/coolaj86/angular-image-crop

coolaj86
  • 74,004
  • 20
  • 105
  • 125
1

You can leverage ui-event to create an event definition object with the keys being the event names and the values being the callbacks. Or you can simply pass these events as options to Jcrop (according to the documentation)

Finally, there is a new update coming to ui-jq that lets you add ui-refresh which is an expression to be watched to re-trigger the plugin.

Theoretically you should be able to do

<img ui-jq="Jcrop" 
     ui-options="{onSelect:myCallback}"
     ui-event="{onChange:'myCallback($event)'}"
     ui-refresh="imgSrc"
     ng-src="imgSrc" />

Note: this simply re-fires the passthrough again, and doesn't automatically mean this will fix the problem or that the plugin will behave properly when re-initialized

We're still working on a good way to allow you to trigger different events at different times.

ProLoser
  • 4,616
  • 2
  • 16
  • 23
  • As I understand, ui-refresh will just re-fire plugin, calling it again on same element. But there are lot of plugins that will add many extra elements with some content even outside of source element. For example Jcrop plugin will add `
    ` after ``. So just re-firing plugin again will not update or remove-add this dynamic content. Personally I do not know, how tracking of what plugin added could be done for any generic plugin...
    – Valentyn Shybanov Jan 15 '13 at 09:19
  • It's a call you'd have to make on a plugin-by-plugin basis as some plugins simply update or refresh. – ProLoser Jan 16 '13 at 00:00