summaryrefslogtreecommitdiffstatshomepage
path: root/src/js
diff options
context:
space:
mode:
authorJoe Dolson <joedolson@git.wordpress.org>2024-08-19 20:45:33 +0000
committerJoe Dolson <joedolson@git.wordpress.org>2024-08-19 20:45:33 +0000
commitc8b744d12b2af5bc8eb01b2e8782c20d681fdadd (patch)
tree9f6f2ccb9b8d8cfb545af7996ce9c050cb3ca5d5 /src/js
parent913ef22dd0f07fc4a2cf2a373096ae1a1cd5d2ce (diff)
downloadwordpress-c8b744d12b2af5bc8eb01b2e8782c20d681fdadd.tar.gz
wordpress-c8b744d12b2af5bc8eb01b2e8782c20d681fdadd.zip
Media: Fix admin image cropping calculations.
The admin image editor crop function introduced rounding errors by using a scaled image to calculate values. Fix uses the image at 100% scale for calculations. Also avoid recalculating selection when the selection position is changed, and prevent incorrect values after scaling or restoration. Previously committed in [58456] and reverted in [58571]. The revert was due to a misattributed test failure. Props Jossnaz, johnillo, shailu25, rachelbaker, sudipatel007, joedolson, kevin940726 , andrewserong, hmbashar. Fixes #32282. git-svn-id: https://develop.svn.wordpress.org/trunk@58915 602fd350-edb4-49c9-b593-d223f7449a82
Diffstat (limited to 'src/js')
-rw-r--r--src/js/_enqueues/lib/image-edit.js110
1 files changed, 81 insertions, 29 deletions
diff --git a/src/js/_enqueues/lib/image-edit.js b/src/js/_enqueues/lib/image-edit.js
index b41e93f55d..74f5579566 100644
--- a/src/js/_enqueues/lib/image-edit.js
+++ b/src/js/_enqueues/lib/image-edit.js
@@ -143,17 +143,12 @@
* @return {void}
*/
init : function(postid) {
- var t = this, old = $('#image-editor-' + t.postid),
- x = t.intval( $('#imgedit-x-' + postid).val() ),
- y = t.intval( $('#imgedit-y-' + postid).val() );
+ var t = this, old = $('#image-editor-' + t.postid);
if ( t.postid !== postid && old.length ) {
t.close(t.postid);
}
- t.hold.w = t.hold.ow = x;
- t.hold.h = t.hold.oh = y;
- t.hold.xy_ratio = x / y;
t.hold.sizer = parseFloat( $('#imgedit-sizer-' + postid).val() );
t.postid = postid;
$('#imgedit-response-' + postid).empty();
@@ -189,6 +184,29 @@
},
/**
+ * Calculate the image size and save it to memory.
+ *
+ * @since 6.7.0
+ *
+ * @memberof imageEdit
+ *
+ * @param {number} postid The post ID.
+ *
+ * @return {void}
+ */
+ calculateImgSize: function( postid ) {
+ var t = this,
+ x = t.intval( $( '#imgedit-x-' + postid ).val() ),
+ y = t.intval( $( '#imgedit-y-' + postid ).val() );
+
+ t.hold.w = t.hold.ow = x;
+ t.hold.h = t.hold.oh = y;
+ t.hold.xy_ratio = x / y;
+ t.hold.sizer = parseFloat( $( '#imgedit-sizer-' + postid ).val() );
+ t.currentCropSelection = null;
+ },
+
+ /**
* Toggles the wait/load icon in the editor.
*
* @since 2.9.0
@@ -525,7 +543,7 @@
for ( n in history ) {
i = history[n];
if ( i.hasOwnProperty('c') ) {
- op[n] = { 'c': { 'x': i.c.x, 'y': i.c.y, 'w': i.c.w, 'h': i.c.h } };
+ op[n] = { 'c': { 'x': i.c.x, 'y': i.c.y, 'w': i.c.w, 'h': i.c.h, 'r': i.c.r } };
} else if ( i.hasOwnProperty('r') ) {
op[n] = { 'r': i.r.r };
} else if ( i.hasOwnProperty('f') ) {
@@ -860,6 +878,7 @@
if ( 'undefined' === typeof this.hold.sizer ) {
this.init( postid );
}
+ this.calculateImgSize( postid );
this.initCrop(postid, img, parent);
this.setCropSelection( postid, { 'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0, 'width': img.innerWidth(), 'height': img.innerHeight() } );
@@ -909,8 +928,6 @@
var t = this,
selW = $('#imgedit-sel-width-' + postid),
selH = $('#imgedit-sel-height-' + postid),
- selX = $('#imgedit-start-x-' + postid),
- selY = $('#imgedit-start-y-' + postid),
$image = $( image ),
$img;
@@ -945,13 +962,16 @@
*
* @return {void}
*/
- parent.children().on( 'mousedown, touchstart', function(e){
- var ratio = false, sel, defRatio;
-
- if ( e.shiftKey ) {
- sel = t.iasapi.getSelection();
- defRatio = t.getSelRatio(postid);
- ratio = ( sel && sel.width && sel.height ) ? sel.width + ':' + sel.height : defRatio;
+ parent.children().on( 'mousedown touchstart', function(e) {
+ var ratio = false,
+ sel = t.iasapi.getSelection(),
+ cx = t.intval( $( '#imgedit-crop-width-' + postid ).val() ),
+ cy = t.intval( $( '#imgedit-crop-height-' + postid ).val() );
+
+ if ( cx && cy ) {
+ ratio = t.getSelRatio( postid );
+ } else if ( e.shiftKey && sel && sel.width && sel.height ) {
+ ratio = sel.width + ':' + sel.height;
}
t.iasapi.setOptions({
@@ -1000,11 +1020,17 @@
* @return {void}
*/
onSelectChange: function(img, c) {
- var sizer = imageEdit.hold.sizer;
- selW.val( imageEdit.round(c.width / sizer) );
- selH.val( imageEdit.round(c.height / sizer) );
- selX.val( imageEdit.round(c.x1 / sizer) );
- selY.val( imageEdit.round(c.y1 / sizer) );
+ var sizer = imageEdit.hold.sizer,
+ oldSel = imageEdit.currentCropSelection;
+
+ if ( oldSel != null && oldSel.width == c.width && oldSel.height == c.height ) {
+ return;
+ }
+
+ selW.val( Math.min( imageEdit.hold.w, imageEdit.round( c.width / sizer ) ) );
+ selH.val( Math.min( imageEdit.hold.h, imageEdit.round( c.height / sizer ) ) );
+
+ t.currentCropSelection = c;
}
});
},
@@ -1022,7 +1048,11 @@
* @return {boolean}
*/
setCropSelection : function(postid, c) {
- var sel;
+ var sel,
+ selW = $( '#imgedit-sel-width-' + postid ),
+ selH = $( '#imgedit-sel-height-' + postid ),
+ sizer = this.hold.sizer,
+ hold = this.hold;
c = c || 0;
@@ -1037,7 +1067,15 @@
return false;
}
- sel = { 'x': c.x1, 'y': c.y1, 'w': c.width, 'h': c.height };
+ // adjust the selection within the bounds of the image on 100% scale
+ var excessW = hold.w - ( Math.round( c.x1 / sizer ) + parseInt( selW.val() ) );
+ var excessH = hold.h - ( Math.round( c.y1 / sizer ) + parseInt( selH.val() ) );
+ var x = Math.round( c.x1 / sizer ) + Math.min( 0, excessW );
+ var y = Math.round( c.y1 / sizer ) + Math.min( 0, excessH );
+
+ // use 100% scaling to prevent rounding errors
+ sel = { 'r': 1, 'x': x, 'y': y, 'w': selW.val(), 'h': selH.val() };
+
this.setDisabled($('.imgedit-crop', '#imgedit-panel-' + postid), 1);
$('#imgedit-selection-' + postid).val( JSON.stringify(sel) );
},
@@ -1165,6 +1203,11 @@
}
this.closePopup(t);
this.addStep({ 'r': { 'r': angle, 'fw': this.hold.h, 'fh': this.hold.w }}, postid, nonce);
+
+ // Clear the selection fields after rotating.
+ $( '#imgedit-sel-width-' + postid ).val( '' );
+ $( '#imgedit-sel-height-' + postid ).val( '' );
+ this.currentCropSelection = null;
},
/**
@@ -1187,6 +1230,11 @@
}
this.closePopup(t);
this.addStep({ 'f': { 'f': axis, 'fw': this.hold.w, 'fh': this.hold.h }}, postid, nonce);
+
+ // Clear the selection fields after flipping.
+ $( '#imgedit-sel-width-' + postid ).val( '' );
+ $( '#imgedit-sel-height-' + postid ).val( '' );
+ this.currentCropSelection = null;
},
/**
@@ -1219,10 +1267,11 @@
}
// Clear the selection fields after cropping.
- $('#imgedit-sel-width-' + postid).val('');
- $('#imgedit-sel-height-' + postid).val('');
- $('#imgedit-start-x-' + postid).val('0');
- $('#imgedit-start-y-' + postid).val('0');
+ $( '#imgedit-sel-width-' + postid ).val( '' );
+ $( '#imgedit-sel-height-' + postid ).val( '' );
+ $( '#imgedit-start-x-' + postid ).val( '0' );
+ $( '#imgedit-start-y-' + postid ).val( '0' );
+ this.currentCropSelection = null;
},
/**
@@ -1312,6 +1361,8 @@
img = $('#image-preview-' + postid), imgh = img.height(), imgw = img.width(),
sizer = this.hold.sizer, x1, y1, x2, y2, ias = this.iasapi;
+ this.currentCropSelection = null;
+
if ( false === this.validateNumeric( el ) ) {
return;
}
@@ -1335,18 +1386,19 @@
if ( x2 > imgw ) {
x1 = 0;
x2 = imgw;
- elX.val( Math.round( x2 / sizer ) );
+ elX.val( Math.min( this.hold.w, Math.round( x2 / sizer ) ) );
}
if ( y2 > imgh ) {
y1 = 0;
y2 = imgh;
- elY.val( Math.round( y2 / sizer ) );
+ elY.val( Math.min( this.hold.h, Math.round( y2 / sizer ) ) );
}
ias.setSelection( x1, y1, x2, y2 );
ias.update();
this.setCropSelection(postid, ias.getSelection());
+ this.currentCropSelection = ias.getSelection();
}
},