Advanced Custom Fields: Image Crop Add-on - Version 1.4.7

Version Description

Download this release

Release Info

Developer andersthorborg
Plugin Icon wp plugin Advanced Custom Fields: Image Crop Add-on
Version 1.4.7
Comparing to
See all releases

Code changes from version 1.4.4 to 1.4.7

acf-image-crop-v4.php CHANGED
@@ -361,7 +361,7 @@ class acf_field_image_crop extends acf_field_image
361
  $height = $height * 2;
362
  }
363
  ?>
364
- <div class="acf-image-uploader clearfix <?php echo $o['class']; ?>" data-field-id="<?php echo $field['key'] ?>" data-preview_size="<?php echo $field['preview_size']; ?>" data-library="<?php echo isset($field['library']) ? $field['library'] : 'all'; ?>" data-width="<?php echo $width ?>" data-height="<?php echo $height ?>" data-crop-type="<?php echo $field['crop_type'] ?>" <?php echo ($field['force_crop'] == 'yes' ? 'data-force-crop="true"' : '')?> data-save-to-media-library="<?php echo $field['save_in_media_library'] ?>" >
365
  <input class="acf-image-value" data-original-image="<?php echo $imageData->original_image ?>" data-cropped-image="<?php echo json_encode($imageData->cropped_image) ?>" type="hidden" name="<?php echo $field['name']; ?>" value="<?php echo htmlspecialchars($field['value']); ?>" />
366
  <div class="has-image">
367
  <div class="image-section">
361
  $height = $height * 2;
362
  }
363
  ?>
364
+ <div class="acf-image-uploader clearfix acf-image-crop <?php echo $o['class']; ?>" data-field-id="<?php echo $field['key'] ?>" data-preview_size="<?php echo $field['preview_size']; ?>" data-library="<?php echo isset($field['library']) ? $field['library'] : 'all'; ?>" data-width="<?php echo $width ?>" data-height="<?php echo $height ?>" data-crop-type="<?php echo $field['crop_type'] ?>" <?php echo ($field['force_crop'] == 'yes' ? 'data-force-crop="true"' : '')?> data-save-to-media-library="<?php echo $field['save_in_media_library'] ?>" >
365
  <input class="acf-image-value" data-original-image="<?php echo $imageData->original_image ?>" data-cropped-image="<?php echo json_encode($imageData->cropped_image) ?>" type="hidden" name="<?php echo $field['name']; ?>" value="<?php echo htmlspecialchars($field['value']); ?>" />
366
  <div class="has-image">
367
  <div class="image-section">
