【愚公系列】2022年09月 微信小程序-图片裁剪功能实现

举报
愚公搬代码 发表于 2022/09/30 22:28:19 2022/09/30
【摘要】 前言1、图片裁剪相关api属性类型缺省值取值描述必填imgSrcString无无限制图片地址(如果是网络图片需配置安全域名)否disable_rotateBooleanfalsetrue/false禁止用户旋转(为false时建议同时设置limit_move为false)否limit_moveBooleanfalsetrue/false限制图片移动范围(裁剪框始终在图片内)(为true时建...

前言

1、图片裁剪相关api

属性 类型 缺省值 取值 描述 必填
imgSrc String 无限制 图片地址(如果是网络图片需配置安全域名)
disable_rotate Boolean false true/false 禁止用户旋转(为false时建议同时设置limit_move为false)
limit_move Boolean false true/false 限制图片移动范围(裁剪框始终在图片内)(为true时建议同时设置disable_rotate为true)
width Number 200 超过屏幕宽度自动转为屏幕宽度 裁剪框宽度
height Number 200 超过屏幕高度自动转为屏幕高度 裁剪框高度
max_width Number 300 裁剪框最大宽度 裁剪框最大宽度
max_height Number 300 裁剪框最大高度 裁剪框最大高度
min_width Number 100 裁剪框最小宽度 裁剪框最小宽度
min_height Number 100 裁剪框最小高度 裁剪框最小高度
disable_width Boolean false true/false 锁定裁剪框宽度
disable_height Boolean false true/false 锁定裁剪框高度
disable_ratio Boolean false true/false 锁定裁剪框比例
export_scale Number 3 无限制 输出图片的比例(相对于裁剪框尺寸)
quality Number 1 0-1 生成的图片质量
cut_top Number 居中 始终在屏幕内 裁剪框上边距
cut_left Number 居中 始终在屏幕内 裁剪框左边距
img_width Number 宽高都不设置,最小边填满裁剪框 支持%(不加单位为px)(只设置宽度,高度自适应) 图片宽度
img_height Number 宽高都不设置,最小边填满裁剪框 支持%(不加单位为px)(只设置高度,宽度自适应) 图片高度
scale Number 1 无限制 图片的缩放比
angle Number 0 (limit_move=true时angle=n*90) 图片的旋转角度
min_scale Number 0.5 无限制 图片的最小缩放比
max_scale Number 2 无限制 图片的最大缩放比
bindload Function null 函数名称 cropper初始化完成
bindimageload Function null 函数名称 图片加载完成,返回值Object{width,height,path,type等}
bindtapcut Function null 函数名称 点击中间裁剪框,返回值Object{src,width,height}

2、函数说明

函数名 参数 返回值 描述 参数必填
upload 调起wx上传图片接口并开始剪裁
pushImg src 放入图片开始裁剪
getImg Function(回调函数) Object{url,width,height} 裁剪并获取图片(图片尺寸 = 图片宽高 * export_scale)
setCutXY X、Y 设置裁剪框位置
setCutSize width、height 设置裁剪框大小
setCutCenter 设置裁剪框居中
setScale scale 设置图片缩放比例(不受min_scale、max_scale影响)
setAngle deg 设置图片旋转角度(带过渡效果)
setTransform {x,y,angle,scale,cutX,cutY} 图片在原有基础上的变化(scale受min_scale、max_scale影响) 根据需要传参
imgReset 重置图片的角度、缩放、位置(可以在onloadImage回调里使用)

一、相关代码封装

1.组件的封装

1.1 wxml

  <view class='image-cropper' catchtouchmove='_preventTouchMove'>
    <view class='main' bindtouchend="_cutTouchEnd" bindtouchstart="_cutTouchStart" bindtouchmove="_cutTouchMove" bindtap="_click">
      <view class='content'>
        <view class='content_top bg_gray {{_flag_bright?"":"bg_black"}}' style="height:{{cut_top}}px;transition-property:{{_cut_animation?'':'background'}}"></view>
        <view class='content_middle' style="height:{{height}}px;">
          <view class='content_middle_left bg_gray {{_flag_bright?"":"bg_black"}}' style="width:{{cut_left}}px;transition-property:{{_cut_animation?'':'background'}}"></view>
          <view class='content_middle_middle' style="width:{{width}}px;height:{{height}}px;transition-duration: .3s;transition-property:{{_cut_animation?'':'background'}};">
            <view class="border border-top-left"></view>
            <view class="border border-top-right"></view>
            <view class="border border-right-top"></view>
            <view class="border border-right-bottom"></view>
            <view class="border border-bottom-right"></view>
            <view class="border border-bottom-left"></view>
            <view class="border border-left-bottom"></view>
            <view class="border border-left-top"></view>
          </view>
          <view class='content_middle_right bg_gray {{_flag_bright?"":"bg_black"}}' style="transition-property:{{_cut_animation?'':'background'}}"></view>
        </view>
        <view class='content_bottom bg_gray {{_flag_bright?"":"bg_black"}}' style="transition-property:{{_cut_animation?'':'background'}}"></view>
      </view>
      <image bindload="imageLoad" bindtouchstart="_start" bindtouchmove="_move" bindtouchend="_end" style="width:{{img_width ? img_width + 'px' : 'auto'}};height:{{img_height ? img_height + 'px' : 'auto'}};transform:translate3d({{_img_left-img_width/2}}px,{{_img_top-img_height/2}}px,0) scale({{scale}}) rotate({{angle}}deg);transition-duration:{{_cut_animation?.4:0}}s;" class='img' src='{{imgSrc}}'></image>
    </view>
    <canvas canvas-id='image-cropper' disable-scroll="true" style="width:{{_canvas_width * export_scale}}px;height:{{_canvas_height * export_scale}}px;left:{{canvas_left}}px;top:{{canvas_top}}px" class='image-cropper-canvas'></canvas>
  </view>

1.2 js

Component({
  properties: {
    /**     
     * 图片路径
     */
    'imgSrc': {
      type: String
    },
    /**
     * 裁剪框高度
     */
    'height': {
      type: Number,
      value: 200
    },
    /**
     * 裁剪框宽度
     */
    'width': {
      type: Number,
      value: 200
    },
    /**
     * 裁剪框最小尺寸
     */
    'min_width': {
      type: Number,
      value: 100
    },
    'min_height': {
      type: Number,
      value: 100
    },
    /**
     * 裁剪框最大尺寸
     */
    'max_width': {
      type: Number,
      value: 300
    },
    'max_height': {
      type: Number,
      value: 300
    },
    /**
     * 裁剪框禁止拖动
     */
    'disable_width': {
      type: Boolean,
      value: false
    },
    'disable_height': {
      type: Boolean,
      value: false
    },
    /**
     * 锁定裁剪框比例
     */
    'disable_ratio':{
      type: Boolean,
      value: false
    },
    /**
     * 生成的图片尺寸相对剪裁框的比例
     */
    'export_scale': {
      type: Number,
      value: 3
    },
    /**
     * 生成的图片质量0-1
     */
    'quality': {
      type: Number,
      value: 1
    },
    'cut_top': {
      type: Number,
      value: null
    },
    'cut_left': {
      type: Number,
      value: null
    },
    /**
     * canvas上边距(不设置默认不显示)
     */
    'canvas_top': {
      type: Number,
      value: null
    },
    /**
     * canvas左边距(不设置默认不显示)
     */
    'canvas_left': {
      type: Number,
      value: null
    },
    /**
     * 图片宽度
     */
    'img_width': {
      type: null,
      value: null
    },
    /**
     * 图片高度
     */
    'img_height': {
      type: null,
      value: null
    },
    /**
     * 图片缩放比
     */
    'scale': {
      type: Number,
      value: 1
    },
    /**
     * 图片旋转角度
     */
    'angle': {
      type: Number,
      value: 0
    },
    /**
     * 最小缩放比
     */
    'min_scale': {
      type: Number,
      value: 0.5
    },
    /**
     * 最大缩放比
     */
    'max_scale': {
      type: Number,
      value: 2
    },
    /**
     * 是否禁用旋转
     */
    'disable_rotate': {
      type: Boolean,
      value: false
    },
    /**
     * 是否限制移动范围(剪裁框只能在图片内)
     */
    'limit_move':{
      type: Boolean,
      value: false
    }
  },
  data: {
    el: 'image-cropper', //暂时无用
    info: wx.getSystemInfoSync(),
    MOVE_THROTTLE:null,//触摸移动节流settimeout
    MOVE_THROTTLE_FLAG: true,//节流标识
    INIT_IMGWIDTH: 0, //图片设置尺寸,此值不变(记录最初设定的尺寸)
    INIT_IMGHEIGHT: 0, //图片设置尺寸,此值不变(记录最初设定的尺寸)
    TIME_BG: null,//背景变暗延时函数
    TIME_CUT_CENTER:null,
    _touch_img_relative: [{
      x: 0,
      y: 0
    }], //鼠标和图片中心的相对位置
    _flag_cut_touch:false,//是否是拖动裁剪框
    _hypotenuse_length: 0, //双指触摸时斜边长度
    _flag_img_endtouch: false, //是否结束触摸
    _flag_bright: true, //背景是否亮
    _canvas_overflow:true,//canvas缩略图是否在屏幕外面
    _canvas_width:200,
    _canvas_height:200,
    origin_x: 0.5, //图片旋转中心
    origin_y: 0.5, //图片旋转中心
    _cut_animation: false,//是否开启图片和裁剪框过渡
    _img_top: wx.getSystemInfoSync().windowHeight / 2, //图片上边距
    _img_left: wx.getSystemInfoSync().windowWidth / 2, //图片左边距
    watch: {
      //监听截取框宽高变化
      width(value, that) {
        if (value < that.data.min_width){
          that.setData({
            width: that.data.min_width
          });
        }
        that._computeCutSize();
      },
      height(value, that) {
        if (value < that.data.min_height) {
          that.setData({
            height: that.data.min_height
          });
        }
        that._computeCutSize();
      },
      angle(value, that){
        //停止居中裁剪框,继续修改图片位置
        that._moveStop();
        if(that.data.limit_move){
          if (that.data.angle % 90) {
            that.setData({
              angle: Math.round(that.data.angle / 90) * 90
            });
            return;
          }
        }
      },
      _cut_animation(value, that){
        //开启过渡300毫秒之后自动关闭
        clearTimeout(that.data._cut_animation_time);
        if (value){
          that.data._cut_animation_time = setTimeout(()=>{
            that.setData({
              _cut_animation:false
            });
          },300)
        }
      },
      limit_move(value, that){
        if (value) {
          if (that.data.angle%90){
            that.setData({
              angle: Math.round(that.data.angle / 90)*90
            });
          }
          that._imgMarginDetectionScale();
          !that.data._canvas_overflow && that._draw();
        }
      },
      canvas_top(value, that){
        that._canvasDetectionPosition();
      },
      canvas_left(value, that){
        that._canvasDetectionPosition();
      },
      imgSrc(value, that){
        that.pushImg();
      },
      cut_top(value, that) {
        that._cutDetectionPosition();
        if (that.data.limit_move) {
          !that.data._canvas_overflow && that._draw();
        }
      },
      cut_left(value, that) {
        that._cutDetectionPosition();
        if (that.data.limit_move) {
          !that.data._canvas_overflow && that._draw();
        }
      }
    }
  },
  attached() {
    this.data.info = wx.getSystemInfoSync();
    //启用数据监听
    this._watcher();
    this.data.INIT_IMGWIDTH = this.data.img_width;
    this.data.INIT_IMGHEIGHT = this.data.img_height;
    this.setData({
      _canvas_height: this.data.height,
      _canvas_width: this.data.width,
    });
    this._initCanvas();
    this.data.imgSrc && (this.data.imgSrc = this.data.imgSrc);
    //根据开发者设置的图片目标尺寸计算实际尺寸
    this._initImageSize();
    //设置裁剪框大小>设置图片尺寸>绘制canvas
    this._computeCutSize();
    //检查裁剪框是否在范围内
    this._cutDetectionPosition();
    //检查canvas是否在范围内
    this._canvasDetectionPosition();
    //初始化完成
    this.triggerEvent('load', {
      cropper: this
    });
  },
  methods: {
    /**
     * 上传图片
     */
    upload() {
      let that = this;
      wx.chooseImage({
        count: 1,
        sizeType: ['original', 'compressed'],
        sourceType: ['album', 'camera'],
        success(res) {
          const tempFilePaths = res.tempFilePaths[0];
          that.pushImg(tempFilePaths);
          wx.showLoading({
            title: '加载中...'
          })
        }
      })
    },
    /**
     * 检测剪裁框位置是否在允许的范围内(屏幕内)
     */
    _cutDetectionPosition(){
      let _cutDetectionPositionTop = () => {
        //检测上边距是否在范围内
        if (this.data.cut_top < 0) {
          this.setData({
            cut_top: 0
          });
        }
        if (this.data.cut_top > this.data.info.windowHeight - this.data.height) {
          this.setData({
            cut_top: this.data.info.windowHeight - this.data.height
          });
        }
      }, _cutDetectionPositionLeft = () => {
        //检测左边距是否在范围内
        if (this.data.cut_left < 0) {
          this.setData({
            cut_left: 0
          });
        }
        if (this.data.cut_left > this.data.info.windowWidth - this.data.width) {
          this.setData({
            cut_left: this.data.info.windowWidth - this.data.width
          });
        }
      };
      //裁剪框坐标处理(如果只写一个参数则另一个默认为0,都不写默认居中)
      if (this.data.cut_top == null && this.data.cut_left == null) {
        this._setCutCenter();
      } else if (this.data.cut_top != null && this.data.cut_left != null){
        _cutDetectionPositionTop();
        _cutDetectionPositionLeft();
      } else if (this.data.cut_top != null && this.data.cut_left == null) {
        _cutDetectionPositionTop();
        this.setData({
          cut_left: (this.data.info.windowWidth - this.data.width) / 2
        });
      } else if (this.data.cut_top == null && this.data.cut_left != null) {
        _cutDetectionPositionLeft();
        this.setData({
          cut_top: (this.data.info.windowHeight - this.data.height) / 2
        });
      }
    },
    
    //渲染
    _draw(callback) {
      if (!this.data.imgSrc) return;
      let draw = () => {
        //图片实际大小
        let img_width = this.data.img_width * this.data.scale * this.data.export_scale;
        let img_height = this.data.img_height * this.data.scale * this.data.export_scale;
        //canvas和图片的相对距离
        var xpos = this.data._img_left - this.data.cut_left;
        var ypos = this.data._img_top - this.data.cut_top;
        //旋转画布
        this.data.ctx.translate(xpos * this.data.export_scale, ypos * this.data.export_scale);
        this.data.ctx.rotate(this.data.angle * Math.PI / 180);
        this.data.ctx.drawImage(this.data.imgSrc, -img_width / 2, -img_height / 2, img_width, img_height);
        this.data.ctx.draw(false, () => {
            callback && callback();
        });
      }
      if (this.data.ctx.width != this.data.width || this.data.ctx.height != this.data.height){
        //优化拖动裁剪框,所以必须把宽高设置放在离用户触发渲染最近的地方
        this.setData({
          _canvas_height: this.data.height,
          _canvas_width: this.data.width,
        },()=>{
          //延迟40毫秒防止点击过快出现拉伸或裁剪过多
          setTimeout(() => {
            draw();
          }, 40);
        });
      }else{
        draw();
      }
    },
    //裁剪框处理
    _cutTouchMove(e) {
      if (this.data._flag_cut_touch && this.data.MOVE_THROTTLE_FLAG) {
        if (this.data.disable_ratio && (this.data.disable_width || this.data.disable_height)) return;
        //节流
        this.data.MOVE_THROTTLE_FLAG = false;
        this._move_throttle();
        let width = this.data.width,
          height = this.data.height,
          cut_top = this.data.cut_top,
          cut_left = this.data.cut_left,
          size_correct = () => {
            width = width <= this.data.max_width ? width >= this.data.min_width ? width : this.data.min_width : this.data.max_width;
            height = height <= this.data.max_height ? height >= this.data.min_height ? height : this.data.min_height : this.data.max_height;
          },
          size_inspect = () => {
            if ((width > this.data.max_width || width < this.data.min_width || height > this.data.max_height || height < this.data.min_height) && this.data.disable_ratio) {
              size_correct();
              return false;
            } else {
              size_correct();
              return true;
            }
          };
        height = this.data.CUT_START.height + ((this.data.CUT_START.corner > 1 && this.data.CUT_START.corner < 4 ? 1 : -1) * (this.data.CUT_START.y - e.touches[0].clientY));
        switch (this.data.CUT_START.corner) {
          case 1:
            width = this.data.CUT_START.width + this.data.CUT_START.x - e.touches[0].clientX;
            if (this.data.disable_ratio) {
              height = width / (this.data.width / this.data.height)
            }
            if (!size_inspect()) return;
            cut_left = this.data.CUT_START.cut_left - (width - this.data.CUT_START.width);
            break
          case 2:
            width = this.data.CUT_START.width + this.data.CUT_START.x - e.touches[0].clientX;
            if (this.data.disable_ratio) {
              height = width / (this.data.width / this.data.height)
            }
            if (!size_inspect()) return;
            cut_top = this.data.CUT_START.cut_top - (height - this.data.CUT_START.height)
            cut_left = this.data.CUT_START.cut_left - (width - this.data.CUT_START.width)
            break
          case 3:
            width = this.data.CUT_START.width - this.data.CUT_START.x + e.touches[0].clientX;
            if (this.data.disable_ratio) {
              height = width / (this.data.width / this.data.height)
            }
            if (!size_inspect()) return;
            cut_top = this.data.CUT_START.cut_top - (height - this.data.CUT_START.height);
            break
          case 4:
            width = this.data.CUT_START.width - this.data.CUT_START.x + e.touches[0].clientX;
            if (this.data.disable_ratio) {
              height = width / (this.data.width / this.data.height)
            }
            if (!size_inspect()) return;
            break
        }
        if (!this.data.disable_width && !this.data.disable_height) {
          this.setData({
            width: width,
            cut_left: cut_left,
            height: height,
            cut_top: cut_top,
          })
        } else if (!this.data.disable_width) {
          this.setData({
            width: width,
            cut_left: cut_left
          })
        } else if (!this.data.disable_height) {
          this.setData({
            height: height,
            cut_top: cut_top
          })
        }
        this._imgMarginDetectionScale();
      }
    },
    _cutTouchStart(e) {
      let currentX = e.touches[0].clientX;
      let currentY = e.touches[0].clientY;
      let cutbox_top4 = this.data.cut_top + this.data.height - 30;
      let cutbox_bottom4 = this.data.cut_top + this.data.height + 20;
      let cutbox_left4 = this.data.cut_left + this.data.width - 30;
      let cutbox_right4 = this.data.cut_left + this.data.width + 30;

      let cutbox_top3 = this.data.cut_top - 30;
      let cutbox_bottom3 = this.data.cut_top + 30;
      let cutbox_left3 = this.data.cut_left + this.data.width - 30;
      let cutbox_right3 = this.data.cut_left + this.data.width + 30;

      let cutbox_top2 = this.data.cut_top - 30;
      let cutbox_bottom2 = this.data.cut_top + 30;
      let cutbox_left2 = this.data.cut_left - 30;
      let cutbox_right2 = this.data.cut_left + 30;

      let cutbox_top1 = this.data.cut_top + this.data.height - 30;
      let cutbox_bottom1 = this.data.cut_top + this.data.height + 30;
      let cutbox_left1 = this.data.cut_left - 30;
      let cutbox_right1 = this.data.cut_left + 30;
      if (currentX > cutbox_left4 && currentX < cutbox_right4 && currentY > cutbox_top4 && currentY < cutbox_bottom4) {
        this._moveDuring();
        this.data._flag_cut_touch = true;
        this.data._flag_img_endtouch = true;
        this.data.CUT_START = {
          width: this.data.width,
          height: this.data.height,
          x: currentX,
          y: currentY,
          corner: 4
        }
      } else if (currentX > cutbox_left3 && currentX < cutbox_right3 && currentY > cutbox_top3 && currentY < cutbox_bottom3) {
        this._moveDuring();
        this.data._flag_cut_touch = true;
        this.data._flag_img_endtouch = true;
        this.data.CUT_START = {
          width: this.data.width,
          height: this.data.height,
          x: currentX,
          y: currentY,
          cut_top: this.data.cut_top,
          cut_left: this.data.cut_left,
          corner: 3
        }
      } else if (currentX > cutbox_left2 && currentX < cutbox_right2 && currentY > cutbox_top2 && currentY < cutbox_bottom2) {
        this._moveDuring();
        this.data._flag_cut_touch = true;
        this.data._flag_img_endtouch = true;
        this.data.CUT_START = {
          width: this.data.width,
          height: this.data.height,
          cut_top: this.data.cut_top,
          cut_left: this.data.cut_left,
          x: currentX,
          y: currentY,
          corner: 2
        }
      } else if (currentX > cutbox_left1 && currentX < cutbox_right1 && currentY > cutbox_top1 && currentY < cutbox_bottom1) {
        this._moveDuring();
        this.data._flag_cut_touch = true;
        this.data._flag_img_endtouch = true;
        this.data.CUT_START = {
          width: this.data.width,
          height: this.data.height,
          cut_top: this.data.cut_top,
          cut_left: this.data.cut_left,
          x: currentX,
          y: currentY,
          corner: 1
        }
      }
    },
    _cutTouchEnd(e) {
      this._moveStop();
      this.data._flag_cut_touch = false;
    },
    //停止移动时需要做的操作
    _moveStop() {
      //清空之前的自动居中延迟函数并添加最新的
      clearTimeout(this.data.TIME_CUT_CENTER);
      this.data.TIME_CUT_CENTER = setTimeout(() => {
        //动画启动
        if (!this.data._cut_animation) {
          this.setData({
            _cut_animation: true
          });
        }
        this.setCutCenter();
      }, 1000)
      //清空之前的背景变化延迟函数并添加最新的
      clearTimeout(this.data.TIME_BG);
      this.data.TIME_BG = setTimeout(() => {
        if (this.data._flag_bright) {
          this.setData({
            _flag_bright: false
          });
        }
      }, 2000)
    },
    //移动中
    _moveDuring() {
      //清空之前的自动居中延迟函数
      clearTimeout(this.data.TIME_CUT_CENTER);
      //清空之前的背景变化延迟函数
      clearTimeout(this.data.TIME_BG);
      //高亮背景
      if (!this.data._flag_bright) {
        this.setData({
          _flag_bright: true
        });
      }
    },
    //监听器
    _watcher() {
      Object.keys(this.data).forEach(v => {
        this._observe(this.data, v, this.data.watch[v]);
      })
    },
    _observe(obj, key, watchFun) {
      var val = obj[key];
      Object.defineProperty(obj, key, {
        configurable: true,
        enumerable: true,
        set:(value) => {
          val = value;
          watchFun && watchFun(val, this);
        },
        get() {
          if (val && '_img_top|img_left||width|height|min_width|max_width|min_height|max_height|export_scale|cut_top|cut_left|canvas_top|canvas_left|img_width|img_height|scale|angle|min_scale|max_scale'.indexOf(key)!=-1){
            let ret = parseFloat(parseFloat(val).toFixed(3));
            if (typeof val == "string" && val.indexOf("%") != -1){
              ret+='%';
            }
            return ret;
          }
          return val;
        }
      })
    },
    _preventTouchMove() {
    }
  }
})

2.组件的使用

2.1 wxml

<!--miniprogram/pages/2.14/cut/index.wxml-->
<view class="page-section">
	<text class="page-section__title">图片裁剪</text>
	<image-cropper id="image-cropper" limit_move="{{true}}" disable_rotate="{{true}}" width="{{width}}" height="{{height}}" imgSrc="{{src}}" bindload="cropperload" bindimageload="loadimage" bindtapcut="clickcut"></image-cropper>
</view>

2.2 js

// miniprogram/pages/2.14/cut/index.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    src: '',
    width: 250, //宽度
    height: 250, //高度
  },
  startCuting() {
    //获取到image-cropper对象
    this.cropper = this.selectComponent("#image-cropper");
    //开始裁剪
    this.setData({
      src: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2Ftp09%2F21031FKU44S6-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664885017&t=c57f23cee60a265d5c3d70ebbaa57e30",
    });
    wx.showLoading({
      title: '加载中'
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.startCuting()
  },
  cropperload(e) {
    console.log("cropper初始化完成");
  },
  loadimage(e) {
    console.log("图片加载完成", e.detail);
    wx.hideLoading();
    //重置图片角度、缩放、位置
    this.cropper.imgReset();
  },
  clickcut(e) {
    console.log(e.detail);
    console.log(e.detail.url)
    //点击裁剪框阅览图片
    wx.previewImage({
        current: e.detail.url, // 当前显示图片的http链接
        urls: [e.detail.url] // 需要预览的图片http链接列表
    })
  },
})

2.3 效果

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。