koorgoo / ngCropper

AngularJS wrapper for https://github.com/fengyuanchen/cropper
107 stars 72 forks source link

Multiple file inputs and croppers #8

Closed benlooi closed 9 years ago

benlooi commented 9 years ago

Hello, I've been trying to understand the code. It works well with one input file and cropper. I can't seem to do multiple files and croppers.

How does onFile work? If I have 2 input files, do I a) call a different function, like onFile2, or b) refer to the next file object in array, i.e., file[1]?

Confused.

How about the preview? Do I give the div a different class and pass it as an option, e.g $scope.option_2 = {preview:"some_other_class"}, then in the attribute, refer to it as ng-options="option_2".

Any help would be appreciated. Thanks in advance.

Here is my (obviously faulty) code:

JS:

   var file, file2, data, data2;

/**

HTML:

benlooi commented 9 years ago

OK! Finally did it correctly! Here's how you do multiple croppers on the same page. I'll post the corresponding HTML5 in the next post.

.controller ('addAlbumCtrl', function ($scope,$timeout,Cropper){

    var file, file2, data, data2;

/**
 * Method is called every time file input's value changes.
 * Because of Angular has not ng-change for file inputs a hack is needed -
 * call `angular.element(this).scope().onFile(this.files[0])`
 * when input's event is fired.
 */
$scope.onFile = function(blob) {
    Cropper.encode((file = blob)).then(function(dataUrl) {
    $scope.dataUrl = dataUrl;
    $timeout(showCropper);  // wait for $digest to set image's src
  });
};

//defined a second scope variable for the second input file, which we will call in the HTML //also assigned dataUrl2 to the 2nd file blob. Noticed I also changed the $timeout to showCropper2 as defined at the end of the controller.

      $scope.onFile2 = function(blob) {
     Cropper.encode((file = blob)).then(function(dataUrl) {
      $scope.dataUrl2 = dataUrl;
      $timeout(showCropper2);  // wait for $digest to set image's src
    });
  };

// When there is a cropped image to show encode it to base64 string and // use as a source for an image element.

   $scope.preview = function() {
        if (!file || !data) return;
        Cropper.crop(file, data).then(Cropper.encode).then(function(dataUrl) {
         ($scope.preview || ($scope.preview = {})).dataUrl = dataUrl;
        });
  };

//defined a second preview2 for the second input file. so, ng-click here will be preview2().

 $scope.preview2 = function() {
      if (!file || !data) return;
      Cropper.crop(file, data).then(Cropper.encode).then(function(dataUrl) {
       ($scope.preview2 || ($scope.preview2 = {})).dataUrl = dataUrl;
    });
      };

  $scope.scale = function(width) {
    Cropper.crop(file, data)
      .then(function(blob) {
       return Cropper.scale(blob, {width: width});
      })
      .then(Cropper.encode).then(function(dataUrl) {
        ($scope.preview || ($scope.preview = {})).dataUrl = dataUrl;
      });
  }

  $scope.scale2 = function(width) {
    Cropper.crop(file, data)
      .then(function(blob) {
       return Cropper.scale(blob, {width: width});
      })
     .then(Cropper.encode).then(function(dataUrl) {
       ($scope.preview2 || ($scope.preview2 = {})).dataUrl = dataUrl;
      });
  }

//specified where to show the preview. Take note it is a JQuery selector, so if you are using a class, you need to include the '.' prefix. You can use id as well, and change it to a hashtag sign

     $scope.options = {
            maximize: true,
           preview:'.preview-container',
         aspectRatio: 3/1,
       done: function(dataNew) {
       data = dataNew;
    }
  };

//for the second preview, give it a different name. See HTML code in next post.

      $scope.options_2 = {
       maximize: true,
      aspectRatio: 3/1,
      preview:'.preview-thumbnail',
       done: function(dataNew) {
       data = dataNew;
      }
     };

//showEvent2 and hideEvent2 is for the second input file

      $scope.showEvent2 = 'show';
      $scope.hideEvent2 = 'hide';

     function showCropper() { $scope.$broadcast($scope.showEvent); }
     function hideCropper() { $scope.$broadcast($scope.hideEvent); }

//showCropper2 and hideCropper2 is for 2nd input file

    function showCropper2() { $scope.$broadcast($scope.showEvent2); }
     function hideCropper2() { $scope.$broadcast($scope.hideEvent2); }

        })
benlooi commented 9 years ago

Here's my HTML5

<section>
<div class="form-group">
<label>
    Album Art (900 x 300 px)
     <form>
     <input type="file" onchange="angular.element(this).scope().onFile(this.files[0])">
  <button ng-click="preview()">Show preview</button>
  <button ng-click="scale(200)">Scale to 200px width</button>
  <label>Disabled <input type="checkbox" ng-model="options.disabled"></label>

  <br />

  <div ng-if="dataUrl" class="img-container">
    <img ng-if="dataUrl" ng-src="{{dataUrl}}" width="900"
     ng-cropper ng-show="{{showEvent}}" ng-hide="{{hideEvent}}" ng-options="options">
  </div>

  <div class="preview-container">
    <img ng-if="preview.dataUrl" ng-src="{{preview.dataUrl}}">
  </div>

</div>

   </form>

<div class="form-group">
         <input type="file" onchange="angular.element(this).scope().onFile2(this.files[0])">
  <button ng-click="preview2()">Show preview</button>
  <button ng-click="scale(200)">Scale to 200px width</button>
  <label>Disabled <input type="checkbox" ng-model="options.disabled"></label>

  <br />

  <div ng-if="dataUrl2" class="img-thumb-container">
    <img ng-if="dataUrl2" ng-src="{{dataUrl2}}" width="900"
     ng-cropper ng-show="{{showEvent2}}" ng-hide="{{hideEvent2}}" ng-options="options_2">
  </div>

  <div class="preview-thumbnail">
    <img ng-if="preview2.dataUrl" ng-src="{{preview2.dataUrl}}">
  </div>

 <!--  <input type="file" ng-file-select="onFileSelect($files)" multiple> -->

</div>
</section>

And the CSS for the previews. DO note the previews have to be the same aspect ratio as what you specified in the options. I sent mine to 3 / 1.

.preview-container {
        overflow:hidden;
        width:900px;
        height:300px;
    }
    .preview-thumbnail {
        overflow:hidden;
        width:900px;
        height:300px;
    }
muhammadn commented 8 years ago

You did not use file2 or data2 so question: why did you declare those two variables?

EDIT: you don't need those two variables for it to work.

grantwhitaker06 commented 8 years ago

@benlooi helped me out was tearing my hair out thanks buddy.