美文网首页
移动端cropper.js上传图片、裁剪

移动端cropper.js上传图片、裁剪

作者: 王远清orz | 来源:发表于2019-08-29 15:07 被阅读0次

代码全部贴出来,包括外链,比较长。
cropper.js官网:http://fengyuanchen.github.io/cropper/

先引入CSS

  <link rel="stylesheet" href="css/bootstrap.min.css">
  <link rel="stylesheet" href="css/cropper.css">
  <link rel="stylesheet" href="css/myCrop.css">

结构部分

<section>
    <input class="photoBtn" type="button" onclick="document.querySelector('.inputImage').click()" value="选择照片" >

    <input class="inputImage" type="file" accept="image/*" style="display: none;" data-area="&quot;width&quot;: 320, &quot;height&quot;: 180" />
    <br />
    <img class="showImg"/>
  </section>

  <div class="container containerDiv" style="padding:0;position:fixed;display: none;top: 0;left: 0;z-index: 200;">
    <div class="imgEdit" style="display: none">
      <div>
        <div class="img-container">
          <img src="" alt="Picture" class="image">
        </div>
      </div>
    </div>

    <div class="actions">
      <div class=" docs-buttons">
        
        <div class="btn-group btn-group-crop">
          <button type="button" class="btn btn-primary imgCutConfirm"  data-method="getCroppedCanvas"
            data-option="{ &quot;width&quot;: 200, &quot;height&quot;: 180}" ><!-- 生成图片的大小,以宽度计算,然后乘以剪切框比例 -->
            <span class="docs-tooltip" data-toggle="tooltip" title="">确认</span>
          </button>
        </div>

        <div class="btn-group">
          <button type="button" class="btn btn-primary" data-method="destroy" title="Destroy">
            <span class="docs-tooltip" data-toggle="tooltip">取消</span>
          </button>
        </div>

      </div>

    </div>
  </div>

JS

<script src="js/jquery-3.4.1.min.js"></script>
  <script src="js/bootstrap.bundle.min.js"></script>
  <script src="js/cropper.js"></script>
  <script src="js/myCrop.js"></script>
  <script type="text/javascript">
    var fileImg = "";

    $(function () {

      $(".imgCutConfirm").bind("click", function () {
        $(".containerDiv").hide();
        $(".imgEdit").hide();
        $(".getCroppedCanvasModal").modal("hide");
      })
    })

    //提交表达
    function submitForm() {
      $(".registerForm").attr("enctype", "multipart/form-data");

      var formData = new FormData($(".registerForm")[0]);
      formData.append("imgBase64", encodeURIComponent(fileImg));//
      formData.append("fileFileName", "photo.jpg");


      $.ajax({
        url: "",
        type: 'POST',
        data: formData,
        timeout: 10000, //超时时间设置,单位毫秒
        async: true,
        cache: false,
        contentType: false,
        processData: false,
        success: function (result) {
        },
        error: function (returndata) {
          Alert.closedLoading();
        }
      });
    }
  </script>

myCrop.css

/* Basic */

body {
  margin: 0;
  overflow-x: hidden;
}

.browserupgrade {
  margin: 0;
  padding: .5em 1em;
  background-color: #fcfcfc;
  text-align: center;
}


/* Header */

.docs-header {
  margin-bottom: 0;
}

.navbar-toggle:hover,
.navbar-toggle:focus {
  border-color: #0074d9;
}

.navbar-toggle .icon-bar {
  background-color: #0074d9;
}


/* Jumbotron */

.docs-jumbotron {
  background-color: #0074d9;
  color: #fff;
}

.docs-jumbotron .version {
  font-size: 14px;
  color: #fff;
  filter: alpha(opacity=50);
  opacity: 0.5;
}


/* Content */

.img-container,
.img-preview {
  background-color: #f7f7f7;
  width: 100%;
  text-align: center;
}

.img-container {
  min-height: 200px;
  max-height: 516px;
}

.img-container > img {
  max-width: 100%;
}

.docs-preview {
  margin-right: -15px;
}

.img-preview {
  float: left;
  margin-right: 10px;
  margin-bottom: 10px;
  overflow: hidden;
}

.img-preview > img {
  max-width: 100%;
}

.preview-lg {
  width: 263px;
  height: 148px;
}

.preview-md {
  width: 139px;
  height: 78px;
}

.preview-sm {
  width: 69px;
  height: 39px;
}

.preview-xs {
  width: 35px;
  height: 20px;
  margin-right: 0;
}

.docs-data > .input-group {
  margin-bottom: 10px;
}

.docs-data > .input-group > label {
  min-width: 80px;
}

.docs-data > .input-group > span {
  min-width: 50px;
}
.docs-buttons{
  text-align: center;
}
.docs-buttons > .btn,
.docs-buttons > .btn-group,
.docs-buttons > .form-control {
  margin-right: 5px;
}

.docs-toggles > .btn,
.docs-toggles > .btn-group,
.docs-toggles > .dropdown {
  margin-bottom: 10px;
}

.docs-tooltip {
  display: block;
}

.docs-tooltip > .icon {
  margin: 0 -3px;
  vertical-align: top;
}

.tooltip-inner {
  white-space: normal;
}

.btn-upload .tooltip-inner {
  white-space: nowrap;
}

.docs-options .dropdown-menu {
  width: 100%;
}

.docs-options .dropdown-menu > li {
  padding: 3px 20px;
}

.docs-options .dropdown-menu > li:hover {
  background-color: #f7f7f7;
}

.docs-options .dropdown-menu > li > label {
  display: block;
}

myCrop.js

