项目需求是需要做一个上传图片按1:1,16:9 ,3:4一个图片截取,网上查了好久,找到一个cropper截取组件 ,现在把接入以及修改步骤记录一下
截取组件原地址找不到了,贴一下代码吧(谢谢大佬分享了!!!)
wxml

<view class="wx-cropper-info" wx:if="{{isShowCropper}}"><view class='cropper-content'><view class="wx-corpper" style="width:{{cropperInitW}}rpx;height:{{cropperInitH}}rpx;background:#000"><view class="wx-corpper-content" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx;left:{{cropperL}}rpx;top:{{cropperT}}rpx"><image class="img" src="{{imageSrc}}" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx"></image><view class="wx-corpper-crop-box" bindtouchstart="contentStartMove" bindtouchmove="contentMoveing"bindtouchend="contentTouchEnd" style="left:{{cutL}}rpx;top:{{cutT}}rpx;right:{{cutR}}rpx;bottom:{{cutB}}rpx"><view class="wx-cropper-view-box"><view class="wx-cropper-dashed-h"></view><view class="wx-cropper-dashed-v"></view><!-- catchtouchmove="dragMove" --><view class="wx-cropper-line-t" data-drag="top" catchtouchstart="dragStart" catchtouchmove="dragMove"></view><view class="wx-cropper-line-r" data-drag="right" catchtouchstart="dragStart"catchtouchmove="dragMove"></view><view class="wx-cropper-line-b" data-drag="bottom" catchtouchstart="dragStart"catchtouchmove="dragMove"></view><view class="wx-cropper-line-l" data-drag="left" catchtouchstart="dragStart" catchtouchmove="dragMove"></view><view class="wx-cropper-point point-t" data-drag="top" catchtouchstart="dragStart"catchtouchmove="dragMove"></view><view class="wx-cropper-point point-tr" data-drag="topTight"></view><view class="wx-cropper-point point-r" data-drag="right" catchtouchstart="dragStart"catchtouchmove="dragMove"></view><view class="wx-cropper-point point-rb" data-drag="rightBottom" catchtouchstart="dragStart"catchtouchmove="dragMove"></view><view class="wx-cropper-point point-b" data-drag="bottom" catchtouchstart="dragStart"catchtouchmove="dragMove" catchtouchend="dragEnd"></view><view class="wx-cropper-point point-bl" data-drag="bottomLeft"></view><view class="wx-cropper-point point-l" data-drag="left" catchtouchstart="dragStart"catchtouchmove="dragMove"></view><view class="wx-cropper-point point-lt" data-drag="leftTop"></view></view></view></view></view></view><view class="cropper-configs" wx:if="{{!isDefault}}"><button type="primary reverse" class="btn" bindtap="changeSome" data-index="1" style='margin-top: 30rpx;'> 1:1 </button><button type="primary reverse" class="btn" bindtap="changeSome" data-index="0.75"style='margin-top: 30rpx;'> 3:4 </button><button type="primary reverse" class="btn" bindtap="changeSome" data-index="0.5625" style='margin-top: 30rpx;'> 9:16 </button></view><view class='cropper-config'><button type="primary reverse" class="btn" bindtap="cancelCropper" style='margin-top: 30rpx;'> 取消 </button><button type="primary" class="cropper-confirm btn" bindtap="confirmCropper" style='margin-top: 30rpx;'>  确认 </button></view><canvas wx:if="{{!isCircleCrop}}" canvas-id="cropper" style="position:absolute;border: 1px solid red; width:{{qualityWidth}}px;height:{{qualityWidth/innerAspectRadio}}px;top:-9999px;left:-9999px;"></canvas><canvas wx:else canvas-id="cropper" style="position:absolute;border: 1px solid red; width:{{canvasW}}px;height:{{canvasH}}px;top:-9999px;left:-9999px;"></canvas>
</view>

js

