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


Posted in Javascript onMarch 01, 2018

效果图如下所示,

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

vue选图截图插件完整代码

<template>
 <div class="myCropper-container">
 <div id="myCropper-workspace">
  <div class="myCropper-words" v-show="!imgCropperData.imgSrc">请点击按钮选择图片进行裁剪</div>
 </div>
 <div class="myCropper-preview" :class="isShort ? 'myCropper-preview-short' : 'myCropper-preview-long'">
  <div class="myCropper-preview-1 avatar-preview">
  ![](!imgCropperData.imgUploadSrc ? '/images/thumbnail/thumbnail-img.jpg' : imgCropperData.imgUploadSrc)
  </div>
  <div class="myCropper-preview-2 avatar-preview">
  ![](!imgCropperData.imgUploadSrc ? '/images/thumbnail/thumbnail-img.jpg' : imgCropperData.imgUploadSrc)
  </div>
  <div class="myCropper-preview-3 avatar-preview">
  ![](!imgCropperData.imgUploadSrc ? '/images/thumbnail/thumbnail-img.jpg' : imgCropperData.imgUploadSrc)
  </div>
  <input id="myCropper-input" type="file" :accept="imgCropperData.accept" ref="inputer" @change="handleFile">
  <Button type="ghost" class="myCropper-btn" @click="btnClick">选择图片</Button>
  <Button type="primary" class="myCropper-btn" :loading="cropperLoading" @click="crop_ok">确认</Button>
 </div>
 </div>
</template>
<script>
 var ezjsUtil = Vue.ezjsUtil;
 import Bus from './bus/bus.js' 
 export default {
 components: { Bus },
 props: {
  imgType: {
  type: String
  },
  proportionX: {
  type: Number
  },
  proportionY: {
  type: Number
  }
 },
 data () {
  return {
  imgCropperData: {
   accept: 'image/gif, image/jpeg, image/png, image/bmp',
   maxSize: 5242880,
   file: null, //上传的文件
   imgSrc: '', //读取的img文件base64数据流
   imgUploadSrc: '', //裁剪之后的img文件base64数据流
  },
  imgObj: null,
  hasSelectImg: false,
  cropperLoading: false,
  isShort: false,
  }
 },
 created: function () {
  let _this = this;
 },
 mounted: function () {
  let _this = this;
  // 初始化预览区域
  let maxWidthNum = Math.floor(300 / _this.proportionX);
  let previewWidth = maxWidthNum * _this.proportionX;
  let previewHeight = maxWidthNum * _this.proportionY;
  if (previewWidth / previewHeight <= 1.7) {
  previewWidth = previewWidth / 2;
  previewHeight = previewHeight / 2;
  _this.isShort = true;
  }
  // 设置最大预览容器的宽高
  $('.myCropper-preview-1').css('width', previewWidth + 'px');
  $('.myCropper-preview-1').css('height', previewHeight + 'px');
  // 设置中等预览容器的宽高
  $('.myCropper-container .myCropper-preview .myCropper-preview-2').css('width',( previewWidth / 2) + 'px');
  $('.myCropper-container .myCropper-preview .myCropper-preview-2').css('height', (previewHeight / 2) + 'px');
  // 设置最小预览容器的宽高
  $('.myCropper-container .myCropper-preview .myCropper-preview-3').css('width',( previewWidth / 4) + 'px');
  $('.myCropper-container .myCropper-preview .myCropper-preview-3').css('height', (previewHeight / 4) + 'px');
 },
 methods: {
  // 点击选择图片
  btnClick () {
  let _this = this;
  // 模拟input点击选择文件
  document.getElementById('myCropper-input').click();
  },
  // 选择之后的回调
  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();
  }
  },
  // 初始化剪切
  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) {
   }
  });
  _this.hasSelectImg = true;
  },
  // 确认
  crop_ok () {
  let _this = this, imgToken = null, imgBase64Data = null;
  // 判断是否选择图片
  if (_this.hasSelectImg == false) {
   _this.$Modal.error({
   title: '裁剪失败',
   content: '请选择图片,然后进行裁剪操作!'
   });
   return false;
  }
  // 确认按钮不可用
  _this.cropperLoading = true;
  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)
  // ajax上传
  $.ajax({
     url: _this.$nfs.uploadUrl,
     method: 'POST',
     data: formData,
     // 默认为true,设为false后直到ajax请求结束(调完回掉函数)后才会执行$.ajax(...)后面的代码
     async: false,
     // 下面三个,因为直接使用FormData作为数据,contentType会自动设置,也不需要jquery做进一步的数据处理(序列化)。
     cache: false,
     contentType: false,
   processData: false,
   type: _this.imgType,
     success: function(res) {
   let imgToken = res.data.token;
   _this.cropperLoading = false;
   // 传参
   Bus.$emit('getTarget', imgToken); 
     },
     error: function(error) {
   _this.cropperLoading = false;
   _this.$Modal.error({
    title: '系统错误',
    content: '请重新裁剪图片进行上传!'
   });
     }
    });
  },
 }
 }
