Skip to content

Commit ee61e60

Browse files
committed
Customizer: Do not force users to go through the cropping flow if the image is the correct ratio.
If a user uploads an 800x800 image and a 512x512 image is required, then they should be allowed to skip cropping. This still creates the correct crop behind the scenes but simplifies the flow a bit for users. Props nirajgirixd, celloexpressions, westonruter, azaozz, jorbin. Fixes #36441. git-svn-id: https://develop.svn.wordpress.org/trunk@59197 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 5da6d2a commit ee61e60

File tree

2 files changed

+67
-27
lines changed

2 files changed

+67
-27
lines changed

src/js/_enqueues/wp/customize/controls.js

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4602,26 +4602,29 @@
46024602
* @return {Object} Options
46034603
*/
46044604
calculateImageSelectOptions: function( attachment, controller ) {
4605-
var control = controller.get( 'control' ),
4606-
flexWidth = !! parseInt( control.params.flex_width, 10 ),
4607-
flexHeight = !! parseInt( control.params.flex_height, 10 ),
4608-
realWidth = attachment.get( 'width' ),
4609-
realHeight = attachment.get( 'height' ),
4610-
xInit = parseInt( control.params.width, 10 ),
4611-
yInit = parseInt( control.params.height, 10 ),
4612-
ratio = xInit / yInit,
4613-
xImg = xInit,
4614-
yImg = yInit,
4605+
var control = controller.get( 'control' ),
4606+
flexWidth = !! parseInt( control.params.flex_width, 10 ),
4607+
flexHeight = !! parseInt( control.params.flex_height, 10 ),
4608+
realWidth = attachment.get( 'width' ),
4609+
realHeight = attachment.get( 'height' ),
4610+
xInit = parseInt( control.params.width, 10 ),
4611+
yInit = parseInt( control.params.height, 10 ),
4612+
requiredRatio = xInit / yInit,
4613+
realRatio = realWidth / realHeight,
4614+
xImg = xInit,
4615+
yImg = yInit,
46154616
x1, y1, imgSelectOptions;
46164617

4618+
controller.set( 'hasRequiredAspectRatio', control.hasRequiredAspectRatio( requiredRatio, realRatio ) );
4619+
controller.set( 'suggestedCropSize', { width: realWidth, height: realHeight, x1: 0, y1: 0, x2: xInit, y2: yInit } );
46174620
controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) );
46184621

4619-
if ( realWidth / realHeight > ratio ) {
4622+
if ( realRatio > requiredRatio ) {
46204623
yInit = realHeight;
4621-
xInit = yInit * ratio;
4624+
xInit = yInit * requiredRatio;
46224625
} else {
46234626
xInit = realWidth;
4624-
yInit = xInit / ratio;
4627+
yInit = xInit / requiredRatio;
46254628
}
46264629

46274630
x1 = ( realWidth - xInit ) / 2;
@@ -4662,13 +4665,13 @@
46624665
/**
46634666
* Return whether the image must be cropped, based on required dimensions.
46644667
*
4665-
* @param {boolean} flexW
4666-
* @param {boolean} flexH
4667-
* @param {number} dstW
4668-
* @param {number} dstH
4669-
* @param {number} imgW
4670-
* @param {number} imgH
4671-
* @return {boolean}
4668+
* @param {boolean} flexW Width is flexible.
4669+
* @param {boolean} flexH Height is flexible.
4670+
* @param {number} dstW Required width.
4671+
* @param {number} dstH Required height.
4672+
* @param {number} imgW Provided image's width.
4673+
* @param {number} imgH Provided image's height.
4674+
* @return {boolean} Whether cropping is required.
46724675
*/
46734676
mustBeCropped: function( flexW, flexH, dstW, dstH, imgW, imgH ) {
46744677
if ( true === flexW && true === flexH ) {
@@ -4694,6 +4697,25 @@
46944697
return true;
46954698
},
46964699

4700+
/**
4701+
* Check if the image's aspect ratio essentially matches the required aspect ratio.
4702+
*
4703+
* Floating point precision is low, so this allows a small tolerance. This
4704+
* tolerance allows for images over 100,000 px on either side to still trigger
4705+
* the cropping flow.
4706+
*
4707+
* @param {number} requiredRatio Required image ratio.
4708+
* @param {number} realRatio Provided image ratio.
4709+
* @return {boolean} Whether the image has the required aspect ratio.
4710+
*/
4711+
hasRequiredAspectRatio: function ( requiredRatio, realRatio ) {
4712+
if ( Math.abs( requiredRatio - realRatio ) < 0.000001 ) {
4713+
return true;
4714+
}
4715+
4716+
return false;
4717+
},
4718+
46974719
/**
46984720
* If cropping was skipped, apply the image data directly to the setting.
46994721
*/

src/js/media/controllers/cropper.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,11 @@ Cropper = wp.media.controller.State.extend(/** @lends wp.media.controller.Croppe
9393
* @return {void}
9494
*/
9595
createCropToolbar: function() {
96-
var canSkipCrop, toolbarOptions;
96+
var canSkipCrop, hasRequiredAspectRatio, suggestedCropSize, toolbarOptions;
9797

98-
canSkipCrop = this.get('canSkipCrop') || false;
98+
suggestedCropSize = this.get( 'suggestedCropSize' );
99+
hasRequiredAspectRatio = this.get( 'hasRequiredAspectRatio' );
100+
canSkipCrop = this.get( 'canSkipCrop' ) || false;
99101

100102
toolbarOptions = {
101103
controller: this.frame,
@@ -127,18 +129,34 @@ Cropper = wp.media.controller.State.extend(/** @lends wp.media.controller.Croppe
127129
}
128130
};
129131

130-
if ( canSkipCrop ) {
132+
if ( canSkipCrop || hasRequiredAspectRatio ) {
131133
_.extend( toolbarOptions.items, {
132134
skip: {
133135
style: 'secondary',
134136
text: l10n.skipCropping,
135137
priority: 70,
136138
requires: { library: false, selection: false },
137139
click: function() {
138-
var selection = this.controller.state().get('selection').first();
139-
this.controller.state().cropperView.remove();
140-
this.controller.trigger('skippedcrop', selection);
141-
this.controller.close();
140+
var controller = this.controller,
141+
selection = controller.state().get( 'selection' ).first();
142+
143+
controller.state().cropperView.remove();
144+
145+
// Apply the suggested crop size.
146+
if ( hasRequiredAspectRatio && !canSkipCrop ) {
147+
selection.set({cropDetails: suggestedCropSize});
148+
controller.state().doCrop( selection ).done( function( croppedImage ) {
149+
controller.trigger( 'cropped', croppedImage );
150+
controller.close();
151+
}).fail( function() {
152+
controller.trigger( 'content:error:crop' );
153+
});
154+
return;
155+
}
156+
157+
// Skip the cropping process.
158+
controller.trigger( 'skippedcrop', selection );
159+
controller.close();
142160
}
143161
}
144162
});

0 commit comments

Comments
 (0)