Dropzone.js使用cropper.js上载模态图像

问题描述 投票:1回答:1

我有一个代码,负责打开模态窗口中拖放字段(dropzone.js)中加载的图像,以便使用cropper.js进行裁剪。该代码工作一半。模态窗口打开,但是模态窗口内部的按钮不起作用。出现错误。 “未捕获的TypeError:无法读取null的属性'cropper'”。如何解决这个问题?这是代码。

<script type="text/javascript">
    Dropzone.autoDiscover = false;
    var c = 0;
    var cropped = false;
    var myDropzone = new Dropzone('div#myDropzone', {
    url: "/plugins/dropzone/dist/upload.php",
    addRemoveLinks: true,
    createImageThumbnails: true,
    autoProcessQueue: false
    });

myDropzone.on('addedfile', function(file) {
    if (!cropped) {
      myDropzone.removeFile(file);
      cropper(file);
    } else {
      cropped = false;
      var previewURL = URL.createObjectURL(file);
      var dzPreview = $(file.previewElement).find('img');
      dzPreview.attr("src", previewURL);
    }
  });

    var cropper = function(file) {
    var fileName = file.name;
    var loadedFilePath = getSrcImageFromBlob(file);
    // @formatter:off
    var modalTemplate =
      '<div class="modal fade" tabindex="-1" role="dialog">' +
      '<div class="modal-dialog" role="document">' +
      '<div class="modal-content">' +
      '<div class="modal-header">' +
      '<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times" aria-hidden="true"></i></button>' +
      '</div>' +
      '<div class="modal-body">' +
      '<div class="cropper-container">' +
      '<img id="img-' + c + '" src="' + loadedFilePath + '" data-vertical-flip="false" data-horizontal-flip="false">' +
      '</div>' +
      '</div>' +
      '<div class="modal-footer">' +
      '<button type="button" class="btn btn-warning rotate-left"><span class="fa fa-rotate-left"></span></button>' +
      '<button type="button" class="btn btn-warning rotate-right"><span class="fa fa-rotate-right"></span></button>' +
      '<button type="button" class="btn btn-warning scale-x" data-value="-1"><span class="fa fa-arrows-h"></span></button>' +
      '<button type="button" class="btn btn-warning scale-y" data-value="-1"><span class="fa fa-arrows-v"></span></button>' +
      '<button type="button" class="btn btn-warning reset"><span class="fa fa-refresh"></span></button>' +
      '<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>' +
      '<button type="button" class="btn btn-primary crop-upload">Crop & upload</button>' +
      '</div>' +
      '</div>' +
      '</div>' +
      '</div>';
    // @formatter:on
jQuery(modalTemplate).modal('show').on("shown.bs.modal", function() {
      var $image = $('#img-' + c);
      console.log($image);
      var cropper = $image.cropper({
          autoCropArea: 1,
          aspectRatio: 9 / 16,
          cropBoxResizable: false,
          movable: true,
          rotatable: true,
          scalable: true,
          viewMode: 2,
          minContainerWidth: 250,
          maxContainerWidth: 250
        })
        .on('hidden.bs.modal', function() {
          $image.cropper('destroy');
        });

$cropperModal.on('click', '.crop-upload', function() {
          // get cropped image data
          $image.cropper('getCroppedCanvas', {
            width: 160,
            height: 90,
            minWidth: 256,
            minHeight: 256,
            maxWidth: 4096,
            maxHeight: 4096,
            fillColor: '#fff',
            imageSmoothingEnabled: false,
            imageSmoothingQuality: 'high'
          }).toBlob(function(blob) {
            var croppedFile = blobToFile(blob, fileName);
            croppedFile.accepted = true;
            var files = myDropzone.getAcceptedFiles();
            for (var i = 0; i < files.length; i++) {
              var file = files[i];
              if (file.name === fileName) {
                myDropzone.removeFile(file);
              }
            }
            cropped = true;

            myDropzone.files.push(croppedFile);
            myDropzone.emit('addedfile', croppedFile);
            myDropzone.createThumbnail(croppedFile); //, width, height, resizeMethod, fixOrientation, callback)
            $cropperModal.modal('hide');
          });
        })
        .on('click', '.rotate-right', function() {
          $image.cropper('rotate', 90);
        })
        .on('click', '.rotate-left', function() {
          $image.cropper('rotate', -90);
        })
        .on('click', '.reset', function() {
          $image.cropper('reset');
        })
        .on('click', '.scale-x', function() {
          if (!$image.data('horizontal-flip')) {
            $image.cropper('scale', -1, 1);
            $image.data('horizontal-flip', true);
          } else {
            $image.cropper('scale', 1, 1);
            $image.data('horizontal-flip', false);
          }
        })
        .on('click', '.scale-y', function() {
          if (!$image.data('vertical-flip')) {
            $image.cropper('scale', 1, -1);
            $image.data('vertical-flip', true);
          } else {
            $image.cropper('scale', 1, 1);
            $image.data('vertical-flip', false);
          }
        });
    });
  };

  function getSrcImageFromBlob(blob) {
    var urlCreator = window.URL || window.webkitURL;
    return urlCreator.createObjectURL(blob);
  }

  function blobToFile(theBlob, fileName) {
    theBlob.lastModifiedDate = new Date();
    theBlob.name = fileName;
    return theBlob;
  }
</script>
bootstrap-modal dropzone.js cropperjs
1个回答
0
投票

确保$imageon("shown.bs.modal", function() {功能之外初始化

工作示例

var dropzone = new Dropzone('div#dropzone', {
  url: "/plugins/dropzone/dist/upload.php",
  addRemoveLinks: true,
  createImageThumbnails: true,
  autoProcessQueue: false
});

dropzone.on('addedfile', function(file) {
  
  dropzone.removeFile(file);
  cropper(file);
  
});

$(function() {
  fetch("https://i.picsum.photos/id/539/200/300.jpg")
    .then(response => response.blob())
    .then(blob => {
      cropper(blob);
    })
})

function cropper(file) { 
  const url = URL.createObjectURL(file);
    
  var modalTemplate = `<div class="modal fade" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
      </div>
      <div class="modal-body">
        <img id="img" src="${url}" data-vertical-flip="false" data-horizontal-flip="false">
      </div>
      <div class="modal-footer">
        <button class="rotate-right">Rotate Right</button>
      </div>  
    </div>
  </div>
</div>`

  var $cropperModal = $(modalTemplate);
  var $image = null;
  
  $cropperModal.on("shown.bs.modal", function() {
    $image = $('#img');
    var cropper = $image.cropper({
      autoCropArea: 1,
      aspectRatio: 9 / 16,
      cropBoxResizable: false,
      movable: true,
      rotatable: true,
      scalable: true,
      viewMode: 2,
      minContainerWidth: 250,
      maxContainerWidth: 250
    });
  
  }).on('click', '.rotate-right', function() {
    $image.cropper('rotate', 90);
  }).modal({show: true})
}
img {
  display: block;
  max-width: 100%;
}

#dropzone {
  height: 100px 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.7/cropper.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.0/basic.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.0/dropzone.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.0/dropzone.js"></script>
<script>window.Dropzone.autoDiscover = false;</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.7/cropper.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery-cropper.min.js"></script>

<div id="dropzone" class="dropzone"></div>
© www.soinside.com 2019 - 2024. All rights reserved.