javascriptjquerymvvmcropperjs

How to get 'zoom' and 'rotate' working with Cropper.js


I am using Cropper.js to edit images. So far so good, I can load and crop and save those images.

I have not been able to get the buttons for 'zoom' and 'rotate' working.

*** Zoom DOES work when I use my mouse's scroll wheel

I have tried pasting in the code from the main distribution and trying to tweak it from there, but have not had any positive results.

The HTML:

        <div class="btn-group">
          <button type="button" class="btn btn-primary" data-method="zoom" data-option="0.1" title="Zoom In">
            <span class="docs-tooltip" data-toggle="tooltip" title="cropper.zoom(0.1)">
              <span class="fa fa-search-plus"></span>
            </span>
          </button>
          <button type="button" class="btn btn-primary" data-method="zoom" data-option="-0.1" title="Zoom Out">
            <span class="docs-tooltip" data-toggle="tooltip" title="cropper.zoom(-0.1)">
              <span class="fa fa-search-minus"></span>
            </span>
          </button>
        </div>
        
         <div class="input-group input-group-sm">
            <label class="input-group-addon" for="dataRotate">Rotate</label>
            <input type="text" class="form-control" id="dataRotate" placeholder="rotate">
            <span class="input-group-addon">deg</span>
         </div>

The JS: (the code I pasted in from the dist starts at the line: var URL = window.URL || window.webkitURL; And ends at the line: console.log("test"); All the other code is working for me.

<cfset imgname2 = "#getProd.ProductName#-midsize">

   <script>
    window.addEventListener('DOMContentLoaded', function () {
      var midsize = document.getElementById('avatar2-<cfoutput>#ProdPhotoID#</cfoutput>');
      var image = document.getElementById('image2-<cfoutput>#ProdPhotoID#</cfoutput>');
      var input = document.getElementById('input2-<cfoutput>#ProdPhotoID#</cfoutput>');
      var $progress = $('.progress');
      var $progressBar = $('.progress-bar');
      var $alert = $('.alert');
      var $modal = $('#modal2-<cfoutput>#ProdPhotoID#</cfoutput>');
      var cropper = null;
      

      $('[data-toggle="tooltip"]').tooltip();

      input.addEventListener('change', function (e) {
        var files = e.target.files;
        var done = function (url) {
          input.value = '';
          image.src = url;
          if(cropper)
          {
              cropper.destroy();
              cropper = new Cropper(image, {
                    aspectRatio: 1,
                    viewMode: 3,
              });
          }
          $alert.hide();
          $modal.modal('show');
        };
        var reader;
        var file;
        var url;
        
  
  var URL = window.URL || window.webkitURL;
  var container = document.querySelector('.img-container');
  
  var download = document.getElementById('download');       
  var actions = document.getElementById('actions');
  var dataX = document.getElementById('dataX');
  var dataY = document.getElementById('dataY');
  var dataHeight = document.getElementById('dataHeight');
  var dataWidth = document.getElementById('dataWidth');
  var dataRotate = document.getElementById('dataRotate');
  var dataScaleX = document.getElementById('dataScaleX');
  var dataScaleY = document.getElementById('dataScaleY');
        
  var options = {
    aspectRatio: 321 / 180,
    preview: '.img-preview',
    ready: function(e) {
      console.log(e.type);
    },
    cropstart: function(e) {
      console.log(e.type, e.detail.action);
    },
    cropmove: function(e) {
      console.log(e.type, e.detail.action);
    },
    cropend: function(e) {
      console.log(e.type, e.detail.action);
    },
    crop: function(e) {
      var data = e.detail;

      console.log(e.type);
      dataX.value = Math.round(data.x);
      dataY.value = Math.round(data.y);
      dataHeight.value = Math.round(data.height);
      dataWidth.value = Math.round(data.width);
      dataRotate.value = typeof data.rotate !== 'undefined' ? data.rotate : '';
      dataScaleX.value = typeof data.scaleX !== 'undefined' ? data.scaleX : '';
      dataScaleY.value = typeof data.scaleY !== 'undefined' ? data.scaleY : '';
    },
    zoom: function(e) {
      console.log(e.type, e.detail.ratio);
      console.log("test");
    }
  };
  
         if (files && files.length > 0) {
          file = files[0];
            $("#midsizeImageModal-<cfoutput>#ProdPhotoID#</cfoutput>").modal('hide');  <!-- close 1st window if new image selected to crop-->
          if (URL) {
            done(URL.createObjectURL(file));
          } else if (FileReader) {
            reader = new FileReader();
            reader.onload = function (e) {
              done(reader.result);
            };
            reader.readAsDataURL(file);
          }
        }
      });

      $modal.on('shown.bs.modal', function () {
          if(!cropper)
            cropper = new Cropper(image, {
                aspectRatio: 1,
                viewMode: 3,
            });
      }).on('hidden.bs.modal', function () {
        if(cropper)
        {
            cropper.destroy();
            cropper = null;
        }        
        
      });

      document.getElementById('crop2-<cfoutput>#ProdPhotoID#</cfoutput>').addEventListener('click', function () {
        var initialmidsizeURL;
        var canvas;

        $modal.modal('hide');

        if (cropper) {
          canvas = cropper.getCroppedCanvas({
            width: 560,
            height: 460,
          });
          initialmidsizeURL = midsize.src;
          midsize.src = canvas.toDataURL();
          $progress.show();
          $alert.removeClass('alert-success alert-warning');
          canvas.toBlob(function (blob) {
            var formData = new FormData();

            formData.append('midsize', blob, 'midsize.jpg');
            formData.append('imageName', "<cfoutput>#imgname2#</cfoutput>");
            formData.append('prodID', "<cfoutput>#URL.prodid#</cfoutput>");
            formData.append('photoID', "<cfoutput>#ProdPhotoID#</cfoutput>"); 
            
            $.ajax('inc/_image_midsize_ajax.cfm', {
              method: 'POST',
              data: formData,      
              processData: false,
              contentType: false,

              xhr: function () {
                var xhr = new XMLHttpRequest();

                xhr.upload.onprogress = function (e) {
                  var percent = '0';
                  var percentage = '0%';

                  if (e.lengthComputable) {
                    percent = Math.round((e.loaded / e.total) * 100);
                    percentage = percent + '%';
                    $progressBar.width(percentage).attr('aria-valuenow', percent).text(percentage);
                  }
                };

                return xhr;
              },

              success: function () {
                $alert.show().addClass('alert-success').text('Upload success');
              },

              error: function () {
                midsize.src = initialmidsizeURL;
                $alert.show().addClass('alert-warning').text('Upload error');
              },

              complete: function () {
                $progress.hide();
              },
              
              
            
              
              
            });
          });
        }
      });
    });
  </script>

Trying to get scroll and rotate working by using the buttons.


Solution

  • This worked for me (and was a beast!). Posting it here in case it helps someone out in the future...

    <div class="btn-group">
          <button
            id="ZoomInBtn"
            type="button"
            class="btn btn-primary"
            data-method="zoom"
            data-option="0.1"
            title="Zoom In"
          >
            <span
              class="docs-tooltip"
              data-toggle="tooltip"
              title="cropper.zoom(0.1)"
            >
              <span class="fa fa-search-plus">+</span>
            </span>
          </button>
          <button
            id="ZoomOutBtn"
            type="button"
            class="btn btn-primary"
            data-method="zoom"
            data-option="-0.1"
            title="Zoom Out"
          >
            <span
              class="docs-tooltip"
              data-toggle="tooltip"
              title="cropper.zoom(-0.1)"
            >
              <span class="fa fa-search-minus">-</span>
            </span>
          </button>
        </div>
    
        <div class="input-group input-group-sm">
          <label class="input-group-addon" for="dataRotate">Rotate</label>
          <input type="text" class="form-control" id="dataRotate" placeholder="rotate">
          <span class="input-group-addon">deg</span>
        </div>
    
    
         window.addEventListener('DOMContentLoaded', function () {
          var midsize = document.getElementById('avatar2-<cfoutput>#ProdPhotoID# 
       </cfoutput>');
          var image = document.getElementById('image2-<cfoutput>#ProdPhotoID# 
       </cfoutput>');
          var input = document.getElementById('input2-<cfoutput>#ProdPhotoID# 
       </cfoutput>');
          var $progress = $('.progress');
          var $progressBar = $('.progress-bar');
          var $alert = $('.alert');
          var $modal = $('#modal2-<cfoutput>#ProdPhotoID#</cfoutput>');
          var cropper = null;
    
    
          $('[data-toggle="tooltip"]').tooltip();
    
          input.addEventListener('change', function (e) {
            var files = e.target.files;
            var done = function (url) {
              input.value = '';
              image.src = url;
              if(cropper)
              {
                  cropper.destroy();
                  cropper = new Cropper(image, {
                        aspectRatio: 1,
                        viewMode: 3,
    
        const ZIBtn = document.getElementById('ZoomInBtn');
        const ZOBtn = document.getElementById('ZoomOutBtn');
    
                  });
              }
              $alert.hide();
              $modal.modal('show');
            };
            var reader;
            var file;
            var url;
    
    
         var URL = window.URL || window.webkitURL;
         var container = document.querySelector('.img-container');
    
         var download = document.getElementById('download');        
         var actions = document.getElementById('actions');
         var dataX = document.getElementById('dataX');
         var dataY = document.getElementById('dataY');
         var dataHeight = document.getElementById('dataHeight');
         var dataWidth = document.getElementById('dataWidth');
         var dataRotate = document.getElementById('dataRotate');
         var dataScaleX = document.getElementById('dataScaleX');
         var dataScaleY = document.getElementById('dataScaleY');
    
         var options = {
         aspectRatio: 321 / 180,
         preview: '.img-preview',
         ready: function(e) {
          console.log(e.type);
        },
        cropstart: function(e) {
    
            // Change the zoom: function(e) {} in var options as below
    
        zoom: function(e) {
            // console.log(e.type, e.detail.ratio);
            if (e.target.id === 'ZoomInBtn') {
              cropper.zoom(0.1);
            }
            if (e.target.id === 'ZoomOutBtn') {
              cropper.zoom(-0.1);
            }
          }
    
    
    
          console.log(e.type, e.detail.action);
        },
        cropmove: function(e) {
          console.log(e.type, e.detail.action);
        },
    
        ZIBtn.onclick = options.zoom;
        ZOBtn.onclick = options.zoom; 
    
        cropend: function(e) {
          console.log(e.type, e.detail.action);
        },
        crop: function(e) {
          var data = e.detail;
    
          console.log(e.type);
          dataX.value = Math.round(data.x);
          dataY.value = Math.round(data.y);
          dataHeight.value = Math.round(data.height);
          dataWidth.value = Math.round(data.width);
          dataRotate.value = typeof data.rotate !== 'undefined' ? data.rotate : '';
          dataScaleX.value = typeof data.scaleX !== 'undefined' ? data.scaleX : '';
          dataScaleY.value = typeof data.scaleY !== 'undefined' ? data.scaleY : '';
        },
        zoom: function(e) {
          console.log(e.type, e.detail.ratio);
          console.log("test");
        }
      };
    
    
    
            if (files && files.length > 0) {
              file = files[0];
                $("#midsizeImageModal-<cfoutput>#ProdPhotoID#</cfoutput>").modal('hide');  <!-- close 1st window if new image selected to crop-->
              if (URL) {
                done(URL.createObjectURL(file));
              } else if (FileReader) {
                reader = new FileReader();
                reader.onload = function (e) {
                  done(reader.result);
                };
                reader.readAsDataURL(file);
              }
            }
          });
    
          $modal.on('shown.bs.modal', function () {
              if(!cropper)
                cropper = new Cropper(image, {
                    aspectRatio: 1,
                    viewMode: 3,
                });
          }).on('hidden.bs.modal', function () {
            if(cropper)
            {
                cropper.destroy();
                cropper = null;
            }        
    
          });