美文网首页
图片剪切插件之cropper.js

图片剪切插件之cropper.js

作者: Biao_349d | 来源:发表于2019-03-23 17:58 被阅读0次

    文档地址

    github: https://github.com/fengyuanchen/cropperjs
    csdn: https://blog.csdn.net/weixin_38023551/article/details/78792400

    使用方法:

    1. 新建标签
    <img ref="cropperImg">
    
    1. 初始化参数
            options: {
              viewMode: 2,  // 0:无限制; 1:将裁剪框限制为不超过画布的大小, 2:限制最小画布尺寸以适应容器,如果画布和容器的比例不同,则最小画布将在其中一个维度中被额外的空格包围。, 3:限制最小画布尺寸以填充容器。如果画布和容器的比例不同,则容器将无法将整个画布适合其中一个尺寸。
              dragMode: 'move', // 'crop':创建一个新的裁剪框    'move':移动画布  'none':do nothing
              aspectRatio: 16/9,  // 设置裁剪框的宽高比。默认情况下,裁剪框是空闲比率。
              data: {}, // 如果您已经存储了以前的裁剪数据,将在构建时自动传递给setData方法。
              preview: '', //添加额外的元素(容器)进行预览。
              autoCropArea: 1,   //介于0和1之间的数字。定义自动裁剪区域大小(百分比), 1: 完全按照最大宽度后最大高度设置剪切框
              checkCrossOrigin: true,
              movable: true,  //启用移动图像。
              rotatable: true,  //启用旋转图像。
              scalable: true,  //启用缩放图像。
              zoomable: true,  //启用缩放图像。
              zoomOnTouch: true,  //启用通过拖动触摸缩放图像。
              zoomOnWheel: true,  //启用通过滚动鼠标放大图像。。
              cropBoxMovable: true,  // 启用通过拖动来移动裁剪框。
              cropBoxResizable: true,  // 启用通过拖动调整裁剪框的大小。。
              toggleDragModeOnDblclick: false,  //在裁剪器上点击两次时,启用“切割”和“移动”之间切换拖动模式。
              minContainerWidth: 200,  //容器的最小宽度。。
              minContainerHeight: 100,  //容器的最小高度。。。
              ready: function () {
                this.cropper && this.cropper.crop();
              // 可以根据用户参入的比例, 进行更改剪切框比例
                if (this.cropObj) {
                  this.cropper &&  this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
                }
              },
              crop: function (e) {
              }
            },
    
    
    1. 初始化剪切区域
    • 新建剪切区域, 新建完毕,
    • 替换url(可根据用户传过来的url进行替换),
    • 替换完毕后, 重置剪切区域
          init() {
            // this.cropper && this.cropper.destroy()
            this.cropper = new Cropper(this.$refs.cropperImg, this.options);
            this.replace(this.src)
            this.cropper &&  this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
          },
    
    1. 完整代码
    <template>
      <div class="b-cropper">
          <img ref="cropperImg">
      </div>
    </template>
    <script>
      import '@/components/cropperjs/dist/cropper.min.css'
      const Cropper_de = require('@/components/cropperjs/dist/cropper.min.js')
      const Cropper = Cropper_de.Cropper
      export default {
        data() {
          var self = this;
          return {
            cropper: null,
            options: {
              viewMode: 2,  // 0:无限制; 1:将裁剪框限制为不超过画布的大小, 2:限制最小画布尺寸以适应容器,如果画布和容器的比例不同,则最小画布将在其中一个维度中被额外的空格包围。, 3:限制最小画布尺寸以填充容器。如果画布和容器的比例不同,则容器将无法将整个画布适合其中一个尺寸。
              dragMode: 'move', // 'crop':创建一个新的裁剪框    'move':移动画布  'none':do nothing
              aspectRatio: 16/9,  // 设置裁剪框的宽高比。默认情况下,裁剪框是空闲比率。
              data: {}, // 如果您已经存储了以前的裁剪数据,将在构建时自动传递给setData方法。
              preview: '', //添加额外的元素(容器)进行预览。
              autoCropArea: 1,   //介于0和1之间的数字。定义自动裁剪区域大小(百分比)
              checkCrossOrigin: true,
              movable: true,  //启用移动图像。
              rotatable: true,  //启用旋转图像。
              scalable: true,  //启用缩放图像。
              zoomable: true,  //启用缩放图像。
              zoomOnTouch: true,  //启用通过拖动触摸缩放图像。
              zoomOnWheel: true,  //启用通过滚动鼠标放大图像。。
              cropBoxMovable: true,  // 启用通过拖动来移动裁剪框。
              cropBoxResizable: true,  // 启用通过拖动调整裁剪框的大小。。
              toggleDragModeOnDblclick: false,  //在裁剪器上点击两次时,启用“切割”和“移动”之间切换拖动模式。
              minContainerWidth: 200,  //容器的最小宽度。。
              minContainerHeight: 100,  //容器的最小高度。。。
              ready: function () {
                this.cropper && this.cropper.crop();
                if (this.cropObj) {
                  this.cropper &&  this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
                }
              },
              crop: function (e) {
              }
            },
            nativeFile: null,
          }
        },
        /*
         reset():将图像和裁剪框重置为初始状态。
          crop(): 手动显示裁剪框。
          clear():清除裁剪框。
          enable():启用(解冻)裁剪器。
          disable():禁用(冻结)裁剪器。
          destroy():销毁裁剪器并从图像中删除实例。
          move(offsetX[, offsetY]):用相对偏移移动画布(图像包装器)。
    
        * */
        props: {
          src: {
            type: String,
            default: ""
          },
          cropObj: {
            type: Object,
            default: ()=>{
              return {
                left: 0,
                top: 0,
                width: 20,
                height: 20.
              }
            }
          },
    
        },
        watch: {
          src (val) {
            this.replace(val)
          },
         cropObj () {
              this.cropper &&  this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
          }
        },
        mounted () {
          this.$nextTick(() => {
            setTimeout(() => {
              this.init();
            })
          })
        },
        methods: {
          init() {
            this.cropper = new Cropper(this.$refs.cropperImg, this.options);
            this.replace(this.src)
            this.cropper &&  this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
          },
          replace (url, onlyColorChanged) {
            this.cropper.reset()
            if (url && url.indexOf("http") == 0) {
              url = '//' + url.split("//")[1] + '?v=3'
            }
            if (onlyColorChanged) {
              this.cropper && this.cropper.replace(url, onlyColorChanged)
            } else {
              this.cropper && this.cropper.replace(url)
            }
          },
          getNativeCanvas(url) {
            return new Promise(resolve => {
              var canvas = document.createElement("canvas");
              var ctx = canvas.getContext('2d');
              var img = new Image();
              img.crossOrigin = "Anonymous";//解决跨域图片问题,就是上面提及的
              img.onload = function(){
                canvas.width = img.width
                canvas.height = img.height
                ctx.drawImage(img, 0, 0, img.width, img.height);
                resolve(canvas)
              }
              img.src = "//" + url.split("//")[1];
            })
          },
          // 获取转换工具;
          utils(){
            let blobToDataURL = function(blob, callback) {
              return new Promise(resolve => {
                var a = new FileReader();
                a.onload = function (e) {
                  callback && callback(e.target.result);
                  resolve(e.target.result)
                }
                a.readAsDataURL(blob);
              })
    
            }
            let dataURLtoFile = function(dataurl, filename) {//将base64转换为文件  
    
              var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
              while(n--){
                u8arr[n] = bstr.charCodeAt(n);
              }
              filename = filename ? filename : Math.ceil(Math.random())*1000 * 1000 + ".jpg"
              return new File([u8arr], filename, {type:mime});
            }
            let dataURLToBlob = function(dataurl){
              var arr = dataurl.split(',');
              var mime = arr[0].match(/:(.*?);/)[1];
              var bstr = atob(arr[1]);
              var n = bstr.length;
              var u8arr = new Uint8Array(n);
              while(n--){
                u8arr[n] = bstr.charCodeAt(n);
              }
              return new Blob([u8arr], {type:mime});
            }
            let getObjectURL = function(file) {
              var url = null;
              if (window.createObjectURL !== undefined) { // basic
                url = window.createObjectURL(file);
              } else if (window.URL !== undefined) { // mozilla(firefox)
                url = window.URL.createObjectURL(file);
              } else if (window.webkitURL !== undefined) { // webkit or chrome
                url = window.webkitURL.createObjectURL(file);
              }
              return url;
            }
            let urlGetBolb = function (url) {
              return new Promise((resolve => {
                url = url && '//' + url.split("//")[1] + '?v=' + (Math.random() * 10)
                var img = new Image();
                var _this = this;
                // img.setAttribute("crossOrigin",'anonymous')    // 添加改代码, 防止跨域
                img.onload = function () {
                  var xhr = new XMLHttpRequest();
                  xhr.open("get", url, true);
                  xhr.responseType = "blob";
                  xhr.onload = function() {
                    if (this.status == 200) {
                      var blob = this.response;
                      resolve(blob)
                    }
                  }
                  xhr.send()
                }
                img.onerror = () => {
    
                };
                // img.setAttribute("crossOrigin",'anonymous')    // 添加改代码, 防止跨域
                img.src =url
    
              }))
    
            }
            return {
              blobToDataURL,
              dataURLtoFile,
              dataURLToBlob,
              getObjectURL,
              urlGetBolb
            }
          },
            getBrowserInfo(){
              var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
              var isOpera = userAgent.indexOf("Opera") > -1;
              //判断是否Opera浏览器
              if (isOpera) {
                  return "Opera"
              };
              //判断是否Firefox浏览器
              if (userAgent.indexOf("Firefox") > -1) {
                  return "FF";
              }
              //判断是否chorme浏览器
              if (userAgent.indexOf("Chrome") > -1){
              return "Chrome";
              }
              //判断是否Safari浏览器
              if (userAgent.indexOf("Safari") > -1) {
                  return "Safari";
              }
              //判断是否IE浏览器
              if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera) {
                  return "IE";
              }
              //判断是否Edge浏览器
              if (userAgent.indexOf("Trident") > -1) {
                  return "Edge";
              };
           },
          getImageData () {
               return this.cropper.getImageData()
          },
          getData () {
           return this.cropper.getData(true)
          }
        },
        beforeDestroy () {
          this.cropper.destroy()
        },
      }
    </script>
    <style lang="less">
      .b-cropper{
        width: 100%;
        height: 100%;
        display: block;
        background: #fff;
        .layer-header{
          display: flex;
          padding: 10px 20px;
          >div{
            flex: 1;
          }
          >div:first-child{
            text-align: left;
          }
          >div:last-child{
            text-align: right;
          }
          .cancel, .confirm{
            font-size: 32px;
            color: #555;
            padding: 0 20px;
          }
          .confirm{
            color: #BE001E;
          }
        }
        .file{
          display: none;
          width: 0;
          height: 0;
          overflow: hidden;
        }
      }
    </style>
    
    
    1. 功能分析
    • watch
      这里面有两点
         src (val) {
            this.replace(val)
          },
         cropObj () {
              this.cropper &&  this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
        }
    

    分别是当src传入的时候, 更改src, 当 cropObj 传入的时候, 更改剪切区域

    • utils
      这里面主要包含了, bold base64, bolb_url, file转化的工具

    • getBrowserInfo
      获取浏览器信息

    • getImageData
      获取原图信息

    • getData
      获取剪切区域图片信息

    • beforeDestroy
      当关闭这个组件, 将组建销毁。

    • replace
      里面有几个重要的点

          replace (url, onlyColorChanged) {
            this.cropper.reset()
            if (url && url.indexOf("http") == 0) {
              url = '//' + url.split("//")[1] + '?v=3'
            }
            if (onlyColorChanged) {
              this.cropper && this.cropper.replace(url, onlyColorChanged)
            } else {
              this.cropper && this.cropper.replace(url)
            }
          },
    1.  this.cropper.reset() 重置
    2. url = '//' + url.split("//")[1] + '?v=3'  有时候我们是请求https的, 但是当前域却在http环境, 因此去掉http|https, 使用//反而更好, 这样能防止跨域。
    3. this.cropper.replace(url) 替换图片;
    

    相关文章

      网友评论

          本文标题:图片剪切插件之cropper.js

          本文链接:https://www.haomeiwen.com/subject/fegsvqtx.html