window.onload = function() {
  ('use strict');

  var Cropper = window.Cropper;
  var URL = window.URL || window.webkitURL;
  var container = document.querySelector('.img-container');
  var image = container.getElementsByTagName('img').item(0);
  var actions = document.querySelector('.actions');
  var screenWidth = $(window).width();
  var screenHeight = $(window).height();
  var inputImage = document.querySelector('.inputImage');
  var dataArea;//dataArea里面width、height是裁剪框的尺寸
  dataArea = {
    area: inputImage.getAttribute('data-area') || undefined,
  };
  var cropArea = dataArea.area;
  cropArea = cropArea.replace(/"/g, '').replace(/\s*/g, '');//去除""和空格
  var areaObj = {};//将width、height转换成对象
  var arr = cropArea.split(',');
  for (var i = 0; i < arr.length; i++) {
    var kv = arr[i].split(':');
    if (areaObj[kv[0]]) {
      areaObj[kv[0]] += ',' + kv[1];
    } else {
      areaObj[kv[0]] = kv[1];
    }
  }

  var options = {
    minContainerHeight: screenHeight,
    minContainerWidth: screenWidth,
    aspectRatio: areaObj.width / areaObj.height,//根据页面中dataArea里面width、height设置裁剪框比例
    viewMode: 3, //显示
    guides: false, //裁剪框虚线 默认true有
    dragMode: 'move',
    autoCropArea: 0.8, //自动裁剪面积大小(百分比)和图片进行对比

    ready: function(e) {
      $('.containerDiv').show();
      $('.imgEdit').show();
    },

    background: true, // 容器是否显示网格背景
    movable: true, //是否能移动图片
    cropBoxMovable: true, //是否允许拖动裁剪框
    cropBoxResizable: false, //是否允许拖动 改变裁剪框大小
    toggleDragModeOnDblclick: false, //定义当点击两次时可以在“crop”和“move”之间切换拖拽模式
  };
  console.log(options.aspectRatio);
  console.log(options.autoCropArea);

  var cropper = new Cropper(image, options);
  var originalImageURL = image.src;
  var uploadedImageType = 'image/jpeg';
  var uploadedImageName = 'cropped.jpg';
  var uploadedImageURL;

  // // Buttons
  if (!document.createElement('canvas').getContext) {
    $('button[data-method="getCroppedCanvas"]').prop('disabled', true);
  }

  if (typeof document.createElement('cropper').style.transition === 'undefined') {
    $('button[data-method="scale"]').prop('disabled', true);
  }

  // Methods

  actions.querySelector('.docs-buttons').onclick = function(event) {
    var e = event || window.event;
    var target = e.target || e.srcElement;
    var cropped;
    var result;
    var input;
    var data;

    if (!cropper) {
      return;
    }

    while (target !== this) {
      if (target.getAttribute('data-method')) {
        break;
      }

      target = target.parentNode;
    }

    if (target === this || target.disabled || target.className.indexOf('disabled') > -1) {
      return;
    }

    data = {
      method: target.getAttribute('data-method'),
      option: target.getAttribute('data-option') || undefined,
      secondOption: target.getAttribute('data-second-option') || undefined,
    };

    // cropped = cropper.cropped;
    if (data.method) {
      switch (data.method) {
        // case 'rotate':
        //   if (cropped && options.viewMode > 0) {
        //     cropper.clear();
        //   }

        //   break;

        case 'getCroppedCanvas':
          try {
            data.option = JSON.parse(data.option);
          } catch (e) {
            console.log(e.message);
          }

          if (uploadedImageType === 'image/jpeg') {
            if (!data.option) {
              data.option = {};
            }

            data.option.fillColor = '#fff';
          }

          break;
      }

      result = cropper[data.method](data.option, data.secondOption);

      switch (data.method) {
        case 'rotate':
          if (cropped && options.viewMode > 0) {
            cropper.crop();
          }

          break;

        case 'scaleX':
        case 'scaleY':
          target.setAttribute('data-option', -data.option);
          break;

        case 'getCroppedCanvas':
          if (result) {
            fileImg = result.toDataURL('image/jpg');
            $('.showImg')
              .attr('src', fileImg)
              .show();
          }

          break;
        case 'destroy':
          $('.inputImage').val('');
          $('.containerDiv').hide();
          $('.imgEdit').hide();
          break;
      }

      if (typeof result === 'object' && result !== cropper && input) {
        try {
          input.value = JSON.stringify(result);
        } catch (e) {
          console.log(e.message);
        }
      }
    }
  };

  document.body.onkeydown = function(event) {
    var e = event || window.event;

    if (e.target !== this || !cropper || this.scrollTop > 300) {
      return;
    }
  };

  // Import image
  var inputImage = document.querySelector('.inputImage');

  if (URL) {
    inputImage.onchange = function() {
      var files = this.files;
      var file;

      if (cropper && files && files.length) {
        file = files[0];

        if (/^image\/\w+/.test(file.type)) {
          uploadedImageType = file.type;
          uploadedImageName = file.name;

          if (uploadedImageURL) {
            URL.revokeObjectURL(uploadedImageURL);
          }

          image.src = uploadedImageURL = URL.createObjectURL(file);
          cropper.destroy();
          cropper = new Cropper(image, options);
          inputImage.value = null;
        } else {
          window.alert('Please choose an image file.');
        }
      }
    };
  } else {
    inputImage.disabled = true;
    inputImage.parentNode.className += ' disabled';
  }
};

参考https://blog.csdn.net/qq727013465/article/details/51823231

我们项目用裁剪的地方比较多,所以做了一些更改,可以在HTML通过data-area中定义裁剪框比例
至于坑,感觉裁剪生成的图片比较模糊,没有官方文档清晰,应该是canvas绘图在高清屏显示问题,对canvas暂时还没有研究,等后面学习了再来填坑

相关文章