const defaultData = {isShowCropper:false,// 初始化的宽高cropperInitW: 750,cropperInitH: 750,// 动态的宽高cropperW: 750,cropperH: 750,// 动态的left top值cropperL: 0,cropperT: 0,transL: 0,transT: 0,// 图片缩放值scaleP: 0,imageW: 0,imageH: 0,// 裁剪框 宽高cutL: 0,cutT: 0,cutB: 0,cutR: 0,qualityWidth: '',innerAspectRadio: 750 / wx.getSystemInfoSync().windowWidth,C_CONSTANTS:{SCREEN_WIDTH : 750,PAGE_X:0, // 手按下的x位置PAGE_Y:0, // 手按下y的位置PR : wx.getSystemInfoSync().pixelRatio, // dpiT_PAGE_X:{}, // 手移动的时候x的位置T_PAGE_Y:{}, // 手移动的时候Y的位置CUT_L:0, // 初始化拖拽元素的left值CUT_T:0, // 初始化拖拽元素的top值CUT_R:0, // 初始化拖拽元素的CUT_B:0, // 初始化拖拽元素的CUT_W:0, // 初始化拖拽元素的宽度CUT_H:0, //  初始化拖拽元素的高度IMG_RATIO:0, // 图片比例IMG_REAL_W:0, // 图片实际的宽度IMG_REAL_H:0, // 图片实际的高度IMG_TYPE:'',//图片的格式DRAFG_MOVE_RATIO : 750 / wx.getSystemInfoSync().windowWidth //移动时候的比例}
};
let data = {};try{data = JSON.parse(JSON.stringify(defaultData));
}catch(e){console.log(e)};Component({properties: {imageSrc:{type:String,value:'',observer(newVal, oldVal) {if(newVal !== oldVal){this.setData({isShowCropper:true},() => {this.loadImage();})}}},isCircleCrop:{type:Boolean,value:false},isDefault: {type: Boolean,value: false},enableScale:{type:Boolean,value:false},ratio:{type:Number,value:1,}},observers:{ratio(val) {let that = this;console.log(val,'1111')that.loadImage()}},data,ready(){if(this.data.isCircleCrop){//圆形裁剪 强制比例为1this.setData({ratio:1})}},methods: {// 修改裁剪比例changeSome(e){let that = this;// console.log(e.currentTarget.dataset.index)that.triggerEvent('changeScale', {'scale': e.currentTarget.dataset.index})// that.setData({//     ratio:e.currentTarget.dataset.index,// })},loadImage() {let {ratio,imageSrc} = this.data;let {IMG_REAL_W,IMG_REAL_H,IMG_RATIO,SCREEN_WIDTH,IMG_TYPE} = this.data.C_CONSTANTS;wx.getImageInfo({src: imageSrc,success: res => {IMG_REAL_W = res.width;IMG_REAL_H = res.height;IMG_RATIO = IMG_REAL_W / IMG_REAL_H;IMG_TYPE = res.type === 'png' ? 'png' : 'jpg';// 根据图片的宽高显示不同的效果   保证图片可以正常显示let temp = {};let cropperData = {};if (IMG_RATIO >= 1) {cropperData = {cropperW: SCREEN_WIDTH,cropperH: SCREEN_WIDTH / IMG_RATIO,// 初始化left rightcropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2)}if(ratio > 1){temp = {cutL: (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2,cutT: (SCREEN_WIDTH / IMG_RATIO - SCREEN_WIDTH / IMG_RATIO / ratio ) / 2,cutR: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2 - SCREEN_WIDTH / IMG_RATIO,cutB: SCREEN_WIDTH / IMG_RATIO - (SCREEN_WIDTH / IMG_RATIO - SCREEN_WIDTH / IMG_RATIO / ratio ) / 2 - SCREEN_WIDTH / IMG_RATIO / ratio}}else{temp = {cutT:0,cutB:0,cutL:(SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO * ratio) / 2,cutR: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO * ratio) / 2 - SCREEN_WIDTH / IMG_RATIO * ratio}}} else {cropperData = {cropperW: SCREEN_WIDTH * IMG_RATIO,cropperH: SCREEN_WIDTH,// 初始化left rightcropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2),cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2)}if(ratio > 1){temp = {cutL:0,cutR:0,cutT: (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO / ratio) / 2,cutB: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO / ratio) / 2 - SCREEN_WIDTH * IMG_RATIO / ratio}}else{temp = {cutL: (SCREEN_WIDTH * IMG_RATIO - SCREEN_WIDTH * IMG_RATIO * ratio) / 2,cutR: SCREEN_WIDTH * IMG_RATIO - (SCREEN_WIDTH * IMG_RATIO - SCREEN_WIDTH * IMG_RATIO * ratio) / 2 - SCREEN_WIDTH * IMG_RATIO * ratio,cutT: (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2,cutB: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2 - SCREEN_WIDTH * IMG_RATIO}}}this.setData({C_CONSTANTS:Object.assign({},this.data.C_CONSTANTS,{IMG_REAL_W,IMG_REAL_H,IMG_RATIO,IMG_TYPE}),isShowCropper: true,// 图片缩放值scaleP: IMG_REAL_W / SCREEN_WIDTH,qualityWidth: IMG_REAL_W,innerAspectRadio: IMG_RATIO,...temp,...cropperData})}});},contentStartMove(e) {this.setData({'C_CONSTANTS.PAGE_X':e.touches[0].pageX,'C_CONSTANTS.PAGE_Y':e.touches[0].pageY})},// 拖动时候触发的touchMove事件contentMoveing(e) {let {PAGE_X,PAGE_Y,DRAFG_MOVE_RATIO} = this.data.C_CONSTANTS;let {cutL,cutR,cutT,cutB} = this.data;let dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIOlet dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO// 左移if (dragLengthX > 0) {if (cutL - dragLengthX < 0) dragLengthX = cutL} else {if (cutR + dragLengthX < 0) dragLengthX = -cutR}if (dragLengthY > 0) {if (cutT - dragLengthY < 0) dragLengthY = cutT} else {if (cutB + dragLengthY < 0) dragLengthY = -cutB}this.setData({cutL: cutL - dragLengthX,cutT: cutT - dragLengthY,cutR: cutR + dragLengthX,cutB: cutB + dragLengthY,'C_CONSTANTS.PAGE_X':e.touches[0].pageX,'C_CONSTANTS.PAGE_Y':e.touches[0].pageY});},// 设置大小的时候触发的touchStart事件dragStart(e) {let {cutL,cutR,cutT,cutB} = this.data;this.setData({C_CONSTANTS:Object.assign({},this.data.C_CONSTANTS,{T_PAGE_X : e.touches[0].pageX,T_PAGE_Y : e.touches[0].pageY,CUT_L : cutL,CUT_R : cutR,CUT_B : cutB,CUT_T : cutT})})},// 设置大小的时候触发的touchMove事件dragMove(e) {let dragType = e.target.dataset.draglet {ratio,cropperW,cropperH,cutL,cutT,cutR,cutB,enableScale} = this.data;let {CUT_R,CUT_L,CUT_T,CUT_B,T_PAGE_X,T_PAGE_Y,DRAFG_MOVE_RATIO} = this.data.C_CONSTANTS;let dragLength;switch (dragType) {case 'right':dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIOif (CUT_R + dragLength < 0) dragLength = -CUT_RcutR = CUT_R + dragLength;if(enableScale){cutT = CUT_T + dragLength / ratio;}if(cutR < 0 || cutT < 0 || cutT > cropperH || cutR > cropperW) return;break;case 'left':dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIOif (CUT_L - dragLength < 0) dragLength = CUT_Lif ((CUT_L - dragLength) > (this.data.cropperW - this.data.cutR)) dragLength = CUT_L - (this.data.cropperW - this.data.cutR)cutL = CUT_L - dragLength;if(enableScale){cutT = CUT_T - dragLength / ratio;}if(cutL < 0 || cutT < 0 || cutT > cropperH || cutL > cropperW) return;break;case 'top':dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIOif (CUT_T - dragLength < 0) dragLength = CUT_Tif ((CUT_T - dragLength) > (this.data.cropperH - this.data.cutB)) dragLength = CUT_T - (this.data.cropperH - this.data.cutB)cutT = CUT_T - dragLength;if(enableScale){cutR = CUT_R - dragLength * ratio;}break;case 'bottom':dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIOif (CUT_B + dragLength < 0) dragLength = -CUT_BcutB = CUT_B + dragLength;if(enableScale){cutR = CUT_R + dragLength * ratio;}if(cutR < 0 || cutT < 0 || cutT > cropperH || cutR > cropperW) return;break;default:'';}this.setData({cutL,cutT,cutR,cutB});},contentTouchEnd(){},  // 获取图片confirmCropper() {const isCircleCrop = this.data.isCircleCrop;if(isCircleCrop){this.circleCrop()}else{this.normalCropper();}},normalCropper(){let {imageSrc,cropperW,cropperH,cutL,cutT,cutR,cutB} = this.data;let {IMG_REAL_W,IMG_REAL_H,IMG_TYPE} = this.data.C_CONSTANTS;// 将图片写入画布const ctx = wx.createCanvasContext('cropper',this)ctx.drawImage(imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);ctx.draw(true, () => {// 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.data.cutT / _this.data.cropperH) * (_this.data.imageH / pixelRatio)let canvasW = ((cropperW - cutL - cutR) / cropperW) * IMG_REAL_Wlet canvasH = ((cropperH - cutT - cutB) / cropperH) * IMG_REAL_Hlet canvasL = (cutL / cropperW) * IMG_REAL_Wlet canvasT = (cutT / cropperH) * IMG_REAL_Hwx.canvasToTempFilePath({x: canvasL,y: canvasT,width: canvasW,height: canvasH,destWidth: canvasW,destHeight: canvasH,fileType:IMG_TYPE || 'jpg',canvasId: 'cropper',success: (res) => {//图片裁剪成功this.cancelCropper();this.triggerEvent('cropperDone', {src:res.tempFilePath,cropperData:{x: canvasL,y: canvasT,width: canvasW,height: canvasH}})},fail:err =>{this.triggerEvent('cropperFail',err)}},this);})},circleCrop(){console.log('圆角切割')let {imageSrc,cropperW,cropperH,cutL,cutT,cutR,cutB} = this.data;let {IMG_REAL_W,IMG_REAL_H,IMG_TYPE} = this.data.C_CONSTANTS;// 将图片写入画布const ctx = wx.createCanvasContext('cropper',this)let canvasW = ((cropperW - cutL - cutR) / cropperW) * IMG_REAL_Wlet canvasL = (cutL / cropperW) * IMG_REAL_Wlet canvasT = (cutT / cropperH) * IMG_REAL_Hthis.setData({canvasW:canvasW,canvasH:canvasW},() => {ctx.arc(canvasW / 2,canvasW / 2,canvasW / 2,0,2 * Math.PI);ctx.clip();ctx.drawImage(imageSrc, canvasL, canvasT, canvasW, canvasW,0,0,canvasW,canvasW);ctx.draw(true, () => {wx.canvasToTempFilePath({fileType:IMG_TYPE || 'jpg',canvasId: 'cropper',success: (res) => {//图片裁剪成功this.cancelCropper();this.triggerEvent('cropperDone', {src:res.tempFilePath,cropperData:{x: canvasL,y: canvasT,width: canvasW,height: canvasW}})},fail:err =>{this.triggerEvent('cropperFail',err)}},this);})})},cancelCropper(){let originData = {}try{originData = JSON.parse(JSON.stringify(defaultData))}catch(e){};this.setData({...originData});this.triggerEvent('cropperCancel')}}
})

1.引入组件

//.json文件
"usingComponents": {"cropper":"../../components/cropper"}
//.wxml文件
<!-- 图片截取 -->
<view class="btn" bindtap="choiceImageCropper">冲冲冲</view>
<cropper imageSrc="{{imageSrc}}" enableScale="{{true}}" isDefault="{{}}" isCircleCrop="{{false}}"ratio="{{proportion}}" bind:changeScale='changeScale' bind:cropperDone="cropperDone"bind:cropperCancel="cropperCancel" bind:cropperFail="cropperFail"></cropper><!-- imageSrc:需要截取的图片地址enableScale:是否限制比例,true为用户不能随意调整比例 isDefault:是否限定默认尺寸为1:1且不显示其他比例选项 默认flaseisCircleCrop:是否显示圆角切割 (用于切割头像)ratio:为传入截取比例尺(组件默认为1) changeScale:组件传递比例事件cropperDone:用户确认截取图片事件cropperCancel:用户取消截取 cropperFail:截取报错-->
//

2.js事件

  //组件触发取消截取方法cropperCancel(e){console.log('用户截取取消了')},// 组件触发截取确认方法cropperDone(e) {console.log(e);let that = this;that.setData({src:e.detail.src})},// 修改比例changeScale(e) {let that = this;that.setData({proportion: e.detail.scale,})},// 上传需要裁剪图片choiceImageCropper(){let that = this;wx.chooseImage({count: 1,sourceType: ['album', 'camera'],sizeType: ['compressed'],success(res) {console.log(res);that.setData({imageSrc:res.tempFilePaths[0]})},fail(err) {}})},

以上代码贴下来可以直接使用,也可根据自身需求去添加功能及修改,组件有一点问题就是切圆形头像的时候截取框还是矩形不是圆形,但是截取出来的还是圆形的图片的,因为项目不需要截取圆形图片就没做修改,代码也添加了项目需求的一部分功能,总的来说这个组件还是挺好的。

希望能帮到大家,也便于自己记录(如果有帮助到大家可以点下赞哦~)!!!
如有疑问或者不对的地方可以下方评论留言讨论哦~会积极回复大家的!!!

7.微信小程序做按比例截取图片相关推荐

  1. python搭建微信小程序卖货要收费用吗_个人的微信小程序做店铺收费吗?要收多少...

    微信小程序受到了广大用户的使用和喜爱,这种不用下载的应用,让人们能更快的开启和关闭应用,不用担心自己的内存不够.那么今天我们来了解下,个人的微信小程序做店铺收费吗?要收多少? 现在许多用了许多小程序了 ...

  2. 微信小程序做问卷——前端部分(生成问卷)

    文章目录 实现效果 界面功能 数据功能 各个组件的实现 右上角的蓝色加号 问卷结构部分 以单选部分举例 每个题型的灰色加号 每个题型的删除按钮 每个选项的删除按钮 每个输入的数据记录 全部代码 que ...

  3. 微信小程序做店铺收费吗?【微信小程序店铺】

    很多商家企业现在都已经有自己的微信小程序店铺了,还没有的微信小程序店铺的商家企业也是计划开通自己的微信小程序店铺,那么对于他们来说,除了要知道怎么做微信小程序店铺,还需要了解微信小程序做店铺收费吗这个 ...

  4. 微信小程序做一个调查问卷

    用微信小程序做了一个调查问卷 功能描述: 用户一天只能进行一次问卷调查=>用户登录功能 获取用户意见信息 题目分为单选题.多选题.简答题 *设置有其他选项,可进行手动输入选项 多选题选择个数设置 ...

  5. 微信小程序做问卷——前端部分(回答问卷)

    文章目录 实现效果 实现 单选部分 多选部分 问答部分 全部代码 item.wxml item.wxss item.js 生成问卷的部分参考 微信小程序做问卷--前端部分(生成问卷) 实现效果 界面如 ...

  6. 微信小程序做一个圆形图片旋转可以控制开始和结束-音乐播放器的图片旋转功能

    微信小程序做一个圆形图片旋转可以控制开始和结束 1.在 WXML 文件中添加一个 标签,并设置图片的 src 和样式,并为其绑定一个 animation 用来控制旋转动画. <image src ...

  7. 微信小程序使用wxParse,解决图片显示路径问题

    微信小程序使用wxParse,解决图片显示路径问题 参考文章: (1)微信小程序使用wxParse,解决图片显示路径问题 (2)https://www.cnblogs.com/zxf100/p/100 ...

  8. imagepreview使用案例_微信小程序wx.previewImage预览图片实例详解

    一.小知识 二.例子 1.wxml 2.wxss .container { box-sizing:border-box; padding:20px; } .previewimg{ float:left ...

  9. 微信小程序 长按图片不出现菜单_微信小程序实现长按删除图片的示例

    说明 最近在学小程序,遇到长按图片删除的问题,特此记录,记录自己的成长轨迹 需求: 长按删除指定图片 需要解决的问题 长按事件如何表示出来? 如何获取当前长按元素的下标? 如何删除元素? 解决办法 长 ...

最新文章

  1. 华为mate30会用鸿蒙嘛,华为Mate30安卓系统再遭限制,鸿蒙系统真的要应战了
  2. 路由器互联端口处于不同网段的路由方法和原理
  3. linux学习笔记 第七篇 (samba(一))(iscsi)
  4. HTML语言:经典笔记(ZT)
  5. IDEA主题设置(字体颜色背景)
  6. 由于权限引起的Tomcat中项目某些页面访问不了
  7. iOS7下隐藏status bar的详细研究
  8. 数据库:SQL 窗口函数知识介绍
  9. :寻找指定和的整数对_寻找时间:如何增加设计的时间
  10. spring vaadin_在Spring Boot中使用Vaadin的简介
  11. php rsa aes混合加密,手动演示RSA和AES混合加密过程
  12. “这辈子不可能打工男子”出狱了,司法所将重点关注,网友:《今瓶没》今日上映!...
  13. XML-RPC技术在WP上研究(一)
  14. 025Python路--安装第三方模块
  15. SOAP(Simple Object Access Protocol )简单对象访问协议
  16. yii、yaf、ci等php框架性能对比
  17. 51单片机外设篇:DS18B20
  18. 【CDAS峰会】吴喜之:数据科学的未来发展
  19. 华为OceanStor Pacific斩获IO500榜单第二,数据存储的时与势
  20. 配电管理地理信息系统解决方案

热门文章

  1. A003-182-2268-黄清梅
  2. 无人机测量技术在房地一体项目中的应用
  3. 小程序生态助力挖掘自有App流量
  4. mysql_assoc函数_PHP:MySQL函数mysql_fetch_assoc()的用法
  5. 用神经网络实现语音分类
  6. python 闭包 lambda_Python lambda闭包范围
  7. (仿微信Android)IM聊天+抢红包+直播+朋友圈源码发布了
  8. 荔枝文案,水果荔枝发朋友圈文案
  9. Project0:小游戏
  10. Python计算分位点与逆运算:根据给定的值,计算在序列中的分位水平