diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js
index c12c25701f..e0cb899ff0 100644
--- a/public/src/client/account/header.js
+++ b/public/src/client/account/header.js
@@ -94,8 +94,6 @@ define('forum/account/header', [
title: '[[user:upload-cover-picture]]',
socketMethod: 'user.updateCover',
aspectRatio: NaN,
- allowSkippingCrop: true,
- restrictImageDimension: false,
paramName: 'uid',
paramValue: ajaxify.data.theirid,
accept: '.png,.jpg,.bmp',
diff --git a/public/src/client/groups/details.js b/public/src/client/groups/details.js
index 8dde2e3eab..30f20f9739 100644
--- a/public/src/client/groups/details.js
+++ b/public/src/client/groups/details.js
@@ -50,8 +50,6 @@ define('forum/groups/details', [
title: '[[groups:upload-group-cover]]',
socketMethod: 'groups.cover.update',
aspectRatio: NaN,
- allowSkippingCrop: true,
- restrictImageDimension: false,
paramName: 'groupName',
paramValue: groupName,
}, function (imageUrlOnServer) {
diff --git a/public/src/modules/accounts/picture.js b/public/src/modules/accounts/picture.js
index 6fe37df734..254fc93dd8 100644
--- a/public/src/modules/accounts/picture.js
+++ b/public/src/modules/accounts/picture.js
@@ -171,11 +171,10 @@ define('accounts/picture', [
pictureCropper.show({
socketMethod: 'user.uploadCroppedPicture',
route: config.relative_path + '/api/user/' + ajaxify.data.userslug + '/uploadpicture',
- aspectRatio: 1 / 1,
+ aspectRatio: 1,
paramName: 'uid',
paramValue: ajaxify.data.theirid,
fileSize: ajaxify.data.maximumProfileImageSize,
- allowSkippingCrop: false,
title: '[[user:upload-picture]]',
description: '[[user:upload-a-picture]]',
accept: ajaxify.data.allowedProfileImageExtensions,
@@ -203,7 +202,6 @@ define('accounts/picture', [
url: url,
socketMethod: 'user.uploadCroppedPicture',
aspectRatio: 1,
- allowSkippingCrop: false,
paramName: 'uid',
paramValue: ajaxify.data.theirid,
}, onUploadComplete);
diff --git a/public/src/modules/pictureCropper.js b/public/src/modules/pictureCropper.js
index 6b0e9f8b6d..006856a86b 100644
--- a/public/src/modules/pictureCropper.js
+++ b/public/src/modules/pictureCropper.js
@@ -48,99 +48,71 @@ define('pictureCropper', ['alerts'], function (alerts) {
const Cropper = (await import(/* webpackChunkName: "cropperjs" */ 'cropperjs')).default;
let cropperTool = new Cropper(img, {
- aspectRatio: data.aspectRatio,
- autoCropArea: 1,
- viewMode: 1,
- checkCrossOrigin: true,
- cropmove: function () {
- if (data.restrictImageDimension) {
- if (cropperTool.cropBoxData.width > data.imageDimension) {
- cropperTool.setCropBoxData({
- width: data.imageDimension,
- });
- }
- if (cropperTool.cropBoxData.height > data.imageDimension) {
- cropperTool.setCropBoxData({
- height: data.imageDimension,
- });
- }
+ template: `
+
+
+
+
+
+ `,
+ });
+
+ const cropperSelection = cropperTool.getCropperSelection();
+ const cropperImage = cropperTool.getCropperImage();
+
+ cropperSelection.aspectRatio = data.aspectRatio;
+
+ cropperImage.$ready(async function () {
+ if (!await checkCORS(cropperSelection, data)) {
+ return cropperModal.modal('hide');
+ }
+
+ cropperModal.find('.rotate').on('click', function () {
+ const degrees = this.getAttribute('data-degrees');
+ const radians = degrees * Math.PI / 180;
+ cropperImage.$rotate(radians);
+ });
+
+ cropperModal.find('.flip').on('click', function () {
+ const method = this.getAttribute('data-method');
+ if (method === 'scaleX') {
+ cropperImage.$scale(-1, 1);
+ } else {
+ cropperImage.$scale(1, -1);
}
- },
- ready: function () {
- if (!checkCORS(cropperTool, data)) {
- return cropperModal.modal('hide');
+ });
+
+ cropperModal.find('.reset').on('click', function () {
+ cropperImage.$resetTransform();
+ cropperSelection.$reset();
+ });
+
+ cropperModal.find('.crop-btn').on('click', async function () {
+ $(this).addClass('disabled');
+ const imageData = await checkCORS(cropperSelection, data);
+ if (!imageData) {
+ return;
}
- if (data.restrictImageDimension) {
- const origDimension = (img.width < img.height) ? img.width : img.height;
- const dimension = (origDimension > data.imageDimension) ? data.imageDimension : origDimension;
- cropperTool.setCropBoxData({
- width: dimension,
- height: dimension,
- });
- }
+ cropperModal.find('#upload-progress-bar').css('width', '0%');
+ cropperModal.find('#upload-progress-box').show().removeClass('hide');
- cropperModal.find('.rotate').on('click', function () {
- const degrees = this.getAttribute('data-degrees');
- cropperTool.rotate(degrees);
- });
-
- cropperModal.find('.flip').on('click', function () {
- const option = this.getAttribute('data-option');
- const method = this.getAttribute('data-method');
- if (method === 'scaleX') {
- cropperTool.scaleX(option);
- } else {
- cropperTool.scaleY(option);
- }
- this.setAttribute('data-option', option * -1);
- });
-
- cropperModal.find('.reset').on('click', function () {
- cropperTool.reset();
- });
-
- cropperModal.find('.crop-btn').on('click', function () {
- $(this).addClass('disabled');
- const imageData = checkCORS(cropperTool, data);
- if (!imageData) {
- return;
+ socketUpload({
+ data: data,
+ imageData: imageData,
+ progressBarEl: cropperModal.find('#upload-progress-bar'),
+ }, function (err, result) {
+ if (err) {
+ cropperModal.find('#upload-progress-box').hide();
+ cropperModal.find('.upload-btn').removeClass('disabled');
+ cropperModal.find('.crop-btn').removeClass('disabled');
+ return alerts.error(err);
}
- cropperModal.find('#upload-progress-bar').css('width', '0%');
- cropperModal.find('#upload-progress-box').show().removeClass('hide');
-
- socketUpload({
- data: data,
- imageData: imageData,
- progressBarEl: cropperModal.find('#upload-progress-bar'),
- }, function (err, result) {
- if (err) {
- cropperModal.find('#upload-progress-box').hide();
- cropperModal.find('.upload-btn').removeClass('disabled');
- cropperModal.find('.crop-btn').removeClass('disabled');
- return alerts.error(err);
- }
-
- callback(result.url);
- cropperModal.modal('hide');
- });
+ callback(result.url);
+ cropperModal.modal('hide');
});
-
-
- cropperModal.find('.upload-btn').on('click', async function () {
- $(this).addClass('disabled');
- cropperTool.destroy();
- const Cropper = (await import(/* webpackChunkName: "cropperjs" */ 'cropperjs')).default;
- cropperTool = new Cropper(img, {
- viewMode: 1,
- autoCropArea: 1,
- ready: function () {
- cropperModal.find('.crop-btn').trigger('click');
- },
- });
- });
- },
+ });
});
});
};
@@ -175,12 +147,18 @@ define('pictureCropper', ['alerts'], function (alerts) {
doUpload();
}
- function checkCORS(cropperTool, data) {
+ async function checkCORS(selection, data) {
let imageData;
try {
+ const canvasOpts = {
+ beforeDraw: function (context) {
+ context.imageSmoothingQuality = 'high';
+ },
+ };
+ const canvas = await selection.$toCanvas(canvasOpts);
imageData = data.imageType ?
- cropperTool.getCroppedCanvas().toDataURL(data.imageType) :
- cropperTool.getCroppedCanvas().toDataURL();
+ canvas.toDataURL(data.imageType) :
+ canvas.toDataURL();
} catch (err) {
const corsErrors = [
'The operation is insecure.',
@@ -232,8 +210,6 @@ define('pictureCropper', ['alerts'], function (alerts) {
imageType: file.type,
socketMethod: data.socketMethod,
aspectRatio: data.aspectRatio,
- allowSkippingCrop: data.allowSkippingCrop,
- restrictImageDimension: data.restrictImageDimension,
imageDimension: data.imageDimension,
paramName: data.paramName,
paramValue: data.paramValue,
diff --git a/src/meta/css.js b/src/meta/css.js
index 4b7e999383..ab0c17f7d8 100644
--- a/src/meta/css.js
+++ b/src/meta/css.js
@@ -29,7 +29,6 @@ const buildImports = {
'@import "@adactive/bootstrap-tagsinput/src/bootstrap-tagsinput";',
source,
'@import "jquery-ui";',
- '@import "cropperjs/dist/cropper";',
].join('\n');
},
admin: function (source) {
diff --git a/src/views/modals/crop_picture.tpl b/src/views/modals/crop_picture.tpl
index 519bacd5ec..7920dd13fc 100644
--- a/src/views/modals/crop_picture.tpl
+++ b/src/views/modals/crop_picture.tpl
@@ -1,16 +1,15 @@
-