</script>
<style lang="less" scoped>
 .myCropper-container {
 height: 400px;
 }
 .myCropper-container #myCropper-input {
 width: 0px;
 height: 0px;
 }
 .myCropper-container #myCropper-workspace {
 width: 500px;
 height: 400px;
 border: 1px solid #dddee1;
 float: left;
 }
 // 裁剪图片未选择图片的提示文字
 .myCropper-container #myCropper-workspace .myCropper-words{
 text-align: center;
 font-size: 18px;
 padding-top: 180px;
 }
 // 裁剪图片的预览区域
 .myCropper-container .myCropper-preview-long {
 width: 300px;
 }
 .myCropper-container .myCropper-preview-short {
 width: 200px;
 }
 .myCropper-container .myCropper-preview {
 float: left;
 height: 400px;
 margin-left: 10px;
 }
 .myCropper-container .myCropper-preview .myCropper-preview-1 {
 border-radius: 5px;
 overflow: hidden;
 border: 1px solid #dddee1;
 box-shadow: 3px 3px 3px #dddee1;
 img {
  width: 100%;
  height: 100%;
 }
 }
 .myCropper-container .myCropper-preview .myCropper-preview-2 {
 margin-top: 20px;
 border-radius: 5px;
 overflow: hidden;
 border: 1px solid #dddee1;
 box-shadow: 3px 3px 3px #dddee1;
 img {
  width: 100%;
  height: 100%;
 }
 }
 .myCropper-container .myCropper-preview .myCropper-preview-3 {
 margin-top: 20px;
 border-radius: 5px;
 overflow: hidden;
 border: 1px solid #dddee1;
 box-shadow: 3px 3px 3px #dddee1;
 img {
  width: 100%;
  height: 100%;
 }
 }
 // 按钮
 .myCropper-btn {
 float: left;
 margin-top: 20px;
 margin-right: 10px;
 }
</style>

BY-LucaLJX

github: lucaljx

总结

以上所述是小编给大家介绍的基于cropper.js封装vue实现在线图片裁剪组件功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JS判断两个时间大小的示例代码
Jan 28 Javascript
jquery制作居中遮罩层效果分享
Feb 21 Javascript
深入理解JavaScript系列(30):设计模式之外观模式详解
Mar 03 Javascript
Vuejs第十二篇之动态组件全面解析
Sep 09 Javascript
JS制作适用于手机和电脑的通知信息效果
Oct 28 Javascript
js中的reduce()函数讲解
Jan 18 Javascript
深入浅出 Vue 系列 -- 数据劫持实现原理
Apr 23 Javascript
微信小程序数据统计和错误统计的实现方法
Jun 26 Javascript
浅谈webpack构建工具配置和常用插件总结
May 11 Javascript
如何利用JS将手机号中间四位变成*号
Sep 29 Javascript
vue-router定义元信息meta操作
Dec 07 Vue.js
vue打包时去掉所有的console.log
Apr 10 Vue.js
详解vue-cli 快速搭建单页应用之遇到的问题及解决办法
Mar 01 #Javascript
React Native 图片查看组件的方法
Mar 01 #Javascript
vue-cli结合Element-ui基于cropper.js封装vue实现图片裁剪组件功能
Mar 01 #Javascript
vue.js 实现图片本地预览 裁剪 压缩 上传功能
Mar 01 #Javascript
vue中使用cropperjs的方法
Mar 01 #Javascript
cropper js基于vue的图片裁剪上传功能的实现代码
Mar 01 #Javascript
Vuex中mutations与actions的区别详解
Mar 01 #Javascript
You might like
PHP实现文件安全下载
2006/10/09 PHP
PHP使用range协议实现输出文件断点续传代码实例
2014/07/04 PHP
php通过隐藏表单控件获取到前两个页面的url
2014/09/09 PHP
magento后台无法登录解决办法的两种方法
2016/12/09 PHP
在Laravel 的 Blade 模版中实现定义变量
2019/10/14 PHP
一个小型js框架myJSFrame附API使用帮助
2008/06/28 Javascript
JavaScript与DropDownList 区别分析
2010/01/01 Javascript
JavaScript获取客户端计算机硬件及系统等信息的方法
2014/01/02 Javascript
javascript常用函数归纳整理
2014/10/31 Javascript
jquery中取消和绑定hover事件的实现代码
2016/06/02 Javascript
AngularJS入门教程中SQL实例详解
2016/07/27 Javascript
浅谈Web页面向后台提交数据的方式和选择
2016/09/23 Javascript
jQuery插件ajaxFileUpload使用实例解析
2016/10/19 Javascript
JavaScript中for循环的几种写法与效率总结
2017/02/03 Javascript
JS中SetTimeout和SetInterval使用初探
2017/03/23 Javascript
详解Angular2组件之间如何通信
2017/06/22 Javascript
Mobile Web开发基础之四--处理手机设备的横竖屏问题
2017/08/11 Javascript
react-native组件中NavigatorIOS和ListView结合使用的方法
2017/09/30 Javascript
关于Layui Table隐藏列问题
2019/09/16 Javascript
详解在Python和IPython中使用Docker
2015/04/28 Python
Mac中升级Python2.7到Python3.5步骤详解
2017/04/27 Python
详解python实现线程安全的单例模式
2018/03/05 Python
Python threading的使用方法解析
2019/08/28 Python
关于pycharm中pip版本10.0无法使用的解决办法
2019/10/10 Python
python多继承(钻石继承)问题和解决方法简单示例
2019/10/21 Python
Python 字符串处理特殊空格\xc2\xa0\t\n Non-breaking space
2020/02/23 Python
ALDI奥乐齐官方海外旗舰店:德国百年超市
2017/12/27 全球购物
西班牙美妆电商:Perfume’s Club(有中文站)
2018/08/08 全球购物
Booking.com德国:预订最好的酒店和住宿
2020/02/16 全球购物
软件研发工程师岗位职责
2014/09/30 职场文书
毕业设计指导教师评语
2014/12/30 职场文书
个人股份转让协议书范本
2015/01/28 职场文书
房租涨价通知
2015/04/23 职场文书
小学生家长意见
2015/06/03 职场文书
Python 循环读取数据内存不足的解决方案
2021/05/25 Python
Python+pyaudio实现音频控制示例详解
2022/07/23 Python