From b7864422c614dc2c533f91f585685fe9875e4133 Mon Sep 17 00:00:00 2001 From: Maria Daniel Deepak Date: Sat, 26 Jan 2019 12:12:31 +0530 Subject: [PATCH 1/4] Implement Image select & crop on Icon and Splash icon upload --- admin/js/main.js | 340 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 317 insertions(+), 23 deletions(-) diff --git a/admin/js/main.js b/admin/js/main.js index 111c12c..4c447e2 100644 --- a/admin/js/main.js +++ b/admin/js/main.js @@ -1,35 +1,329 @@ +var mediaUploader; + +var cropControl = { + id: "control-id", + params: { + flex_width: false, // set to true if the width of the cropped image can be different to the width defined here + flex_height: true, // set to true if the height of the cropped image can be different to the height defined here + width: 192, // set the desired width of the destination image here + height: 192, // set the desired height of the destination image here + } +}; + +cropControl.mustBeCropped = function (flexW, flexH, dstW, dstH, imgW, imgH) { + + // If the width and height are both flexible + // then the user does not need to crop the image. + + if (true === flexW && true === flexH) { + return false; + } + + // If the width is flexible and the cropped image height matches the current image height, + // then the user does not need to crop the image. + if (true === flexW && dstH === imgH) { + return false; + } + + // If the height is flexible and the cropped image width matches the current image width, + // then the user does not need to crop the image. + if (true === flexH && dstW === imgW) { + return false; + } + + // If the cropped image width matches the current image width, + // and the cropped image height matches the current image height + // then the user does not need to crop the image. + if (dstW === imgW && dstH === imgH) { + return false; + } + + // If the destination width is equal to or greater than the cropped image width + // then the user does not need to crop the image... + if (imgW <= dstW) { + return false; + } + + return true; +}; + +function superPWACalculateImageSelectOptions(attachment, controller) { + + var control = controller.get( 'control' ); + + var flexWidth = !! parseInt( control.params.flex_width, 10 ); + var flexHeight = !! parseInt( control.params.flex_height, 10 ); + + var realWidth = attachment.get( 'width' ); + var realHeight = attachment.get( 'height' ); + + var xInit = parseInt(control.params.width, 10); + var yInit = parseInt(control.params.height, 10); + + var ratio = xInit / yInit; + + controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) ); + + var xImg = xInit; + var yImg = yInit; + + if ( realWidth / realHeight > ratio ) { + yInit = realHeight; + xInit = yInit * ratio; + } else { + xInit = realWidth; + yInit = xInit / ratio; + } + + var x1 = ( realWidth - xInit ) / 2; + var y1 = ( realHeight - yInit ) / 2; + + var imgSelectOptions = { + handles: true, + keys: true, + instance: true, + persistent: true, + imageWidth: realWidth, + imageHeight: realHeight, + minWidth: xImg > xInit ? xInit : xImg, + minHeight: yImg > yInit ? yInit : yImg, + x1: x1, + y1: y1, + x2: xInit + x1, + y2: yInit + y1 + }; + + return imgSelectOptions; +} + +function superPWAsetImageFromURL(url, attachmentId, width, height) { + var choice, data = {}; + + data.url = url; + data.thumbnail_url = url; + data.timestamp = _.now(); + + if (attachmentId) { + data.attachment_id = attachmentId; + } + + if (width) { + data.width = width; + } + + if (height) { + data.height = height; + } + + console.log('url: ' + url); + + $("input[name='superpwa_settings[splash_icon]']").val( url ); +} + +function superPWAsetImageFromAttachment(attachment) { + + $("#heading_picture").val( attachment.url ); + $("#heading_picture_preview").prop("src", attachment.url); + +} + +function selectAndCropBtnHandler(e) { + e.preventDefault(); + + /* We need to setup a Crop control that contains a few parameters + and a method to indicate if the CropController can skip cropping the image. + In this example I am just creating a control on the fly with the expected properties. + However, the controls used by WordPress Admin are api.CroppedImageControl and api.SiteIconControl + */ + + var cropControl = { + id: "control-id", + params: { + flex_width: false, // set to true if the width of the cropped image can be different to the width defined here + flex_height: true, // set to true if the height of the cropped image can be different to the height defined here + width: 192, // set the desired width of the destination image here + height: 192, // set the desired height of the destination image here + } + }; + + cropControl.mustBeCropped = function (flexW, flexH, dstW, dstH, imgW, imgH) { + + // If the width and height are both flexible + // then the user does not need to crop the image. + + if (true === flexW && true === flexH) { + return false; + } + + // If the width is flexible and the cropped image height matches the current image height, + // then the user does not need to crop the image. + if (true === flexW && dstH === imgH) { + return false; + } + + // If the height is flexible and the cropped image width matches the current image width, + // then the user does not need to crop the image. + if (true === flexH && dstW === imgW) { + return false; + } + + // If the cropped image width matches the current image width, + // and the cropped image height matches the current image height + // then the user does not need to crop the image. + if (dstW === imgW && dstH === imgH) { + return false; + } + + // If the destination width is equal to or greater than the cropped image width + // then the user does not need to crop the image... + if (imgW <= dstW) { + return false; + } + + return true; + }; + + /* NOTE: Need to set this up every time instead of reusing if already there + as the toolbar button does not get reset when doing the following: + + mediaUploader.setState('library'); + mediaUploader.open(); + + */ + + mediaUploader = wp.media({ + button: { + text: 'Select and Crop', // l10n.selectAndCrop, + close: false + }, + states: [ + new wp.media.controller.Library({ + title: 'Select and Crop', // l10n.chooseImage, + library: wp.media.query({type: 'image'}), + multiple: false, + date: false, + priority: 20, + suggestedWidth: 192, + suggestedHeight: 192 + }), + new wp.media.controller.CustomizeImageCropper({ + imgSelectOptions: superPWACalculateImageSelectOptions, + control: cropControl + }) + ] + }); + + mediaUploader.on('cropped', function (croppedImage) { + + var url = croppedImage.url, + attachmentId = croppedImage.attachment_id, + w = croppedImage.width, + h = croppedImage.height; + + superPWAsetImageFromURL(url, attachmentId, w, h); + + }); + + mediaUploader.on('skippedcrop', function (selection) { + + var url = selection.get('url'), + w = selection.get('width'), + h = selection.get('height'); + + superPWAsetImageFromURL(url, selection.id, w, h); + + }); + + mediaUploader.on("select", function () { + + var attachment = mediaUploader.state().get('selection').first().toJSON(); + + if (cropControl.params.width === attachment.width + && cropControl.params.height === attachment.height + && !cropControl.params.flex_width + && !cropControl.params.flex_height) { + superPWAsetImageFromAttachment(attachment); + mediaUploader.close(); + } else { + mediaUploader.setState('cropper'); + } + + }); + + mediaUploader.open(); +} + jQuery(document).ready(function($){ $('.superpwa-colorpicker').wpColorPicker(); // Color picker - $('.superpwa-icon-upload').click(function(e) { // Application Icon upload - e.preventDefault(); - var superpwa_meda_uploader = wp.media({ - title: 'Application Icon', - button: { - text: 'Select Icon' - }, - multiple: false // Set this to true to allow multiple files to be selected - }) - .on('select', function() { - var attachment = superpwa_meda_uploader.state().get('selection').first().toJSON(); - $('.superpwa-icon').val(attachment.url); - }) - .open(); - }); + + $('.superpwa-icon-upload').click(selectAndCropBtnHandler); + $('.superpwa-splash-icon-upload').click(function(e) { // Splash Screen Icon upload e.preventDefault(); + var superpwa_meda_uploader = wp.media({ title: 'Splash Screen Icon', button: { - text: 'Select Icon' + text: 'Select and Crop', + close: false }, - multiple: false // Set this to true to allow multiple files to be selected - }) - .on('select', function() { - var attachment = superpwa_meda_uploader.state().get('selection').first().toJSON(); - $('.superpwa-splash-icon').val(attachment.url); - }) - .open(); + states: [ + new wp.media.controller.Library({ + title: 'Select and Crop', // l10n.chooseImage, + library: wp.media.query({type: 'image'}), + multiple: false, + date: false, + priority: 20, + suggestedWidth: 192, + suggestedHeight: 192 + }), + new wp.media.controller.CustomizeImageCropper({ + imgSelectOptions: superPWACalculateImageSelectOptions, + control: cropControl + }) + ] + }); + + superpwa_meda_uploader.on('cropped', function (croppedImage) { + + var url = croppedImage.url, + attachmentId = croppedImage.attachment_id, + w = croppedImage.width, + h = croppedImage.height; + + superPWAsetImageFromURL(url, attachmentId, w, h); + + }); + + superpwa_meda_uploader.on('skippedcrop', function (selection) { + + var url = selection.get('url'), + w = selection.get('width'), + h = selection.get('height'); + + superPWAsetImageFromURL(url, selection.id, w, h); + + }); + + superpwa_meda_uploader.on("select", function () { + + var attachment = superpwa_meda_uploader.state().get('selection').first().toJSON(); + + if (cropControl.params.width === attachment.width + && cropControl.params.height === attachment.height + && !cropControl.params.flex_width + && !cropControl.params.flex_height) { + superPWAsetImageFromAttachment(attachment); + superpwa_meda_uploader.close(); + } else { + superpwa_meda_uploader.setState('cropper'); + } + + }); + + superpwa_meda_uploader.open(); }); + $('.superpwa-app-short-name').on('input', function(e) { // Warn when app_short_name exceeds 12 characters. if ( $('.superpwa-app-short-name').val().length > 12 ) { $('.superpwa-app-short-name').css({'color': '#dc3232'}); From ef6c3e8848aaad6a9501ce713377376cc70b77f1 Mon Sep 17 00:00:00 2001 From: Maria Daniel Deepak Date: Mon, 4 Feb 2019 14:05:52 +0530 Subject: [PATCH 2/4] Make input name dynamic in `selectAndCropBtnHandler` --- admin/js/main.js | 56 ++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/admin/js/main.js b/admin/js/main.js index 4c447e2..db1224e 100644 --- a/admin/js/main.js +++ b/admin/js/main.js @@ -1,5 +1,5 @@ var mediaUploader; - +/* var cropControl = { id: "control-id", params: { @@ -46,7 +46,7 @@ cropControl.mustBeCropped = function (flexW, flexH, dstW, dstH, imgW, imgH) { return true; }; - +*/ function superPWACalculateImageSelectOptions(attachment, controller) { var control = controller.get( 'control' ); @@ -96,40 +96,30 @@ function superPWACalculateImageSelectOptions(attachment, controller) { return imgSelectOptions; } -function superPWAsetImageFromURL(url, attachmentId, width, height) { - var choice, data = {}; - - data.url = url; - data.thumbnail_url = url; - data.timestamp = _.now(); - - if (attachmentId) { - data.attachment_id = attachmentId; - } - - if (width) { - data.width = width; - } - - if (height) { - data.height = height; - } - - console.log('url: ' + url); - - $("input[name='superpwa_settings[splash_icon]']").val( url ); +function superPWAsetImageFromURL(url, attachmentId, width, height, inputName) { + $("input[name='" + inputName + "']").val( url ); } -function superPWAsetImageFromAttachment(attachment) { - - $("#heading_picture").val( attachment.url ); - $("#heading_picture_preview").prop("src", attachment.url); - +function superPWAsetImageFromAttachment(attachment, inputName) { + $("input[name='" + inputName +"']").val( attachment.url ); } function selectAndCropBtnHandler(e) { e.preventDefault(); + var inputNamesList = { + 'superpwa-icon-upload': 'superpwa_settings[icon]', + 'superpwa-splash-icon-upload': 'superpwa_settings[splash_icon]', + }, inputName; + + if($(e.target).hasClass('superpwa-icon-upload')) { + inputName = inputNamesList['superpwa-icon-upload'] + } else if ($(e.target).hasClass('superpwa-splash-icon-upload')) { + inputName = inputNamesList['superpwa-splash-icon-upload']; + } else { + inputName = ''; + } + /* We need to setup a Crop control that contains a few parameters and a method to indicate if the CropController can skip cropping the image. In this example I am just creating a control on the fly with the expected properties. @@ -220,7 +210,7 @@ function selectAndCropBtnHandler(e) { w = croppedImage.width, h = croppedImage.height; - superPWAsetImageFromURL(url, attachmentId, w, h); + superPWAsetImageFromURL(url, attachmentId, w, h, inputName); }); @@ -230,7 +220,7 @@ function selectAndCropBtnHandler(e) { w = selection.get('width'), h = selection.get('height'); - superPWAsetImageFromURL(url, selection.id, w, h); + superPWAsetImageFromURL(url, selection.id, w, h, inputName); }); @@ -242,7 +232,7 @@ function selectAndCropBtnHandler(e) { && cropControl.params.height === attachment.height && !cropControl.params.flex_width && !cropControl.params.flex_height) { - superPWAsetImageFromAttachment(attachment); + superPWAsetImageFromAttachment(attachment, inputName); mediaUploader.close(); } else { mediaUploader.setState('cropper'); @@ -277,7 +267,7 @@ jQuery(document).ready(function($){ suggestedWidth: 192, suggestedHeight: 192 }), - new wp.media.controller.CustomizeImageCropper({ + new wp.media.controller.CustomizeImageCropper( { imgSelectOptions: superPWACalculateImageSelectOptions, control: cropControl }) From fbff7a31fb68320b8a601994f45c0747c5461ed9 Mon Sep 17 00:00:00 2001 From: Maria Daniel Deepak Date: Mon, 4 Feb 2019 14:08:35 +0530 Subject: [PATCH 3/4] Reuse `selectAndCropBtnHandler` for both App & Splash icon --- admin/js/main.js | 113 +---------------------------------------------- 1 file changed, 1 insertion(+), 112 deletions(-) diff --git a/admin/js/main.js b/admin/js/main.js index db1224e..fa7f3de 100644 --- a/admin/js/main.js +++ b/admin/js/main.js @@ -1,52 +1,5 @@ var mediaUploader; -/* -var cropControl = { - id: "control-id", - params: { - flex_width: false, // set to true if the width of the cropped image can be different to the width defined here - flex_height: true, // set to true if the height of the cropped image can be different to the height defined here - width: 192, // set the desired width of the destination image here - height: 192, // set the desired height of the destination image here - } -}; - -cropControl.mustBeCropped = function (flexW, flexH, dstW, dstH, imgW, imgH) { - - // If the width and height are both flexible - // then the user does not need to crop the image. - - if (true === flexW && true === flexH) { - return false; - } - - // If the width is flexible and the cropped image height matches the current image height, - // then the user does not need to crop the image. - if (true === flexW && dstH === imgH) { - return false; - } - // If the height is flexible and the cropped image width matches the current image width, - // then the user does not need to crop the image. - if (true === flexH && dstW === imgW) { - return false; - } - - // If the cropped image width matches the current image width, - // and the cropped image height matches the current image height - // then the user does not need to crop the image. - if (dstW === imgW && dstH === imgH) { - return false; - } - - // If the destination width is equal to or greater than the cropped image width - // then the user does not need to crop the image... - if (imgW <= dstW) { - return false; - } - - return true; -}; -*/ function superPWACalculateImageSelectOptions(attachment, controller) { var control = controller.get( 'control' ); @@ -248,71 +201,7 @@ jQuery(document).ready(function($){ $('.superpwa-icon-upload').click(selectAndCropBtnHandler); - $('.superpwa-splash-icon-upload').click(function(e) { // Splash Screen Icon upload - e.preventDefault(); - - var superpwa_meda_uploader = wp.media({ - title: 'Splash Screen Icon', - button: { - text: 'Select and Crop', - close: false - }, - states: [ - new wp.media.controller.Library({ - title: 'Select and Crop', // l10n.chooseImage, - library: wp.media.query({type: 'image'}), - multiple: false, - date: false, - priority: 20, - suggestedWidth: 192, - suggestedHeight: 192 - }), - new wp.media.controller.CustomizeImageCropper( { - imgSelectOptions: superPWACalculateImageSelectOptions, - control: cropControl - }) - ] - }); - - superpwa_meda_uploader.on('cropped', function (croppedImage) { - - var url = croppedImage.url, - attachmentId = croppedImage.attachment_id, - w = croppedImage.width, - h = croppedImage.height; - - superPWAsetImageFromURL(url, attachmentId, w, h); - - }); - - superpwa_meda_uploader.on('skippedcrop', function (selection) { - - var url = selection.get('url'), - w = selection.get('width'), - h = selection.get('height'); - - superPWAsetImageFromURL(url, selection.id, w, h); - - }); - - superpwa_meda_uploader.on("select", function () { - - var attachment = superpwa_meda_uploader.state().get('selection').first().toJSON(); - - if (cropControl.params.width === attachment.width - && cropControl.params.height === attachment.height - && !cropControl.params.flex_width - && !cropControl.params.flex_height) { - superPWAsetImageFromAttachment(attachment); - superpwa_meda_uploader.close(); - } else { - superpwa_meda_uploader.setState('cropper'); - } - - }); - - superpwa_meda_uploader.open(); - }); + $('.superpwa-splash-icon-upload').click(selectAndCropBtnHandler); $('.superpwa-app-short-name').on('input', function(e) { // Warn when app_short_name exceeds 12 characters. if ( $('.superpwa-app-short-name').val().length > 12 ) { From 9f97a07a37e4c6992f300357f352196f7e84c61c Mon Sep 17 00:00:00 2001 From: Maria Daniel Deepak Date: Thu, 11 Apr 2019 20:06:07 +0530 Subject: [PATCH 4/4] Set Splash Icon crop wxh to 512x512 This shouldn't affect the Application Icon size --- admin/js/main.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/admin/js/main.js b/admin/js/main.js index fa7f3de..3a3b7dd 100644 --- a/admin/js/main.js +++ b/admin/js/main.js @@ -60,15 +60,17 @@ function superPWAsetImageFromAttachment(attachment, inputName) { function selectAndCropBtnHandler(e) { e.preventDefault(); - var inputNamesList = { - 'superpwa-icon-upload': 'superpwa_settings[icon]', - 'superpwa-splash-icon-upload': 'superpwa_settings[splash_icon]', - }, inputName; + var inputFieldsList = { + 'superpwa-icon-upload': {name: 'superpwa_settings[icon]', width: 192, height: 192}, + 'superpwa-splash-icon-upload': {name: 'superpwa_settings[splash_icon]', width: 512, height: 512}, + }, inputName, fieldKey; if($(e.target).hasClass('superpwa-icon-upload')) { - inputName = inputNamesList['superpwa-icon-upload'] + fieldKey = 'superpwa-icon-upload'; + inputName = inputFieldsList[fieldKey]['name'] } else if ($(e.target).hasClass('superpwa-splash-icon-upload')) { - inputName = inputNamesList['superpwa-splash-icon-upload']; + fieldKey = 'superpwa-splash-icon-upload'; + inputName = inputFieldsList[fieldKey]['name']; } else { inputName = ''; } @@ -84,8 +86,8 @@ function selectAndCropBtnHandler(e) { params: { flex_width: false, // set to true if the width of the cropped image can be different to the width defined here flex_height: true, // set to true if the height of the cropped image can be different to the height defined here - width: 192, // set the desired width of the destination image here - height: 192, // set the desired height of the destination image here + width: inputFieldsList[fieldKey]['width'], // set the desired width of the destination image here + height: inputFieldsList[fieldKey]['height'], // set the desired height of the destination image here } }; @@ -146,8 +148,8 @@ function selectAndCropBtnHandler(e) { multiple: false, date: false, priority: 20, - suggestedWidth: 192, - suggestedHeight: 192 + suggestedWidth: inputFieldsList[fieldKey]['width'], + suggestedHeight: inputFieldsList[fieldKey]['height'] }), new wp.media.controller.CustomizeImageCropper({ imgSelectOptions: superPWACalculateImageSelectOptions,