基于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 相关文章推荐
根据分辨率不同,调用不同的css文件
Aug 25 Javascript
用jQuery实现检测浏览器及版本的脚本代码
Jan 22 Javascript
通过DOM脚本去设置样式信息
Sep 19 Javascript
基于jquery的多彩百分比 动态进度条 投票效果显示效果实现代码
Aug 28 Javascript
javascript实现回车键提交表单方法总结
Jan 10 Javascript
JS延时提示框实现方法详解
Nov 26 Javascript
原生js实现自由拖拽弹窗代码demo
Jun 29 Javascript
原生JS实现图片轮播切换效果
Dec 15 Javascript
JavaScript 网页中实现一个计算当年还剩多少时间的倒数计时程序
Jan 25 Javascript
JS+canvas实现的五子棋游戏【人机大战版】
Jul 19 Javascript
随机生成10个不重复的0-100的数字(实例讲解)
Aug 16 Javascript
javascript canvas封装动态时钟
Sep 30 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
php visitFile()遍历指定文件夹函数
2010/08/21 PHP
从性能方面考虑PHP下载远程文件的3种方法
2015/12/29 PHP
PHP使用token防止表单重复提交的方法
2016/04/07 PHP
2017年最新PHP经典面试题目汇总(上篇)
2017/03/17 PHP
php实现分页功能的详细实例方法
2019/09/29 PHP
jQuery Study Notes学习笔记 (二)
2010/08/04 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
2013/11/19 Javascript
node.js中的http.response.getHeader方法使用说明
2014/12/14 Javascript
jQuery中:eq()选择器用法实例
2014/12/29 Javascript
JavaScript实现相册弹窗功能(zepto.js)
2016/06/21 Javascript
JS实现匀加速与匀减速运动的方法示例
2017/09/04 Javascript
详解使用Typescript开发node.js项目(简单的环境配置)
2017/10/09 Javascript
vue组件实现进度条效果
2018/06/06 Javascript
JavaScript深入V8引擎以及编写优化代码的5个技巧
2019/06/24 Javascript
解决layui弹框失效的问题
2019/09/09 Javascript
[03:00]DOTA2-DPC中国联赛1月18日Recap集锦
2021/03/11 DOTA
巧用Python装饰器 免去调用父类构造函数的麻烦
2012/05/18 Python
使用python实现接口的方法
2017/07/07 Python
Python装饰器原理与用法分析
2018/04/30 Python
python3使用flask编写注册post接口的方法
2018/12/28 Python
Python中*args和**kwargs的区别详解
2019/09/17 Python
python 实现将小图片放到另一个较大的白色或黑色背景图片中
2019/12/12 Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
2020/03/20 Python
pandas dataframe 中的explode函数用法详解
2020/05/18 Python
浅谈numpy中函数resize与reshape,ravel与flatten的区别
2020/06/18 Python
详解python metaclass(元类)
2020/08/13 Python
html5的新玩法——语音搜索
2013/01/03 HTML / CSS
美国知名的家庭连锁百货商店:Boscov’s
2017/07/27 全球购物
椰子猫砂:CatSpot
2018/08/27 全球购物
给老婆的搞笑检讨书
2014/01/12 职场文书
绿化先进工作者事迹材料
2014/01/30 职场文书
指导教师评语
2014/04/26 职场文书
党委领导班子整改方案
2014/09/30 职场文书
2016年圣诞节寄语(一句话)
2015/12/07 职场文书
导游词之西湖雷峰塔
2019/09/18 职场文书
Python中Permission denied的解决方案
2021/04/02 Python