acf-image-crop-v5.php CHANGED
@@ -349,8 +349,8 @@ class acf_field_image_crop extends acf_field_image {
349
  </div>
350
  <div class="view show-if-value acf-soh">
351
  <ul class="acf-hl acf-soh-target">
352
- <li><a class="acf-icon dark" data-name="edit" href="#"><i class="acf-sprite-edit"></i></a></li>
353
- <li><a class="acf-icon dark" data-name="remove" href="#"><i class="acf-sprite-delete"></i></a></li>
354
  </ul>
355
  <img data-name="image" src="<?php echo $url; ?>" alt=""/>
356
  <div class="crop-section">
@@ -466,7 +466,6 @@ class acf_field_image_crop extends acf_field_image {
466
 
467
 
468
  function input_admin_enqueue_scripts() {
469
-
470
  $dir = plugin_dir_url( __FILE__ );
471
 
472
 
@@ -529,6 +528,9 @@ class acf_field_image_crop extends acf_field_image {
529
  // Get image editor from original image path to crop the image
530
  $image = wp_get_image_editor( $mediaDir['basedir'] . '/' . $originalImageData['file'] );
531
 
 
 
 
532
  if(! is_wp_error( $image ) ){
533
 
534
  // Crop the image using the provided measurements
349
  </div>
350
  <div class="view show-if-value acf-soh">
351
  <ul class="acf-hl acf-soh-target">
352
+ <li><a class="acf-icon -pencil dark" data-name="edit" href="#"><i class="acf-sprite-edit"></i></a></li>
353
+ <li><a class="acf-icon -cancel dark" data-name="remove" href="#"><i class="acf-sprite-delete"></i></a></li>
354
  </ul>
355
  <img data-name="image" src="<?php echo $url; ?>" alt=""/>
356
  <div class="crop-section">
466
 
467
 
468
  function input_admin_enqueue_scripts() {
 
469
  $dir = plugin_dir_url( __FILE__ );
470
 
471
 
528
  // Get image editor from original image path to crop the image
529
  $image = wp_get_image_editor( $mediaDir['basedir'] . '/' . $originalImageData['file'] );
530
 
531
+ // Set quality
532
+ $image->set_quality( apply_filters('acf-image-crop/image-quality', 100) );
533
+
534
  if(! is_wp_error( $image ) ){
535
 
536
  // Crop the image using the provided measurements
acf-image-crop.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Advanced Custom Fields: Image Crop Add-on
4
  Plugin URI: https://github.com/andersthorborg/ACF-Image-Crop
5
  Description: An image field making it possible/required for the user to crop the selected image to the specified image size or dimensions
6
- Version: 1.4.4
7
  Author: Anders Thorborg
8
  Author URI: http://thorb.org
9
  License: GPLv2 or later
3
  Plugin Name: Advanced Custom Fields: Image Crop Add-on
4
  Plugin URI: https://github.com/andersthorborg/ACF-Image-Crop
5
  Description: An image field making it possible/required for the user to crop the selected image to the specified image size or dimensions
6
+ Version: 1.4.7
7
  Author: Anders Thorborg
8
  Author URI: http://thorb.org
9
  License: GPLv2 or later
css/input.css CHANGED
@@ -1,30 +1,30 @@
1
- .field_type-image_crop .crop-stage .crop-image{
2
  max-width:100%;
3
  }
4
- .field_type-image_crop .crop-stage .crop-action{
5
  float:left;
6
  width:65%;
7
  }
8
- .field_type-image_crop .crop-stage .crop-preview{
9
  float:right;
10
  /* changed */
11
  width: 30%;
12
  /* changed END */
13
  }
14
  /* added */
15
- .field_type-image_crop .crop-stage .crop-action h4,
16
- .field_type-image_crop .crop-stage .crop-preview h4{
17
  margin-top:0;
18
  }
19
- .field_type-image_crop .error{
20
  margin-top: 20px !important;
21
  }
22
  /* added END */
23
- .field_type-image_crop .crop-stage .crop-preview .preview{
24
  width:100%;
25
  }
26
 
27
- .field_type-image_crop .crop-stage .crop-preview .crop-controls{
28
  padding-top:20px;
29
  clear: both;
30
  /* added */
@@ -32,10 +32,10 @@
32
  /* added END */
33
  }
34
 
35
- .field_type-image_crop .crop-section .crop-stage, .field_type-image_crop.cropping .image-section, .field_type-image_crop.cropping .init-crop-button{
36
  display:none;
37
  }
38
- .field_type-image_crop.cropping .crop-stage {
39
  display:block;
40
  position:fixed;
41
  top:60px;
@@ -53,11 +53,11 @@
53
  /* changed END */
54
 
55
  }
56
- .field_type-image_crop.cropping .has-image, .field_type-image_crop.cropping .crop-section{
57
  width:100%;
58
  }
59
 
60
- .field_type-image_crop .crop-stage.loading .crop-controls{
61
  -webkit-transition: opacity 300ms;
62
  -moz-transition: opacity 300ms;
63
  -ms-transition: opacity 300ms;
1
+ .acf-image-crop .crop-stage .crop-image{
2
  max-width:100%;
3
  }
4
+ .acf-image-crop .crop-stage .crop-action{
5
  float:left;
6
  width:65%;
7
  }
8
+ .acf-image-crop .crop-stage .crop-preview{
9
  float:right;
10
  /* changed */
11
  width: 30%;
12
  /* changed END */
13
  }
14
  /* added */
15
+ .acf-image-crop .crop-stage .crop-action h4,
16
+ .acf-image-crop .crop-stage .crop-preview h4{
17
  margin-top:0;
18
  }
19
+ .acf-image-crop .error{
20
  margin-top: 20px !important;
21
  }
22
  /* added END */
23
+ .acf-image-crop .crop-stage .crop-preview .preview{
24
  width:100%;
25
  }
26
 
27
+ .acf-image-crop .crop-stage .crop-preview .crop-controls{
28
  padding-top:20px;
29
  clear: both;
30
  /* added */
32
  /* added END */
33
  }
34
 
35
+ .acf-image-crop .crop-section .crop-stage, .acf-image-crop.cropping .image-section, .acf-image-crop.cropping .init-crop-button{
36
  display:none;
37
  }
38
+ .acf-image-crop.cropping .crop-stage {
39
  display:block;
40
  position:fixed;
41
  top:60px;
53
  /* changed END */
54
 
55
  }
56
+ .acf-image-crop.cropping .has-image, .acf-image-crop.cropping .crop-section{
57
  width:100%;
58
  }
59
 
60
+ .acf-image-crop .crop-stage.loading .crop-controls{
61
  -webkit-transition: opacity 300ms;
62
  -moz-transition: opacity 300ms;
63
  -ms-transition: opacity 300ms;
js/input-old.js CHANGED
@@ -1,142 +1,335 @@
1
  (function($){
 
2
 
 
 
3
 
4
- function initialize_field( $el ) {
5
- var $field = $el, $options = $el.find('.acf-image-uploader');
6
- $field.find('.acf-image-value').on('change', function(){
7
- var originalImage = $(this).val();
8
- if($(this).val()){
9
- $field.removeClass('invalid');
10
- $field.find('.init-crop-button').removeAttr('disabled');
11
- $field.find('.acf-image-value').data('original-image', originalImage);
12
- $field.find('.acf-image-value').data('cropped-image', originalImage);
13
- $field.find('.acf-image-value').data('cropped', false);
14
- $.post(ajaxurl, {action: 'acf_image_crop_get_image_size', image_id: originalImage}, function(data, textStatus, xhr) {
15
- if($field.find('img.crop-image').length == 0){
16
- $field.find('.crop-action').append($('<img class="crop-image" src="#"/>'));
17
- }
18
- $field.find('img.crop-image').attr('src', data['url']);
19
- $field.find('img.crop-image').data('width', data['width']);
20
- $field.find('img.crop-image').data('height', data['height']);
21
- var warnings = [];
22
- var valid = true;
23
- if($options.data('width') && data['width'] < $options.data('width')){
24
- warnings.push('Width should be at least: ' + $options.data('width') + 'px (Selected image width: ' + data['width'] + 'px)');
25
- valid = false;
26
- }
27
- if($options.data('height') && data['height'] < $options.data('height')){
28
- warnings.push('Height should be at least: ' + $options.data('height') + 'px (Selected image height: ' + data['height'] + 'px)');
29
- valid = false;
30
- }
31
- if(!valid){
32
- $field.addClass('invalid');
33
- $field.find('.init-crop-button').attr('disabled', 'disabled');
34
- alert('Warning: The selected image is smaller than the required size:\n' + warnings.join('\n'));
35
- }
36
- else{
37
- if($options.data('force_crop')){
38
- initCrop($field);
39
- }
40
- }
41
-
42
- }, 'json');
43
- updateFieldValue($field);
44
- }
45
- else{
46
- //Do nothing
47
- }
48
-
49
- });
50
- $field.find('.init-crop-button').click(function(e){
51
- e.preventDefault();
52
- initCrop($field);
53
- });
54
- $field.find('.perform-crop-button').click(function(e){
55
- e.preventDefault();
56
- performCrop($field);
57
- });
58
- $field.find('.cancel-crop-button').click(function(e){
59
- e.preventDefault();
60
- cancelCrop($field);
61
- });
62
- $field.find('[data-name=edit]').click(function(e){
63
- e.preventDefault();
64
- e.stopPropagation();
65
- var id = $field.find('.acf-image-value').data('cropped-image');
66
- if(!$.isNumeric(id)){
67
- id = $field.find('.acf-image-value').data('original-image');;
68
- }
69
- acf.media.popup({
70
- mode : 'edit',
71
- title : acf._e('image', 'edit'),
72
- button : acf._e('image', 'update'),
73
- id : id
74
- });
75
- });
76
-
77
- }
78
-
79
- function initCrop($field){
80
- var $options = $field.find('.acf-image-uploader');
81
- var options = {
82
- handles: true,
83
- onSelectEnd: function (img, selection) {
84
- updateThumbnail($field, img, selection);
85
- updateCropData($field, img, selection);
86
- },
87
- imageWidth:$options.find('.crop-stage img.crop-image').data('width'),
88
- imageHeight:$options.find('.crop-stage img.crop-image').data('height'),
89
- x1: 0,
90
- y1: 0
91
- };
92
- if($options.data('crop_type') == 'hard'){
93
- options.aspectRatio = $options.data('width') + ':' + $options.data('height');
94
- options.minWidth = $options.data('width');
95
- options.minHeight = $options.data('height');
96
- options.x2 = $options.data('width');
97
- options.y2 = $options.data('height');
98
- }
99
- else if($options.data('crop_type') == 'min'){
100
- if($options.data('width')){
101
- options.minWidth = $options.data('width');
102
- options.x2 = $options.data('width');
103
- }
104
- else{
105
- options.x2 = options.imageWidth;
106
- }
107
- if($options.data('height')){
108
- options.minHeight = $options.data('height');
109
- options.y2 = $options.data('height');
110
- }
111
- else{
112
- options.y2 = options.imageHeight;
113
- }
114
- }
115
- // Center crop - disabled needs more testing
116
- // options.x1 = options.imageWidth/2 - (options.minWidth/2);
117
- // options.y1 = options.imageHeight/2 - (options.minHeight/2)
118
- // options.x2 = options.minWidth + options.x1;
119
- // options.y2 = options.minHeight + options.y1;
120
- //options.y1 = (options.imageHeight - options.minHeight) / 2;
121
- if(!$field.hasClass('invalid')){
122
- toggleCropView($field);
123
- $field.find('.crop-stage img.crop-image').imgAreaSelect(options);
124
- updateCropData($field, $field.find('.crop-stage img.crop-image').get(0), {y1: options.y1, y2: options.y2, x1: options.x1, x2: options.x2});
125
- updateThumbnail($field, $field.find('.crop-stage img.crop-image').get(0), {y1: options.y1, y2: options.y2, x1: options.x1, x2: options.x2});
126
- }
127
- }
128
-
129
- function updateCropData($field, img, selection){
130
- var $options = $field.find('.acf-image-uploader');
131
- $options.data('x1', selection.x1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  $options.data('x2', selection.x2);
133
  $options.data('y1', selection.y1);
134
  $options.data('y2', selection.y2);
135
- }
136
 
137
- function updateThumbnail($field, img, selection){
138
- var $options = $field.find('.acf-image-uploader');
139
- var div = $field.find('.crop-preview .preview');
 
140
  var targetWidth = $field.find('.crop-preview .preview').width();
141
  var factor = targetWidth / (selection.x2 - selection.x1);
142
  //image
@@ -145,140 +338,148 @@
145
  div.css('width', (selection.x2 - selection.x1) * factor);
146
  //height
147
  div.css('height', (selection.y2 - selection.y1) * factor);
148
- //x offset
149
- div.css('background-position-x', 0-(selection.x1 * factor));
150
- //y offset
151
- div.css('background-position-y', 0-(selection.y1 * factor));
 
 
152
  div.css('background-size', $options.find('.crop-stage img.crop-image').data('width') * factor + 'px' + ' ' + $options.find('.crop-stage img.crop-image').data('height') * factor + 'px');
153
- }
154
-
155
- function generateCropJSON(originalImage, croppedImage){
156
- var obj = {
157
- original_image: originalImage,
158
- cropped_image: croppedImage
159
- }
160
- return JSON.stringify(obj);
161
- }
162
-
163
- function performCrop($field){
164
- if(!$field.find('.crop-stage').hasClass('loading')){
165
- $field.find('.crop-stage').addClass('loading');
166
- var $options = $field.find('.acf-image-uploader');
167
- var targetWidth = $options.data('width');
168
- var targetHeight = $options.data('height');
169
- var saveToMediaLibrary = $options.data('save_to_media_library');
170
- if($options.data('crop_type') == 'min'){
171
- targetWidth = $options.data('x2') - $options.data('x1');
172
- targetHeight = $options.data('y2') - $options.data('y1');
173
- }
174
- var data = {
175
- action: 'acf_image_crop_perform_crop',
176
- id: $field.find('.acf-image-value').data('original-image'),
177
- x1: $options.data('x1'),
178
- x2: $options.data('x2'),
179
- y1: $options.data('y1'),
180
- y2: $options.data('y2'),
181
- target_width: targetWidth,
182
- target_height: targetHeight,
183
- preview_size: $options.data('preview_size'),
184
- save_to_media_library: saveToMediaLibrary
185
- }
186
- $.post(ajaxurl, data, function(data, textStatus, xhr) {
187
- $field.find('[data-name=image]').attr('src', data.preview_url);
188
- $field.find('.acf-image-value').data('cropped-image', data.value);
189
- $field.find('.acf-image-value').data('cropped', true);
190
- updateFieldValue($field);
191
- $field.find('.crop-stage').removeClass('loading');
192
- cancelCrop($field);
193
- }, 'json');
194
- }
195
- }
196
-
197
- function cancelCrop($field){
198
- toggleCropView($field);
199
- $field.find('.crop-stage img.crop-image').imgAreaSelect({remove:true});
200
- }
201
-
202
- function toggleCropView($field){
203
- if($field.hasClass('cropping')){
204
- $('#acf-image-crop-overlay').remove();
205
- }
206
- else{
207
- $('body').append($('<div id="acf-image-crop-overlay"></div>'));
208
- }
209
- $field.toggleClass('cropping');
210
-
211
- }
212
-
213
- function updateFieldValue($field){
214
- var $input = $field.find('.acf-image-value');
215
- $input.val(generateCropJSON($input.data('original-image'), $input.data('cropped-image')));
216
- }
217
-
218
- function getFullImageUrl(id, callback){
219
- $.post(ajaxurl, {images: []}, function(data, textStatus, xhr) {
220
- }, 'json');
221
- }
222
-
223
-
224
- if( typeof acf.add_action !== 'undefined' ) {
225
-
226
- /*
227
- * ready append (ACF5)
228
- *
229
- * These are 2 events which are fired during the page load
230
- * ready = on page load similar to $(document).ready()
231
- * append = on new DOM elements appended via repeater field
232
- *
233
- * @type event
234
- * @date 20/07/13
235
- *
236
- * @param $el (jQuery selection) the jQuery element which contains the ACF fields
237
- * @return n/a
238
- */
239
-
240
- acf.add_action('ready append', function( $el ){
241
-
242
- // search $el for fields of type 'image_crop'
243
- acf.get_fields({ type : 'image_crop'}, $el).each(function(){
244
-
245
- initialize_field( $(this) );
246
-
247
- });
248
-
249
- });
250
-
251
-
252
- } else {
253
-
254
-
255
- /*
256
- * acf/setup_fields (ACF4)
257
- *
258
- * This event is triggered when ACF adds any new elements to the DOM.
259
- *
260
- * @type function
261
- * @since 1.0.0
262
- * @date 01/01/12
263
- *
264
- * @param event e: an event object. This can be ignored
265
- * @param Element postbox: An element which contains the new HTML
266
- *
267
- * @return n/a
268
- */
269
-
270
- $(document).live('acf/setup_fields', function(e, postbox){
271
-
272
- $(postbox).find('.field[data-field_type="image_crop"]').each(function(){
273
-
274
- initialize_field( $(this) );
275
-
276
- });
277
-
278
- });
279
-
280
-
281
- }
 
 
 
 
 
 
282
 
283
 
284
  })(jQuery);
1
  (function($){
2
+ acf.fields.image_crop = acf.field.extend({
3
 
4
+ type: 'image_crop',
5
+ $el: null,
6
 
7
+ events: {
8
+ 'click [data-name="add"]': 'add',
9
+ 'click [data-name="edit"]': 'edit',
10
+ 'click [data-name="remove"]': 'remove',
11
+ },
12
+
13
+ focus: function(){
14
+
15
+ this.$el = this.$field.find('.acf-image-uploader');
16
+
17
+ this.settings = acf.get_data( this.$el );
18
+
19
+ },
20
+
21
+ add: function() {
22
+
23
+ // reference
24
+ var self = this;
25
+
26
+
27
+ // vars
28
+ var field_key = acf.get_data( this.$field, 'key' );
29
+
30
+
31
+ // get repeater
32
+ var $repeater = acf.get_closest_field( this.$field, {type:'repeater'} );
33
+
34
+
35
+ // popup
36
+ var frame = acf.media.popup({
37
+ 'title' : acf._e('image', 'select'),
38
+ 'mode' : 'select',
39
+ 'type' : 'image',
40
+ 'multiple' : $repeater.exists(),
41
+ 'library' : this.settings.library,
42
+ 'select' : function( attachment, i ) {
43
+
44
+ // select / add another image field?
45
+ if( i > 0 ) {
46
+
47
+ // vars
48
+ var $tr = self.$field.parent(),
49
+ $next = false;
50
+
51
+
52
+ // find next image field
53
+ $tr.nextAll('.acf-row').not('.clone').each(function(){
54
+
55
+ // get next $field
56
+ $next = acf.get_field( field_key, $(this) );
57
+
58
+
59
+ // bail early if $next was not found
60
+ if( !$next ) {
61
+
62
+ return;
63
+
64
+ }
65
+
66
+
67
+ // bail early if next file uploader has value
68
+ if( $next.find('.acf-image-uploader.has-value').exists() ) {
69
+
70
+ $next = false;
71
+ return;
72
+
73
+ }
74
+
75
+
76
+ // end loop if $next is found
77
+ return false;
78
+
79
+ });
80
+
81
+
82
+ // add extra row if next is not found
83
+ if( !$next ) {
84
+
85
+ $tr = acf.fields.repeater.doFocus( $repeater ).add();
86
+
87
+
88
+ // bail early if no $tr (maximum rows hit)
89
+ if( !$tr ) {
90
+
91
+ return false;
92
+
93
+ }
94
+
95
+
96
+ // get next $field
97
+ $next = acf.get_field( field_key, $tr );
98
+
99
+ }
100
+
101
+
102
+ // update $el
103
+ self.doFocus( $next );
104
+
105
+ }
106
+
107
+
108
+ // add file to field
109
+ self.render( attachment );
110
+
111
+ }
112
+ });
113
+
114
+
115
+ },
116
+
117
+ render: function( attachment ){
118
+
119
+ // override url
120
+ if( acf.isset(attachment, 'attributes', 'sizes', this.settings.preview_size, 'url') ) {
121
+
122
+ attachment.url = attachment.attributes.sizes[ this.settings.preview_size ].url;
123
+
124
+ }
125
+ // set url to default url in case preview size does not exist
126
+ else if(acf.isset(attachment, 'attributes', 'url')){
127
+
128
+ attachment.url = attachment.attributes.url;
129
+ }
130
+
131
+ // set atts
132
+ this.$el.find('[data-name="image"]').attr( 'src', attachment.url );
133
+ this.$el.find('[data-name="id"]').val( attachment.id ).trigger('change');
134
+
135
+
136
+ // set div class
137
+ this.$el.addClass('has-value');
138
+
139
+ },
140
+
141
+ edit: function() {
142
+
143
+ // reference
144
+ var self = this;
145
+
146
+
147
+ // vars
148
+ var id = this.$el.find('[data-name="id"]').val();
149
+
150
+
151
+ // popup
152
+ var frame = acf.media.popup({
153
+
154
+ title: acf._e('image', 'edit'),
155
+ button: acf._e('image', 'update'),
156
+ mode: 'edit',
157
+ id: id,
158
+
159
+ select: function( attachment, i ) {
160
+
161
+ // add file to field
162
+ self.render( attachment );
163
+
164
+ }
165
+
166
+ });
167
+
168
+ },
169
+
170
+ remove: function() {
171
+
172
+ // vars
173
+ var attachment = {
174
+ id: '',
175
+ url: ''
176
+ };
177
+
178
+
179
+ // add file to field
180
+ this.render( attachment );
181
+
182
+
183
+ // remove class
184
+ this.$el.removeClass('has-value');
185
+
186
+ }
187
+
188
+ });
189
+
190
+ function initialize_field( $el ) {
191
+ var $field = $el, $options = $el.find('.acf-image-uploader');
192
+ $field.find('.acf-image-value').on('change', function(){
193
+ var originalImage = $(this).val();
194
+ if($(this).val()){
195
+ $field.removeClass('invalid');
196
+ $field.find('.init-crop-button').removeAttr('disabled');
197
+ $field.find('.acf-image-value').data('original-image', originalImage);
198
+ $field.find('.acf-image-value').data('cropped-image', originalImage);
199
+ $field.find('.acf-image-value').data('cropped', false);
200
+ $.post(ajaxurl, {action: 'acf_image_crop_get_image_size', image_id: originalImage}, function(data, textStatus, xhr) {
201
+ if($field.find('img.crop-image').length == 0){
202
+ $field.find('.crop-action').append($('<img class="crop-image" src="#"/>'));
203
+ }
204
+ $field.find('img.crop-image').attr('src', data['url']);
205
+ $field.find('img.crop-image').data('width', data['width']);
206
+ $field.find('img.crop-image').data('height', data['height']);
207
+ var warnings = [];
208
+ var valid = true;
209
+ if($options.data('width') && data['width'] < $options.data('width')){
210
+ // changed for translation
211
+ warnings.push( acf._e('image_crop', 'width_should_be') + $options.data('width') + 'px\n' + acf._e('image_crop', 'selected_width') + data['width'] + 'px');
212
+ // changed END
213
+ valid = false;
214
+ }
215
+ if($options.data('height') && data['height'] < $options.data('height')){
216
+ // changed for translation
217
+ warnings.push(acf._e('image_crop', 'height_should_be') + $options.data('height') + 'px\n' + acf._e('image_crop', 'selected_height') + data['height'] + 'px');
218
+ // changed END
219
+ valid = false;
220
+ }
221
+ if(!valid){
222
+ $field.addClass('invalid');
223
+ $field.find('.init-crop-button').attr('disabled', 'disabled');
224
+ // changed for translation
225
+ alert(acf._e('image_crop', 'size_warning') + '\n\n' + warnings.join('\n\n'));
226
+ // changed END
227
+ }
228
+ else{
229
+ if($options.data('force_crop')){
230
+ initCrop($field);
231
+ }
232
+ }
233
+
234
+ }, 'json');
235
+ updateFieldValue($field);
236
+ }
237
+ else{
238
+ //Do nothing
239
+ }
240
+
241
+ });
242
+ $field.find('.init-crop-button').click(function(e){
243
+ e.preventDefault();
244
+ initCrop($field);
245
+ });
246
+ $field.find('.perform-crop-button').click(function(e){
247
+ e.preventDefault();
248
+ performCrop($field);
249
+ });
250
+ $field.find('.cancel-crop-button').click(function(e){
251
+ e.preventDefault();
252
+ cancelCrop($field);
253
+ });
254
+ $field.find('[data-name=edit]').click(function(e){
255
+ e.preventDefault();
256
+ e.stopPropagation();
257
+ var id = $field.find('.acf-image-value').data('cropped-image');
258
+ if(!$.isNumeric(id)){
259
+ id = $field.find('.acf-image-value').data('original-image');;
260
+ }
261
+ acf.media.popup({
262
+ mode : 'edit',
263
+ title : acf._e('image', 'edit'),
264
+ button : acf._e('image', 'update'),
265
+ id : id
266
+ });
267
+ });
268
+
269
+ }
270
+
271
+ function initCrop($field){
272
+ var $options = $field.find('.acf-image-uploader');
273
+ var options = {
274
+ handles: true,
275
+ onSelectEnd: function (img, selection) {
276
+ updateThumbnail($field, img, selection);
277
+ updateCropData($field, img, selection);
278
+ },
279
+ imageWidth:$options.find('.crop-stage img.crop-image').data('width'),
280
+ imageHeight:$options.find('.crop-stage img.crop-image').data('height'),
281
+ x1: 0,
282
+ y1: 0
283
+ };
284
+ if($options.data('crop_type') == 'hard'){
285
+ options.aspectRatio = $options.data('width') + ':' + $options.data('height');
286
+ options.minWidth = $options.data('width');
287
+ options.minHeight = $options.data('height');
288
+ options.x2 = $options.data('width');
289
+ options.y2 = $options.data('height');
290
+ }
291
+ else if($options.data('crop_type') == 'min'){
292
+ if($options.data('width')){
293
+ options.minWidth = $options.data('width');
294
+ options.x2 = $options.data('width');
295
+ }
296
+ else{
297
+ options.x2 = options.imageWidth;
298
+ }
299
+ if($options.data('height')){
300
+ options.minHeight = $options.data('height');
301
+ options.y2 = $options.data('height');
302
+ }
303
+ else{
304
+ options.y2 = options.imageHeight;
305
+ }
306
+ }
307
+ // Center crop - disabled needs more testing
308
+ // options.x1 = options.imageWidth/2 - (options.minWidth/2);
309
+ // options.y1 = options.imageHeight/2 - (options.minHeight/2)
310
+ // options.x2 = options.minWidth + options.x1;
311
+ // options.y2 = options.minHeight + options.y1;
312
+ //options.y1 = (options.imageHeight - options.minHeight) / 2;
313
+ if(!$field.hasClass('invalid')){
314
+ toggleCropView($field);
315
+ $field.find('.crop-stage img.crop-image').imgAreaSelect(options);
316
+ updateCropData($field, $field.find('.crop-stage img.crop-image').get(0), {y1: options.y1, y2: options.y2, x1: options.x1, x2: options.x2});
317
+ updateThumbnail($field, $field.find('.crop-stage img.crop-image').get(0), {y1: options.y1, y2: options.y2, x1: options.x1, x2: options.x2});
318
+ }
319
+ }
320
+
321
+ function updateCropData($field, img, selection){
322
+ var $options = $field.find('.acf-image-uploader');
323
+ $options.data('x1', selection.x1);
324
  $options.data('x2', selection.x2);
325
  $options.data('y1', selection.y1);
326
  $options.data('y2', selection.y2);
327
+ }
328
 
329
+ function updateThumbnail($field, img, selection){
330
+ console.log('updating thumbnail');
331
+ var $options = $field.find('.acf-image-uploader');
332
+ var div = $field.find('.crop-preview .preview');
333
  var targetWidth = $field.find('.crop-preview .preview').width();
334
  var factor = targetWidth / (selection.x2 - selection.x1);
335
  //image
338
  div.css('width', (selection.x2 - selection.x1) * factor);
339
  //height
340
  div.css('height', (selection.y2 - selection.y1) * factor);
341
+
342
+ // Set offset - Fix by @christdg
343
+ pos_x = 0-(selection.x1 * factor);
344
+ pos_y = 0-(selection.y1 * factor);
345
+ div.css('background-position', pos_x + 'px ' + pos_y + 'px');
346
+
347
  div.css('background-size', $options.find('.crop-stage img.crop-image').data('width') * factor + 'px' + ' ' + $options.find('.crop-stage img.crop-image').data('height') * factor + 'px');
348
+ }
349
+
350
+ function generateCropJSON(originalImage, croppedImage){
351
+ var obj = {
352
+ original_image: originalImage,
353
+ cropped_image: croppedImage
354
+ }
355
+ return JSON.stringify(obj);
356
+ }
357
+
358
+ function performCrop($field){
359
+ if(!$field.find('.crop-stage').hasClass('loading')){
360
+ $field.find('.crop-stage').addClass('loading');
361
+ var $options = $field.find('.acf-image-uploader');
362
+ var targetWidth = $options.data('width');
363
+ var targetHeight = $options.data('height');
364
+ var saveToMediaLibrary = $options.data('save_to_media_library');
365
+ if($options.data('crop_type') == 'min'){
366
+ targetWidth = $options.data('x2') - $options.data('x1');
367
+ targetHeight = $options.data('y2') - $options.data('y1');
368
+ }
369
+ var data = {
370
+ action: 'acf_image_crop_perform_crop',
371
+ id: $field.find('.acf-image-value').data('original-image'),
372
+ x1: $options.data('x1'),
373
+ x2: $options.data('x2'),
374
+ y1: $options.data('y1'),
375
+ y2: $options.data('y2'),
376
+ target_width: targetWidth,
377
+ target_height: targetHeight,
378
+ preview_size: $options.data('preview_size'),
379
+ save_to_media_library: saveToMediaLibrary
380
+ }
381
+ $.post(ajaxurl, data, function(data, textStatus, xhr) {
382
+ if(data.success){
383
+ $field.find('[data-name=image]').attr('src', data.preview_url);
384
+ $field.find('.acf-image-value').data('cropped-image', data.value);
385
+ $field.find('.acf-image-value').data('cropped', true);
386
+ updateFieldValue($field);
387
+ }
388
+ else{
389
+ $field.append('<div class="error"><p>' + acf._e('image_crop', 'crop_error') + '</p>' + data.error_message);
390
+ }
391
+ $field.find('.crop-stage').removeClass('loading');
392
+ cancelCrop($field);
393
+ }, 'json');
394
+ }
395
+ }
396
+
397
+ function cancelCrop($field){
398
+ toggleCropView($field);
399
+ $field.find('.crop-stage img.crop-image').imgAreaSelect({remove:true});
400
+ }
401
+
402
+ function toggleCropView($field){
403
+ var $innerField = $field.find('.acf-image-crop');
404
+ if($innerField.hasClass('cropping')){
405
+ $('#acf-image-crop-overlay').remove();
406
+ }
407
+ else{
408
+ $('body').append($('<div id="acf-image-crop-overlay"></div>'));
409
+ }
410
+ $innerField.toggleClass('cropping');
411
+
412
+ }
413
+
414
+ function updateFieldValue($field){
415
+ var $input = $field.find('.acf-image-value');
416
+ $input.val(generateCropJSON($input.data('original-image'), $input.data('cropped-image')));
417
+ }
418
+
419
+ function getFullImageUrl(id, callback){
420
+ $.post(ajaxurl, {images: []}, function(data, textStatus, xhr) {
421
+ }, 'json');
422
+ }
423
+
424
+
425
+ if( typeof acf.add_action !== 'undefined' ) {
426
+
427
+ /*
428
+ * ready append (ACF5)
429
+ *
430
+ * These are 2 events which are fired during the page load
431
+ * ready = on page load similar to $(document).ready()
432
+ * append = on new DOM elements appended via repeater field
433
+ *
434
+ * @type event
435
+ * @date 20/07/13
436
+ *
437
+ * @param $el (jQuery selection) the jQuery element which contains the ACF fields
438
+ * @return n/a
439
+ */
440
+
441
+ acf.add_action('ready append', function( $el ){
442
+
443
+ // search $el for fields of type 'image_crop'
444
+ acf.get_fields({ type : 'image_crop'}, $el).each(function(){
445
+
446
+ initialize_field( $(this) );
447
+
448
+ });
449
+
450
+ });
451
+
452
+
453
+ } else {
454
+
455
+
456
+ /*
457
+ * acf/setup_fields (ACF4)
458
+ *
459
+ * This event is triggered when ACF adds any new elements to the DOM.
460
+ *
461
+ * @type function
462
+ * @since 1.0.0
463
+ * @date 01/01/12
464
+ *
465
+ * @param event e: an event object. This can be ignored
466
+ * @param Element postbox: An element which contains the new HTML
467
+ *
468
+ * @return n/a
469
+ */
470
+
471
+ $(document).live('acf/setup_fields', function(e, postbox){
472
+
473
+ $(postbox).find('.field[data-field_type="image_crop"]').each(function(){
474
+
475
+ initialize_field( $(this) );
476
+
477
+ });
478
+
479
+ });
480
+
481
+
482
+ }
483
 
484
 
485
  })(jQuery);
js/input-v4.js CHANGED
@@ -18,7 +18,9 @@
18
 
19
  $(document).on('acf/setup_fields', function(e, postbox){
20
  $(postbox).find('.field_type-image_crop').each(function(){
21
- var $field = $(this), $options = $field.find('.acf-image-uploader');
 
 
22
  $field.find('.acf-image-value').on('change', function(){
23
  var originalImage = $(this).val();
24
  if($(this).val()){
@@ -98,7 +100,7 @@
98
  });
99
 
100
  function initCrop($field){
101
- var $options = $field.find('.acf-image-uploader');
102
  var options = {
103
  handles: true,
104
  onSelectEnd: function (img, selection) {
@@ -148,7 +150,7 @@
148
  }
149
 
150
  function updateCropData($field, img, selection){
151
- var $options = $field.find('.acf-image-uploader');
152
  $options.data('x1', selection.x1);
153
  $options.data('x2', selection.x2);
154
  $options.data('y1', selection.y1);
@@ -156,7 +158,7 @@
156
  }
157
 
158
  function updateThumbnail($field, img, selection){
159
- var $options = $field.find('.acf-image-uploader');
160
  var div = $field.find('.crop-preview .preview');
161
  var targetWidth = $field.find('.crop-preview .preview').width();
162
  var factor = targetWidth / (selection.x2 - selection.x1);
@@ -186,7 +188,7 @@
186
  function performCrop($field){
187
  if(!$field.find('.crop-stage').hasClass('loading')){
188
  $field.find('.crop-stage').addClass('loading');
189
- var $options = $field.find('.acf-image-uploader');
190
  var targetWidth = $options.data('width');
191
  var targetHeight = $options.data('height');
192
  var saveToMediaLibrary = $options.data('save-to-media-library');
@@ -208,7 +210,7 @@
208
  }
209
  $.post(ajaxurl, data, function(data, textStatus, xhr) {
210
  if(data.success){
211
- $field.find('[data-name=image]').attr('src', data.preview_url);
212
  $field.find('.acf-image-value').data('cropped-image', data.value);
213
  $field.find('.acf-image-value').data('cropped', true);
214
  updateFieldValue($field);
@@ -235,7 +237,6 @@
235
  $('body').append($('<div id="acf-image-crop-overlay"></div>'));
236
  }
237
  $field.toggleClass('cropping');
238
-
239
  }
240
 
241
  function updateFieldValue($field){
18
 
19
  $(document).on('acf/setup_fields', function(e, postbox){
20
  $(postbox).find('.field_type-image_crop').each(function(){
21
+ var $field = $(this).find('.acf-image-crop');
22
+ var $options = $field;
23
+ // var $el = $field.find('.acf-image-crop');
24
  $field.find('.acf-image-value').on('change', function(){
25
  var originalImage = $(this).val();
26
  if($(this).val()){
100
  });
101
 
102
  function initCrop($field){
103
+ var $options = $field;
104
  var options = {
105
  handles: true,
106
  onSelectEnd: function (img, selection) {
150
  }
151
 
152
  function updateCropData($field, img, selection){
153
+ var $options = $field;
154
  $options.data('x1', selection.x1);
155
  $options.data('x2', selection.x2);
156
  $options.data('y1', selection.y1);
158
  }
159
 
160
  function updateThumbnail($field, img, selection){
161
+ var $options = $field;
162
  var div = $field.find('.crop-preview .preview');
163
  var targetWidth = $field.find('.crop-preview .preview').width();
164
  var factor = targetWidth / (selection.x2 - selection.x1);
188
  function performCrop($field){
189
  if(!$field.find('.crop-stage').hasClass('loading')){
190
  $field.find('.crop-stage').addClass('loading');
191
+ var $options = $field;
192
  var targetWidth = $options.data('width');
193
  var targetHeight = $options.data('height');
194
  var saveToMediaLibrary = $options.data('save-to-media-library');
210
  }
211
  $.post(ajaxurl, data, function(data, textStatus, xhr) {
212
  if(data.success){
213
+ $field.find('.acf-image-image').attr('src', data.preview_url);
214
  $field.find('.acf-image-value').data('cropped-image', data.value);
215
  $field.find('.acf-image-value').data('cropped', true);
216
  updateFieldValue($field);
237
  $('body').append($('<div id="acf-image-crop-overlay"></div>'));
238
  }
239
  $field.toggleClass('cropping');
 
240
  }
241
 
242
  function updateFieldValue($field){
js/input.js CHANGED
@@ -4,60 +4,83 @@
4
  type: 'image_crop',
5
  $el: null,
6
 
 
 
 
 
 
7
  events: {
8
- 'click [data-name="add"]': 'add',
9
- 'click [data-name="edit"]': 'edit',
10
- 'click [data-name="remove"]': 'remove',
 
11
  },
12
 
13
  focus: function(){
14
 
 
15
  this.$el = this.$field.find('.acf-image-uploader');
16
 
17
- this.settings = acf.get_data( this.$el );
 
 
18
 
19
  },
20
 
21
- add: function() {
 
 
22
 
23
- // reference
24
- var self = this;
25
 
 
26
 
27
- // vars
28
- var field_key = acf.get_data( this.$field, 'key' );
 
 
 
 
29
 
30
 
31
  // get repeater
32
- var $repeater = acf.get_closest_field( this.$field, {type:'repeater'} );
33
 
34
 
35
  // popup
36
  var frame = acf.media.popup({
37
- 'title' : acf._e('image', 'select'),
38
- 'mode' : 'select',
39
- 'type' : 'image',
40
- 'multiple' : $repeater.exists(),
41
- 'library' : this.settings.library,
42
- 'select' : function( attachment, i ) {
 
 
 
 
43
 
44
  // select / add another image field?
45
  if( i > 0 ) {
46
 
47
  // vars
48
- var $tr = self.$field.parent(),
49
- $next = false;
 
 
 
 
50
 
51
 
52
  // find next image field
53
- $tr.nextAll('.acf-row').not('.clone').each(function(){
54
 
55
  // get next $field
56
- $next = acf.get_field( field_key, $(this) );
57
 
58
 
59
  // bail early if $next was not found
60
- if( !$next ) {
61
 
62
  return;
63
 
@@ -65,9 +88,9 @@
65
 
66
 
67
  // bail early if next file uploader has value
68
- if( $next.find('.acf-image-uploader.has-value').exists() ) {
69
 
70
- $next = false;
71
  return;
72
 
73
  }
@@ -80,7 +103,7 @@
80
 
81
 
82
  // add extra row if next is not found
83
- if( !$next ) {
84
 
85
  $tr = acf.fields.repeater.doFocus( $repeater ).add();
86
 
@@ -94,43 +117,52 @@
94
 
95
 
96
  // get next $field
97
- $next = acf.get_field( field_key, $tr );
98
 
99
  }
100
 
101
-
102
- // update $el
103
- self.doFocus( $next );
104
-
105
  }
106
 
 
 
 
107
 
108
- // add file to field
109
- self.render( attachment );
110
 
111
  }
112
- });
113
 
 
114
 
115
  },
116
 
117
- render: function( attachment ){
 
 
 
 
 
118
 
119
- // override url
120
- if( acf.isset(attachment, 'attributes', 'sizes', this.settings.preview_size, 'url') ) {
121
 
122
- attachment.url = attachment.attributes.sizes[ this.settings.preview_size ].url;
 
123
 
124
- }
125
- // set url to default url in case preview size does not exist
126
- else if(acf.isset(attachment, 'attributes', 'url')){
127
 
128
- attachment.url = attachment.attributes.url;
129
  }
130
 
 
 
 
 
 
 
 
 
 
131
  // set atts
132
- this.$el.find('[data-name="image"]').attr( 'src', attachment.url );
133
- this.$el.find('[data-name="id"]').val( attachment.id ).trigger('change');
134
 
135
 
136
  // set div class
@@ -139,27 +171,30 @@
139
  },
140
 
141
  edit: function() {
142
-
143
  // reference
144
  var self = this;
145
 
146
 
147
  // vars
148
- var id = this.$el.find('[data-name="id"]').val();
149
 
 
 
 
 
150
 
151
  // popup
152
  var frame = acf.media.popup({
153
 
154
  title: acf._e('image', 'edit'),
 
155
  button: acf._e('image', 'update'),
156
  mode: 'edit',
157
  id: id,
158
 
159
  select: function( attachment, i ) {
160
 
161
- // add file to field
162
- self.render( attachment );
163
 
164
  }
165
 
@@ -183,6 +218,12 @@
183
  // remove class
184
  this.$el.removeClass('has-value');
185
 
 
 
 
 
 
 
186
  }
187
 
188
  });
@@ -251,20 +292,20 @@ function initialize_field( $el ) {
251
  e.preventDefault();
252
  cancelCrop($field);
253
  });
254
- $field.find('[data-name=edit]').click(function(e){
255
- e.preventDefault();
256
- e.stopPropagation();
257
- var id = $field.find('.acf-image-value').data('cropped-image');
258
- if(!$.isNumeric(id)){
259
- id = $field.find('.acf-image-value').data('original-image');;
260
- }
261
- acf.media.popup({
262
- mode : 'edit',
263
- title : acf._e('image', 'edit'),
264
- button : acf._e('image', 'update'),
265
- id : id
266
- });
267
- });
268
 
269
  }
270
 
@@ -400,13 +441,14 @@ function initialize_field( $el ) {
400
  }
401
 
402
  function toggleCropView($field){
403
- if($field.hasClass('cropping')){
 
404
  $('#acf-image-crop-overlay').remove();
405
  }
406
  else{
407
  $('body').append($('<div id="acf-image-crop-overlay"></div>'));
408
  }
409
- $field.toggleClass('cropping');
410
 
411
  }
412
 
4
  type: 'image_crop',
5
  $el: null,
6
 
7
+ actions: {
8
+ 'ready': 'initialize',
9
+ 'append': 'initialize'
10
+ },
11
+
12
  events: {
13
+ 'click a[data-name="add"]': 'add',
14
+ 'click a[data-name="edit"]': 'edit',
15
+ 'click a[data-name="remove"]': 'remove',
16
+ 'change input[type="file"]': 'change'
17
  },
18
 
19
  focus: function(){
20
 
21
+ // get elements
22
  this.$el = this.$field.find('.acf-image-uploader');
23
 
24
+ // get options
25
+ this.o = acf.get_data( this.$el );
26
+
27
 
28
  },
29
 
30
+ initialize: function(){
31
+ // add attribute to form
32
+ if( this.o.uploader == 'basic' ) {
33
 
34
+ this.$el.closest('form').attr('enctype', 'multipart/form-data');
 
35
 
36
+ }
37
 
38
+ },
39
+
40
+ add: function() {
41
+ // reference
42
+ var self = this,
43
+ $field = this.$field;
44
 
45
 
46
  // get repeater
47
+ var $repeater = acf.get_closest_field( this.$field, 'repeater' );
48
 
49
 
50
  // popup
51
  var frame = acf.media.popup({
52
+
53
+ title: acf._e('image', 'select'),
54
+ mode: 'select',
55
+ type: 'image',
56
+ field: acf.get_field_key($field),
57
+ multiple: $repeater.exists(),
58
+ library: this.o.library,
59
+ mime_types: this.o.mime_types,
60
+
61
+ select: function( attachment, i ) {
62
 
63
  // select / add another image field?
64
  if( i > 0 ) {
65
 
66
  // vars
67
+ var key = acf.get_field_key( $field ),
68
+ $tr = $field.closest('.acf-row');
69
+
70
+
71
+ // reset field
72
+ $field = false;
73
 
74
 
75
  // find next image field
76
+ $tr.nextAll('.acf-row:visible').each(function(){
77
 
78
  // get next $field
79
+ $field = acf.get_field( key, $(this) );
80
 
81
 
82
  // bail early if $next was not found
83
+ if( !$field ) {
84
 
85
  return;
86
 
88
 
89
 
90
  // bail early if next file uploader has value
91
+ if( $field.find('.acf-image-uploader.has-value').exists() ) {
92
 
93
+ $field = false;
94
  return;
95
 
96
  }
103
 
104
 
105
  // add extra row if next is not found
106
+ if( !$field ) {
107
 
108
  $tr = acf.fields.repeater.doFocus( $repeater ).add();
109
 
117
 
118
 
119
  // get next $field
120
+ $field = acf.get_field( key, $tr );
121
 
122
  }
123
 
 
 
 
 
124
  }
125
 
126
+ // focus
127
+ self.doFocus( $field );
128
+
129
 
130
+ // render
131
+ self.render( self.prepare(attachment) );
132
 
133
  }
 
134
 
135
+ });
136
 
137
  },
138
 
139
+ prepare: function( attachment ) {
140
+ // vars
141
+ var image = {
142
+ id: attachment.id,
143
+ url: attachment.attributes.url
144
+ };
145
 
 
 
146
 
147
+ // check for preview size
148
+ if( acf.isset(attachment.attributes, 'sizes', this.o.preview_size, 'url') ) {
149
 
150
+ image.url = attachment.attributes.sizes[ this.o.preview_size ].url;
 
 
151
 
 
152
  }
153
 
154
+
155
+ // return
156
+ return image;
157
+
158
+ },
159
+
160
+ render: function( image ){
161
+
162
+
163
  // set atts
164
+ this.$el.find('[data-name="image"]').attr( 'src', image.url );
165
+ this.$el.find('[data-name="id"]').val( image.id ).trigger('change');
166
 
167
 
168
  // set div class
171
  },
172
 
173
  edit: function() {
 
174
  // reference
175
  var self = this;
176
 
177
 
178
  // vars
179
+ //var id = this.$el.find('[data-name="id"]').val();
180
 
181
+ var id = this.$el.find('.acf-image-value').data('cropped-image');
182
+ if(!$.isNumeric(id)){
183
+ id = this.$el.find('.acf-image-value').data('original-image');;
184
+ }
185
 
186
  // popup
187
  var frame = acf.media.popup({
188
 
189
  title: acf._e('image', 'edit'),
190
+ type: 'image',
191
  button: acf._e('image', 'update'),
192
  mode: 'edit',
193
  id: id,
194
 
195
  select: function( attachment, i ) {
196
 
197
+ self.render( self.prepare(attachment) );
 
198
 
199
  }
200
 
218
  // remove class
219
  this.$el.removeClass('has-value');
220
 
221
+ },
222
+
223
+ change: function( e ){
224
+
225
+ this.$el.find('[data-name="id"]').val( e.$el.val() );
226
+
227
  }
228
 
229
  });
292
  e.preventDefault();
293
  cancelCrop($field);
294
  });
295
+ // $field.find('[data-name=edit]').click(function(e){
296
+ // e.preventDefault();
297
+ // e.stopPropagation();
298
+ // var id = $field.find('.acf-image-value').data('cropped-image');
299
+ // if(!$.isNumeric(id)){
300
+ // id = $field.find('.acf-image-value').data('original-image');;
301
+ // }
302
+ // acf.media.popup({
303
+ // mode : 'edit',
304
+ // title : acf._e('image', 'edit'),
305
+ // button : acf._e('image', 'update'),
306
+ // id : id
307
+ // });
308
+ // });
309
 
310
  }
311
 
441
  }
442
 
443
  function toggleCropView($field){
444
+ var $innerField = $field.find('.acf-image-crop');
445
+ if($innerField.hasClass('cropping')){
446
  $('#acf-image-crop-overlay').remove();
447
  }
448
  else{
449
  $('body').append($('<div id="acf-image-crop-overlay"></div>'));
450
  }
451
+ $innerField.toggleClass('cropping');
452
 
453
  }
454
 
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: andersthorborg
3
  Tags: afc, advanced custom fields, image crop, image, crop
4
  Requires at least: 3.5
5
- Tested up to: 4.1.1
6
- Stable tag: 1.4.4
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -61,6 +61,16 @@ function my_register_fields()
61
 
62
  == Changelog ==
63
 
 
 
 
 
 
 
 
 
 
 
64
  = 1.4.4 =
65
  * Fixed migration from image field to not only return image ID
66
  * Fixed a js error in field settings caused by a change in class names in ACF
2
  Contributors: andersthorborg
3
  Tags: afc, advanced custom fields, image crop, image, crop
4
  Requires at least: 3.5
5
+ Tested up to: 4.3.1
6
+ Stable tag: 1.4.7
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
61
 
62
  == Changelog ==
63
 
64
+ = 1.4.6 =
65
+ * Added compatibility with ACF PRO 5.4.2.2 icons
66
+
67
+ = 1.4.6 =
68
+ * Added compatibility with ACF 4.4.2 and ACF PRO 5.2.9
69
+
70
+ = 1.4.5 =
71
+ * Added compatibility with ACF 5.2.7
72
+ * Added image quality filter (needs testing)
73
+
74
  = 1.4.4 =
75
  * Fixed migration from image field to not only return image ID
76
  * Fixed a js error in field settings caused by a change in class names in ACF