基于cropper.js封装vue在线图片裁剪组件

基于cropper.js封装vue在线图片裁剪组件_第1张图片
cropper-demo.jpg

github:demo下载

cropper.js

github:cropper.js

官网(demo)

cropper.js 安装

  • npm或bower安装
npm install cropper
# or
bower install cropper
  • clone下载:下载地址
git clone https://github.com/fengyuanchen/cropper.git

引用cropper.js

  • 主要引用cropper.js跟cropper.css两个文件



注意:必须先引入jquery文件,才能使用cropper.js插件

简单使用

  • 构建截图所要用到的div容器

![](picture.jpg)
  • 添加容器的样式,让img填充满整个容器(很重要)
/* Limit image width to avoid overflow the container */
img {
  max-width: 100%; /* This rule is very important, please do not ignore this! */
}
  • 调用cropper.js方法,初始化截图控件
$('#image').cropper({
  aspectRatio: 16 / 9,
  crop: function(e) {
    // Output the result data for cropping image.
    console.log(e.x);
    console.log(e.y);
    console.log(e.width);
    console.log(e.height);
    console.log(e.rotate);
    console.log(e.scaleX);
    console.log(e.scaleY);
  }
});

其他详细api请参考:github:cropper.js

封装成vue组件

封装成vue组件中需解决的问题

  • cropper.js相关
    • 模拟input框点击选择图片并对选择的图片进行格式、大小限制
    • 重新选择图片裁剪
    • 确认裁剪并获取base64格式的图片信息
  • vue相关
    • 非父子组件之间的通信问题

模拟input框点击选择图片并对选择的图片进行格式、大小限制

  • 构建一个隐藏的input标签,然后模拟点击此input,从而达到能选择图片的功能


//模拟点击
document.getElementById('myCropper-input').click();
  • 给input绑定一个监听内容变化的方法,拿到上传的文件,并进行格式、大小校验
// imgCropperData: {
//   accept: 'image/gif, image/jpeg, image/png, image/bmp',
// }
handleFile (e) {
  let _this = this;
  let inputDOM = this.$refs.inputer;
  // 通过DOM取文件数据
  _this.file = inputDOM.files[0];
  // 判断文件格式
  if (_this.imgCropperData.accept.indexOf(_this.file.type) == -1) {
    _this.$Modal.error({
      title: '格式错误',
      content: '您选择的图片格式不正确!'
    });
    return;
  }
  // 判断文件大小限制
  if (_this.file.size > 5242880) {
    _this.$Modal.error({
      title: '超出限制',
      content: '您选择的图片过大,请选择5MB以内的图片!'
    });
    return;
  }
  var reader = new FileReader();
  // 将图片将转成 base64 格式
  reader.readAsDataURL(_this.file);
  reader.onload = function () {
    _this.imgCropperData.imgSrc = this.result;
    _this.initCropper();
  }
}

参考:从0开始做一个的Vue图片/ 文件选择(上传)组件[基础向]

重新选择图片裁剪

  • 当第一次选择图片之后,肯定会面临需要重选图片的问题,那么就会面临如何替换掉裁剪框中的图片,上面的步骤选择了图片后通过FileRender()方法拿到了图片的主要信息,现在就需要重新构建裁剪框就可以解决问题了,查看cropper.js给出的官方demo,发现官方是使用动态添加裁剪容器的方法,进行操作的,这里我们仿照官方进行实现。
// 初始化剪切
  initCropper () {
    let _this = this;
    // 初始化裁剪区域
    _this.imgObj = $('![](' + _this.imgCropperData.imgSrc + ')');
    let $avatarPreview = $('.avatar-preview');
    $('#myCropper-workspace').empty().html(_this.imgObj);
    _this.imgObj.cropper({
      aspectRatio: _this.proportionX / _this.proportionY,
      preview: $avatarPreview,
      crop: function(e) {
        
      }
    });
  }

确认裁剪并获取base64格式的图片信息

let $imgData = _this.imgObj.cropper('getCroppedCanvas')
imgBase64Data = $imgData.toDataURL('image/png'); 

构造用于上传的数据

// 构造上传图片的数据
let formData = new FormData();
// 截取字符串
let photoType = imgBase64Data.substring(imgBase64Data.indexOf(",") + 1);
//进制转换
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
  const byteCharacters = atob(b64Data);
  const byteArrays = [];
  for(let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);
    const byteNumbers = new Array(slice.length);
    for(let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }
  const blob = new Blob(byteArrays, {
    type: contentType
  });
  return blob;
}
const contentType = 'image/jepg';
const b64Data2 = photoType;
const blob = b64toBlob(b64Data2, contentType);
formData.append("file", blob, "client-camera-photo.png")
formData.append("type", _this.imgType)

非父子组件之间的通信问题

在之前的项目中,常用到父子组件之间的通信传参,一般用两种方法

  • 在router里面放置参数,然后通过调用$route.params.xxx或者$route.query.xxx进行获取
  • 通过props进行通信

这里我们使用eventBus进行组件之间的通信

步骤

1.声明一个bus组件用于B组件把参数传递给A组件

//bus.js
import Vue from 'vue';  
export default new Vue();

2.在A组件中引用bus组件,并实时监听其参数变化

// A.vue
import Bus from '../../components/bus/bus.js'

export default {
  components: { Bus },
  data () {},
  created: function () {
    Bus.$on('getTarget', imgToken => {  
      var _this = this;
      console.log(imgToken);
      ...  
    });  
  }
}

3.B组件中同样引用bus组件,来把参数传给A组件

// B.vue
// 传参
Bus.$emit('getTarget', imgToken); 

参考:

  • vue-$on
  • vue-$emit
  • vue.js之路(4)——vue2.0s中eventBus实现兄弟组件通信

vue选图截图插件完整代码







BY-LucaLJX

github: lucaljx

你可能感兴趣的:(基于cropper.js封装vue在线图片裁剪组件)