基于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 相关文章推荐
用 javascript 实现的点击复制代码
Mar 24 Javascript
js浮动图片的动态效果
Jul 10 Javascript
javascript计算用户打开网页的停留时间
Jan 09 Javascript
原生js获取宽高与jquery获取宽高的方法关系对比
Apr 04 Javascript
JavaScript模拟实现继承的方法
Mar 30 Javascript
输入框点击时边框变色效果的实现方法
Dec 26 Javascript
Vue.js实现移动端短信验证码功能
Mar 29 Javascript
微信小程序tab切换可滑动切换导航栏跟随滚动实现代码
Sep 04 Javascript
layui-table对返回的数据进行转变显示的实例
Sep 04 Javascript
详解vue 中 scoped 样式作用域的规则
Sep 14 Javascript
vue自定义树状结构图的实现方法
Oct 18 Javascript
JS前端使用Canvas快速实现手势解锁特效
Sep 23 Javascript
详解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
php5中date()得出的时间为什么不是当前时间的解决方法
2008/06/30 PHP
smarty模板的使用方法实例分析
2019/09/18 PHP
在chrome中window.onload事件的一些问题
2010/03/01 Javascript
超级有用的13个基于jQuery的内容滚动插件和教程
2011/07/31 Javascript
jQuery 删除或是清空某个HTML元素示例
2014/08/04 Javascript
JavaScript中的style.cssText使用教程
2014/11/06 Javascript
PHP 数组current和next用法分享
2015/03/05 Javascript
js实现延迟加载的方法
2015/06/24 Javascript
基于JavaScript制作霓虹灯文字 代码 特效
2015/09/01 Javascript
JS学习之表格的排序简单实例
2016/05/16 Javascript
JS两种类型的表单提交方法实例分析
2016/11/28 Javascript
详解Windows下安装Nodejs步骤
2017/05/18 NodeJs
小程序自定义组件实现城市选择功能
2018/07/18 Javascript
React 无状态组件(Stateless Component) 与高阶组件
2018/08/14 Javascript
layui 中select下拉change事件失效的解决方法
2019/09/20 Javascript
VUE注册全局组件和局部组件过程解析
2019/10/10 Javascript
原生js实现下拉选项卡
2019/11/27 Javascript
TypeScript之调用栈的实现
2019/12/31 Javascript
js Math数学简单使用操作示例
2020/03/13 Javascript
js实现盒子滚动动画效果
2020/08/09 Javascript
[51:34]Ti4主赛事胜者组 DK vs EG 2
2014/07/19 DOTA
[03:07]完美世界DOTA2联赛PWL DAY10 决赛集锦
2020/11/11 DOTA
Python中函数的参数传递与可变长参数介绍
2015/06/30 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
在Python中os.fork()产生子进程的例子
2019/08/08 Python
Python中正反斜杠(‘/’和‘\’)的意义与用法
2019/08/12 Python
python内置函数sorted()用法深入分析
2019/10/08 Python
使用jupyter notebook运行python和R的步骤
2020/08/13 Python
Pycharm配置autopep8实现流程解析
2020/11/28 Python
Python 的 f-string 可以连接字符串与数字的原因解析
2021/02/20 Python
利用promise及参数解构封装ajax请求的方法
2021/03/24 Javascript
小学开学寄语
2014/01/19 职场文书
医学求职信
2014/05/28 职场文书
2014年办公室主任工作总结
2014/11/12 职场文书
先进党支部申报材料
2014/12/24 职场文书
mysql死锁和分库分表问题详解
2021/04/16 MySQL