From 4008d54a3e7e86254a7c9bb2f2d10bec64beec7e Mon Sep 17 00:00:00 2001 From: George Shevtsov Date: Wed, 6 Nov 2019 12:36:03 +0200 Subject: [PATCH 1/3] add resizeWithRatio --- croppie.js | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/croppie.js b/croppie.js index 2652d0ef..26aed3fd 100755 --- a/croppie.js +++ b/croppie.js @@ -424,6 +424,9 @@ if (self.options.enableResize) { _initializeResize.call(self); } + if (self.options.enableResizeWithRatio) { + _initializeRatioResize.call(self); + } } // function _initRotationControls () { @@ -460,6 +463,139 @@ return this.options.enableExif && window.EXIF; } + function _initializeRatioResize() { + var self = this; + var wrap = document.createElement('div'); + var isDragging = false; + var direction; + var originalY; + var minSize = 50; + var maxWidth; + var maxHeight; + var ratio = self.options.viewport.width / self.options.viewport.height; + var tr; + var br; + + addClass(wrap, 'cr-resizer'); + css(wrap, { + width: this.options.viewport.width + 'px', + height: this.options.viewport.height + 'px' + }); + + tr = document.createElement('div'); + addClass(tr, 'cr-resizer-top-right'); + wrap.appendChild(tr); + + br = document.createElement('div'); + addClass(br, 'cr-resizer-bottom-right'); + wrap.appendChild(br); + + function getDirection(className) { + if(className.indexOf('top-right') >= 0) { + return 'tr'; + } + if(className.indexOf('bottom-right') >= 0) { + return 'br'; + } + } + + function mouseDown(ev) { + if (ev.button !== undefined && ev.button !== 0) return; + + ev.preventDefault(); + if (isDragging) { + return; + } + + var overlayRect = self.elements.overlay.getBoundingClientRect(); + + isDragging = true; + originalX = ev.pageX; + originalY = ev.pageY; + direction = getDirection(ev.currentTarget.className); + maxWidth = overlayRect.width; + maxHeight = overlayRect.height; + if (ev.touches) { + var touches = ev.touches[0]; + originalX = touches.pageX; + originalY = touches.pageY; + } + window.addEventListener('mousemove', mouseMove); + window.addEventListener('touchmove', mouseMove); + window.addEventListener('mouseup', mouseUp); + window.addEventListener('touchend', mouseUp); + document.body.style[CSS_USERSELECT] = 'none'; + } + + function mouseMove(ev) { + var pageX = ev.pageX; + var pageY = ev.pageY; + var newVHeight; + var newVWidth; + ev.preventDefault(); + + if (ev.touches) { + var touches = ev.touches[0]; + pageX = touches.pageX; + pageY = touches.pageY; + } + + var deltaY = pageY - originalY; + var deltaX = deltaY * ratio; + + if(direction === 'tr') { + newVHeight = self.options.viewport.height - deltaY; + newVWidth = self.options.viewport.width - deltaX; + } + if(direction === 'br') { + newVHeight = self.options.viewport.height + deltaY; + newVWidth = self.options.viewport.width + deltaX; + } + if( + (newVHeight && newVHeight >= minSize && newVHeight <= maxHeight && newVHeight <= self.options.boundary.height) + && + (newVWidth && newVWidth >= minSize && newVWidth <= maxWidth && newVWidth <= self.options.boundary.width) + ) { + css(wrap, { + height: newVHeight + 'px', + width: newVWidth + 'px' + }); + self.options.viewport.height = newVHeight; + self.options.viewport.width = newVWidth; + + css(self.elements.viewport, { + height: self.options.viewport.height + 'px', + width: self.options.viewport.width + 'px' + }); + } + + _updateOverlay.call(self); + _updateZoomLimits.call(self); + _updateCenterPoint.call(self); + _triggerUpdate.call(self); + originalY = pageY; + originalX = pageX; + } + + function mouseUp() { + isDragging = false; + window.removeEventListener('mousemove', mouseMove); + window.removeEventListener('touchmove', mouseMove); + window.removeEventListener('mouseup', mouseUp); + window.removeEventListener('touchend', mouseUp); + document.body.style[CSS_USERSELECT] = ''; + } + + tr.addEventListener('mousedown', mouseDown); + tr.addEventListener('touchstart', mouseDown); + + br.addEventListener('mousedown', mouseDown); + br.addEventListener('touchstart', mouseDown); + + + this.elements.boundary.appendChild(wrap); + } + function _initializeResize () { var self = this; var wrap = document.createElement('div'); From 744b1d830ae1730d214781dfc5f54b9fe2edd25a Mon Sep 17 00:00:00 2001 From: George Shevtsov Date: Wed, 6 Nov 2019 12:36:25 +0200 Subject: [PATCH 2/3] add styles for resizeHandlers top-right and bottom-right --- croppie.css | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/croppie.css b/croppie.css index 0af2e2c6..d0a52a53 100644 --- a/croppie.css +++ b/croppie.css @@ -42,13 +42,17 @@ } .croppie-container .cr-resizer-vertical, -.croppie-container .cr-resizer-horisontal { +.croppie-container .cr-resizer-horisontal, +.croppie-container .cr-resizer-top-right, +.croppie-container .cr-resizer-bottom-right { position: absolute; pointer-events: all; } .croppie-container .cr-resizer-vertical::after, -.croppie-container .cr-resizer-horisontal::after { +.croppie-container .cr-resizer-horisontal::after, +.croppie-container .cr-resizer-top-right::after, +.croppie-container .cr-resizer-bottom-right::after { display: block; position: absolute; box-sizing: border-box; @@ -66,11 +70,29 @@ height: 10px; } -.croppie-container .cr-resizer-vertical::after { +.croppie-container .cr-resizer-top-right, +.croppie-container .cr-resizer-bottom-right { + width: 10px; + height: 10px; + right: -5px; +} + +.croppie-container .cr-resizer-vertical { + cursor: row-resize; left: 50%; margin-left: -5px; } +.croppie-container .cr-resizer-top-right { + cursor: nesw-resize; + top: -5px; +} + +.croppie-container .cr-resizer-bottom-right { + cursor: nwse-resize; + bottom: -5px; +} + .croppie-container .cr-resizer-horisontal { right: -5px; cursor: col-resize; From 2c1d7329719510721edf3d2b3f852ce42511af8c Mon Sep 17 00:00:00 2001 From: George Shevtsov Date: Wed, 6 Nov 2019 12:36:56 +0200 Subject: [PATCH 3/3] add demo for resizeWithRatio --- demo/demo.js | 34 +++++++++++++++++++++++++++++----- index.html | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index c7a066b8..168d2c6b 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -144,16 +144,40 @@ var Demo = (function() { viewport: { width: 100, height: 100 }, boundary: { width: 300, height: 300 }, showZoomer: false, - enableResize: true, - enableOrientation: true, - mouseWheelZoom: 'ctrl' + enableResize: true, + enableOrientation: true, + mouseWheelZoom: 'ctrl' + }); + resize.bind({ + url: 'demo/demo-2.jpg', + zoom: 0 + }); + vEl.addEventListener('update', function (ev) { + }); + document.querySelector('.resizer-result').addEventListener('click', function (ev) { + resize.result({ + type: 'blob' + }).then(function (blob) { + popupResult({ + src: window.URL.createObjectURL(blob) + }); + }); + }); + } + function demoRatioResizer() { + var vEl = document.getElementById('resizer-ratio-demo'), + resize = new Croppie(vEl, { + viewport: { width: 250, height: 100 }, + boundary: { width: 300, height: 300 }, + showZoomer: false, + enableResizeWithRatio: true, + enableOrientation: true, }); resize.bind({ url: 'demo/demo-2.jpg', zoom: 0 }); vEl.addEventListener('update', function (ev) { - console.log('resize update', ev); }); document.querySelector('.resizer-result').addEventListener('click', function (ev) { resize.result({ @@ -178,7 +202,6 @@ var Demo = (function() { $uploadCrop.croppie('bind', { url: e.target.result }).then(function(){ - console.log('jQuery bind complete'); }); } @@ -251,6 +274,7 @@ var Demo = (function() { demoBasic(); demoVanilla(); demoResizer(); + demoRatioResizer(); demoUpload(); demoHidden(); } diff --git a/index.html b/index.html index 928a04b5..957576b6 100644 --- a/index.html +++ b/index.html @@ -399,6 +399,38 @@

Demos

+
+
+
+
+ Resize With Preserving Ratio Example +

+var el = document.getElementById('resizer-ratio-demo');
+var resize = new Croppie(el, {
+    viewport: { width: 100, height: 100 },
+    boundary: { width: 300, height: 100 },
+    showZoomer: false,
+    enableResizeWithRatio: true,
+    enableOrientation: true,
+    mouseWheelZoom: 'ctrl'
+});
+resize.bind({
+    url: 'demo/demo-2.jpg',
+});
+//on button click
+resize.result('blob').then(function(blob) {
+    // do something with cropped blob
+});
+
+ +
+
+
+
+
+
+
+