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.

Built from https://develop.svn.wordpress.org/trunk@59197


git-svn-id: http://core.svn.wordpress.org/trunk@58592 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Aaron Jorbin 2024-10-08 22:29:21 +00:00
parent 94bd76c77d
commit 58c1f27c40
5 changed files with 70 additions and 30 deletions

View File

@ -4602,26 +4602,29 @@
* @return {Object} Options * @return {Object} Options
*/ */
calculateImageSelectOptions: function( attachment, controller ) { calculateImageSelectOptions: function( attachment, controller ) {
var control = controller.get( 'control' ), var control = controller.get( 'control' ),
flexWidth = !! parseInt( control.params.flex_width, 10 ), flexWidth = !! parseInt( control.params.flex_width, 10 ),
flexHeight = !! parseInt( control.params.flex_height, 10 ), flexHeight = !! parseInt( control.params.flex_height, 10 ),
realWidth = attachment.get( 'width' ), realWidth = attachment.get( 'width' ),
realHeight = attachment.get( 'height' ), realHeight = attachment.get( 'height' ),
xInit = parseInt( control.params.width, 10 ), xInit = parseInt( control.params.width, 10 ),
yInit = parseInt( control.params.height, 10 ), yInit = parseInt( control.params.height, 10 ),
ratio = xInit / yInit, requiredRatio = xInit / yInit,
xImg = xInit, realRatio = realWidth / realHeight,
yImg = yInit, xImg = xInit,
yImg = yInit,
x1, y1, imgSelectOptions; x1, y1, imgSelectOptions;
controller.set( 'hasRequiredAspectRatio', control.hasRequiredAspectRatio( requiredRatio, realRatio ) );
controller.set( 'suggestedCropSize', { width: realWidth, height: realHeight, x1: 0, y1: 0, x2: xInit, y2: yInit } );
controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) ); controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) );
if ( realWidth / realHeight > ratio ) { if ( realRatio > requiredRatio ) {
yInit = realHeight; yInit = realHeight;
xInit = yInit * ratio; xInit = yInit * requiredRatio;
} else { } else {
xInit = realWidth; xInit = realWidth;
yInit = xInit / ratio; yInit = xInit / requiredRatio;
} }
x1 = ( realWidth - xInit ) / 2; x1 = ( realWidth - xInit ) / 2;
@ -4662,13 +4665,13 @@
/** /**
* Return whether the image must be cropped, based on required dimensions. * Return whether the image must be cropped, based on required dimensions.
* *
* @param {boolean} flexW * @param {boolean} flexW Width is flexible.
* @param {boolean} flexH * @param {boolean} flexH Height is flexible.
* @param {number} dstW * @param {number} dstW Required width.
* @param {number} dstH * @param {number} dstH Required height.
* @param {number} imgW * @param {number} imgW Provided image's width.
* @param {number} imgH * @param {number} imgH Provided image's height.
* @return {boolean} * @return {boolean} Whether cropping is required.
*/ */
mustBeCropped: function( flexW, flexH, dstW, dstH, imgW, imgH ) { mustBeCropped: function( flexW, flexH, dstW, dstH, imgW, imgH ) {
if ( true === flexW && true === flexH ) { if ( true === flexW && true === flexH ) {
@ -4694,6 +4697,25 @@
return true; return true;
}, },
/**
* Check if the image's aspect ratio essentially matches the required aspect ratio.
*
* Floating point precision is low, so this allows a small tolerance. This
* tolerance allows for images over 100,000 px on either side to still trigger
* the cropping flow.
*
* @param {number} requiredRatio Required image ratio.
* @param {number} realRatio Provided image ratio.
* @return {boolean} Whether the image has the required aspect ratio.
*/
hasRequiredAspectRatio: function ( requiredRatio, realRatio ) {
if ( Math.abs( requiredRatio - realRatio ) < 0.000001 ) {
return true;
}
return false;
},
/** /**
* If cropping was skipped, apply the image data directly to the setting. * If cropping was skipped, apply the image data directly to the setting.
*/ */

File diff suppressed because one or more lines are too long

View File

@ -378,9 +378,11 @@ Cropper = wp.media.controller.State.extend(/** @lends wp.media.controller.Croppe
* @return {void} * @return {void}
*/ */
createCropToolbar: function() { createCropToolbar: function() {
var canSkipCrop, toolbarOptions; var canSkipCrop, hasRequiredAspectRatio, suggestedCropSize, toolbarOptions;
canSkipCrop = this.get('canSkipCrop') || false; suggestedCropSize = this.get( 'suggestedCropSize' );
hasRequiredAspectRatio = this.get( 'hasRequiredAspectRatio' );
canSkipCrop = this.get( 'canSkipCrop' ) || false;
toolbarOptions = { toolbarOptions = {
controller: this.frame, controller: this.frame,
@ -412,7 +414,7 @@ Cropper = wp.media.controller.State.extend(/** @lends wp.media.controller.Croppe
} }
}; };
if ( canSkipCrop ) { if ( canSkipCrop || hasRequiredAspectRatio ) {
_.extend( toolbarOptions.items, { _.extend( toolbarOptions.items, {
skip: { skip: {
style: 'secondary', style: 'secondary',
@ -420,10 +422,26 @@ Cropper = wp.media.controller.State.extend(/** @lends wp.media.controller.Croppe
priority: 70, priority: 70,
requires: { library: false, selection: false }, requires: { library: false, selection: false },
click: function() { click: function() {
var selection = this.controller.state().get('selection').first(); var controller = this.controller,
this.controller.state().cropperView.remove(); selection = controller.state().get( 'selection' ).first();
this.controller.trigger('skippedcrop', selection);
this.controller.close(); controller.state().cropperView.remove();
// Apply the suggested crop size.
if ( hasRequiredAspectRatio && !canSkipCrop ) {
selection.set({cropDetails: suggestedCropSize});
controller.state().doCrop( selection ).done( function( croppedImage ) {
controller.trigger( 'cropped', croppedImage );
controller.close();
}).fail( function() {
controller.trigger( 'content:error:crop' );
});
return;
}
// Skip the cropping process.
controller.trigger( 'skippedcrop', selection );
controller.close();
} }
} }
}); });

File diff suppressed because one or more lines are too long

View File

@ -16,7 +16,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '6.7-beta2-59196'; $wp_version = '6.7-beta2-59197';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.