基于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 相关文章推荐
解决FLASH需要点击激活的代码
Dec 20 Javascript
JavaScript使用ActiveXObject访问Access和SQL Server数据库
Apr 02 Javascript
对JavaScript的全文搜索实现相关度评分的功能的方法
Jun 24 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
Oct 22 Javascript
实例讲解jquery与json的结合
Jan 07 Javascript
Vue.js 表单校验插件
Aug 14 Javascript
Bootstrap框架结合jQuery仿百度换肤功能实例解析
Sep 17 Javascript
jQuery获取table下某一行某一列的值实现代码
Apr 07 jQuery
详解vue2路由vue-router配置(懒加载)
Apr 08 Javascript
Vuex利用state保存新闻数据实例
Jun 28 Javascript
js实现坦克大战游戏
Feb 24 Javascript
基于javascript的无缝滚动动画实现2
Aug 07 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
dede全站URL静态化改造[070414更正]
2007/04/17 PHP
php函数式编程简单示例
2019/08/08 PHP
PHP类的自动加载与命名空间用法实例分析
2020/06/05 PHP
jquery随意添加移除html的实现代码
2011/06/21 Javascript
js AppendChild与insertBefore用法详细对比
2013/12/16 Javascript
jquery 实现input输入什么div图层显示什么
2014/06/15 Javascript
jQuery ajax调用WCF服务实例
2014/07/16 Javascript
JavaScript中的splice()方法使用详解
2015/06/09 Javascript
javascript自动切换焦点控制效果完整实例
2016/02/02 Javascript
mvc 、bootstrap 结合分布式图简单实现分页
2016/10/10 Javascript
jQuery电话号码验证实例
2017/01/05 Javascript
jQuery插件select2利用ajax高效查询大数据列表(可搜索、可分页)
2017/05/19 jQuery
javascript ES6 新增了let命令使用介绍
2017/07/07 Javascript
vue.js中v-on:textInput无法执行事件问题的解决过程
2017/07/12 Javascript
nodejs判断文件、文件夹是否存在及删除的方法
2017/11/10 NodeJs
微信小程序封装的HTTP请求示例【附升级版】
2019/05/11 Javascript
Vue组件之高德地图地址选择功能的实例代码
2019/06/21 Javascript
Vue 2.0双向绑定原理的实现方法
2019/10/23 Javascript
vue-resource 拦截器interceptors使用详解
2021/01/18 Vue.js
跨平台python异步回调机制实现和使用方法
2013/11/26 Python
零基础写python爬虫之打包生成exe文件
2014/11/06 Python
总结Python编程中三条常用的技巧
2015/05/11 Python
解决python文件字符串转列表时遇到空行的问题
2017/07/09 Python
pandas DataFrame 根据多列的值做判断,生成新的列值实例
2018/05/18 Python
通过python实现随机交换礼物程序详解
2019/07/10 Python
基于HTML5 audio元素播放声音jQuery小插件
2011/05/11 HTML / CSS
HTML5响应式(自适应)网页设计的实现
2017/11/17 HTML / CSS
个人素质的自我评价分享
2013/12/16 职场文书
三年级班级文化建设方案
2014/05/04 职场文书
2014年收银工作总结
2014/11/13 职场文书
2014年志愿者工作总结
2014/11/20 职场文书
导游词之无锡东林书院
2019/12/11 职场文书
Pycharm连接远程服务器并远程调试的全过程
2021/06/24 Python
使用 Apache Superset 可视化 ClickHouse 数据的两种方法
2021/07/07 Servers
Android开发之WECHAT微信小程序路由跳转的两种形式
2022/04/12 Java/Android
Python matplotlib绘制雷达图
2022/04/13 Python