<!--微信小程序 --> <view> <view bindtap='upEwm'> <view>頭像</view> <image style='width:200rpx;height:200rpx;background-color:red' src='{{headImg}}'></image> </view> </view> <!--裁剪圖片浮層--> <view class='fixed-upimg' wx:if="{{imageFixed}}"> <view class="wx-content-info"> <view wx:if="{{isShowImg}}" class="wx-corpper" style="width:{{cropperInitW}}rpx;height:{{cropperInitH}}rpx;background:#000"> <view bindtap='upLoad' class="wx-corpper-content" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx;left:{{cropperL}}rpx;top:{{cropperT}}rpx"> <image src="{{imageSrc}}" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx"></image> <view class="wx-corpper-crop-box" bindtouchstart="contentStartMove" bindtouchmove="contentMoveing" style="width:{{cutW}}rpx;height:{{cutH}}rpx;left:{{cutL}}rpx;top:{{cutT}}rpx"> <view class="wx-cropper-view-box"> <view class="wx-cropper-dashed-h"></view> <view class="wx-cropper-dashed-v"></view> <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"></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> <canvas canvas-id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}rpx;height:{{imageH}}rpx;top:-9999px;left:-9999px;"></canvas> <button type="primary" bindtap="getImageInfo" style="position:fixed;bottom:120rpx;width:90%;left:50%;transform:translate3d(-50%,0,0)"> 確認提交 </button> </view> </view>
js 部分
// 手機的寬度 var windowWRPX = 750 // 拖動時候的 pageX var pageX = 0 // 拖動時候的 pageY var pageY = 0 var pixelRatio = wx.getSystemInfoSync().pixelRatio // 調整大小時候的 pageX var sizeConfPageX = 0 // 調整大小時候的 pageY var sizeConfPageY = 0 var initDragCutW = 0 var initDragCutL = 0 var initDragCutH = 0 var initDragCutT = 0 // 移動時 手勢位移與 實際元素位移的比 var dragScaleP = 2 Page({ /** * 頁面的初始數據 */ data: { imageNum: '', //上傳的圖片id headImg: '', //頭像上傳 imageFixed: false, //裁剪浮層 imageSrc: '', //要裁剪的圖片 returnImage: '', isShowImg: false, // 初始化的寬高 cropperInitW: windowWRPX, cropperInitH: windowWRPX, // 動態的寬高 cropperW: windowWRPX, cropperH: windowWRPX, // 動態的left top值 cropperL: 0, cropperT: 0, // 圖片縮放值 scaleP: 0, imageW: 0, imageH: 0, // 裁剪框 寬高 cutW: 400, cutH: 400, cutL: 0, cutT: 0, }, /** * 生命周期函數--監聽頁面加載 */ onReady: function(options) {}, /** * 生命周期函數--監聽頁面初次渲染完成 */ onLoad: function() { var _this = this wx.getImageInfo({ src: _this.data.imageSrc, success: function success(res) { var innerAspectRadio = res.width / res.height; console.log(innerAspectRadio) // 根據圖片的寬高顯示不同的效果 保證圖片可以正常顯示 if (innerAspectRadio >= 1) { _this.setData({ cropperW: windowWRPX, cropperH: windowWRPX / innerAspectRadio, // 初始化left right cropperL: Math.ceil((windowWRPX - windowWRPX) / 2), cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2), // 裁剪框 寬高 // cutW: windowWRPX - 200, // cutH: windowWRPX / innerAspectRadio - 200, cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2), cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2), // 圖片縮放值 scaleP: res.width * pixelRatio / windowWRPX, // 圖片原始寬度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio }) } else { _this.setData({ cropperW: windowWRPX * innerAspectRadio, cropperH: windowWRPX, // 初始化left right cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2), cropperT: Math.ceil((windowWRPX - windowWRPX) / 2), // 裁剪框的寬高 // cutW: windowWRPX * innerAspectRadio - 66, // cutH: 400, cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2), cutT: Math.ceil((windowWRPX - 340) / 2), // 圖片縮放值 scaleP: res.width * pixelRatio / windowWRPX, // 圖片原始寬度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio }) } _this.setData({ isShowImg: true }) } }) }, // 拖動時候觸發的touchStart事件 contentStartMove(e) { pageX = e.touches[0].pageX pageY = e.touches[0].pageY }, // 拖動時候觸發的touchMove事件 contentMoveing(e) { var _this = this var dragLengthX = (pageX - e.touches[0].pageX) * dragScaleP var dragLengthY = (pageY - e.touches[0].pageY) * dragScaleP var minX = Math.max(_this.data.cutL - (dragLengthX), 0) var minY = Math.max(_this.data.cutT - (dragLengthY), 0) var maxX = _this.data.cropperW - _this.data.cutW var maxY = _this.data.cropperH - _this.data.cutH this.setData({ cutL: Math.min(maxX, minX), cutT: Math.min(maxY, minY), }) console.log(`${maxX} ----- ${minX}`) pageX = e.touches[0].pageX pageY = e.touches[0].pageY }, // 獲取圖片 getImageInfo() { var _this = this console.log('shengcheng:' + _this.data.imageSrc) wx.showLoading({ title: '圖片生成中...', }) // wx.downloadFile({ // url:_this.data.imageSrc, //僅為示例,並非真實的資源 // success: function (res) { // 將圖片寫入畫布 const ctx = wx.createCanvasContext('myCanvas') ctx.drawImage(_this.data.imageSrc) ctx.draw(true, () => { // 獲取畫布要裁剪的位置和寬度 均為百分比 * 畫布中圖片的寬度 保證了在微信小程序中裁剪的圖片模糊 位置不對的問題 var canvasW = (_this.data.cutW / _this.data.cropperW) * (_this.data.imageW / pixelRatio) var canvasH = (_this.data.cutH / _this.data.cropperH) * (_this.data.imageH / pixelRatio) var canvasL = (_this.data.cutL / _this.data.cropperW) * (_this.data.imageW / pixelRatio) var canvasT = (_this.data.cutT / _this.data.cropperH) * (_this.data.imageH / pixelRatio) console.log(`canvasW:${canvasW} --- canvasH: ${canvasH} --- canvasL: ${canvasL} --- canvasT: ${canvasT} -------- _this.data.imageW: ${_this.data.imageW} ------- _this.data.imageH: ${_this.data.imageH} ---- pixelRatio ${pixelRatio}`) wx.canvasToTempFilePath({ x: canvasL, y: canvasT, width: canvasW, height: canvasH, destWidth: canvasW, destHeight: canvasH, canvasId: 'myCanvas', success: function(res) { wx.hideLoading() console.log('end:' + res.tempFilePath) _this.setData({ imageFixed: false, headImg: res.tempFilePath }) } }) }) }, // 設置大小的時候觸發的touchStart事件 dragStart(e) { var _this = this sizeConfPageX = e.touches[0].pageX sizeConfPageY = e.touches[0].pageY initDragCutW = _this.data.cutW initDragCutL = _this.data.cutL initDragCutT = _this.data.cutT initDragCutH = _this.data.cutH }, // 設置大小的時候觸發的touchMove事件 dragMove(e) { var _this = this var dragType = e.target.dataset.drag switch (dragType) { case 'right': var dragLength = (sizeConfPageX - e.touches[0].pageX) * dragScaleP if (initDragCutW >= dragLength) { // 如果 移動小於0 說明是在往下啦 放大裁剪的高度 這樣一來 圖片的高度 最大 等於 圖片的top值加 當前圖片的高度 否則就說明超出界限 if (dragLength < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) { this.setData({ cutW: initDragCutW - dragLength }) } // 如果是移動 大於0 說明在縮小 只需要縮小的距離小於原本裁剪的高度就ok if (dragLength > 0) { this.setData({ cutW: initDragCutW - dragLength }) } else { return } } else { return } break; case 'left': var dragLength = (dragLength = sizeConfPageX - e.touches[0].pageX) * dragScaleP console.log(dragLength) if (initDragCutW >= dragLength && initDragCutL > dragLength) { if (dragLength < 0 && Math.abs(dragLength) >= initDragCutW) return this.setData({ cutL: initDragCutL - dragLength, cutW: initDragCutW + dragLength }) } else { return; } break; case 'top': var dragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP if (initDragCutH >= dragLength && initDragCutT > dragLength) { if (dragLength < 0 && Math.abs(dragLength) >= initDragCutH) return this.setData({ cutT: initDragCutT - dragLength, cutH: initDragCutH + dragLength }) } else { return; } break; case 'bottom': var dragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP // console.log(_this.data.cropperH > _this.data.cutT + _this.data.cutH) console.log(dragLength) console.log(initDragCutH >= dragLength) console.log(_this.data.cropperH > initDragCutT + _this.data.cutH) // 必須是 dragLength 向上縮小的時候必須小於原本的高度 if (initDragCutH >= dragLength) { // 如果 移動小於0 說明是在往下啦 放大裁剪的高度 這樣一來 圖片的高度 最大 等於 圖片的top值加 當前圖片的高度 否則就說明超出界限 if (dragLength < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) { this.setData({ cutH: initDragCutH - dragLength }) } // 如果是移動 大於0 說明在縮小 只需要縮小的距離小於原本裁剪的高度就ok if (dragLength > 0) { this.setData({ cutH: initDragCutH - dragLength }) } else { return } } else { return } break; case 'rightBottom': var dragLengthX = (sizeConfPageX - e.touches[0].pageX) * dragScaleP var dragLengthY = (sizeConfPageY - e.touches[0].pageY) * dragScaleP if (initDragCutH >= dragLengthY && initDragCutW >= dragLengthX) { // bottom 方向的變化 if ((dragLengthY < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) || (dragLengthY > 0)) { this.setData({ cutH: initDragCutH - dragLengthY }) } // right 方向的變化 if ((dragLengthX < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) || (dragLengthX > 0)) { this.setData({ cutW: initDragCutW - dragLengthX }) } else { return } } else { return } break; default: break; } }, // 圖片上傳 upLoad: function() { }, upEwm() { var _this = this wx.chooseImage({ count: 1, // 默認9 sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有 sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有 success: function(res) { var tempFilePaths = res.tempFilePaths[0]; console.log('shangchuan:' + tempFilePaths) _this.setData({ imageFixed: true, imageSrc: tempFilePaths }) // start wx.getImageInfo({ src: _this.data.imageSrc, success: function success(res) { var innerAspectRadio = res.width / res.height; console.log('bili' + innerAspectRadio) // 根據圖片的寬高顯示不同的效果 保證圖片可以正常顯示 if (innerAspectRadio == '1') { _this.setData({ imageFixed: false, headImg: tempFilePaths.join() }) } else if (innerAspectRadio > 1) { _this.setData({ cropperW: windowWRPX, cropperH: windowWRPX / innerAspectRadio, // 初始化left right cropperL: Math.ceil((windowWRPX - windowWRPX) / 2), cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2), // 裁剪框 寬高 // cutW: windowWRPX - 200, // cutH: windowWRPX / innerAspectRadio - 200, cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2), cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2), // 圖片縮放值 scaleP: res.width * pixelRatio / windowWRPX, // 圖片原始寬度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio }) } else { _this.setData({ cropperW: windowWRPX * innerAspectRadio, cropperH: windowWRPX, // 初始化left right cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2), cropperT: Math.ceil((windowWRPX - windowWRPX) / 2), // 裁剪框的寬高 // cutW: windowWRPX * innerAspectRadio - 66, // cutH: 400, cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2), cutT: Math.ceil((windowWRPX - 340) / 2), // 圖片縮放值 scaleP: res.width * pixelRatio / windowWRPX, // 圖片原始寬度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio }) } _this.setData({ isShowImg: true }) wx.hideLoading() } }) } }) }, /** * 生命周期函數--監聽頁面顯示 */ onShow: function() { } })
css 部分
/* pages/wx-cropper/index.wxss */ .fixed-upimg{ position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: #fff; } .wx-content-info{ position: fixed; top: 130rpx; left: 0; right: 0; bottom: 0; } .wx-corpper{ position: relative; overflow: hidden; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; box-sizing: border-box; } .wx-corpper-content{ position: absolute; top: 0; right: 0; bottom: 0; left: 0; } .wx-corpper-content image { display: block; width: 100%; min-width: 0 !important; max-width: none !important; height: 100%; min-height: 0 !important; max-height: none !important; image-orientation: 0deg !important; margin: 0 auto; } /* 移動圖片效果 */ .wx-cropper-drag-box{ position: absolute; top: 0; right: 0; bottom: 0; left: 0; cursor: move; background: rgba(0,0,0,0.6); z-index: 1; } /* 內部的信息 */ .wx-corpper-crop-box{ position: absolute; width: 500rpx; height: 500rpx; background: rgba(255,255,255,0.3); z-index: 2; } .wx-corpper-crop-box .wx-cropper-view-box { position: relative; display: block; width: 100%; height: 100%; overflow: visible; outline: 1px solid #69f; outline-color: rgba(102, 153, 255, .75) } /* 橫向虛線 */ .wx-cropper-dashed-h{ position: absolute; top: 33.33333333%; left: 0; width: 100%; height: 33.33333333%; border-top: 1px dashed rgba(255,255,255,0.5); border-bottom: 1px dashed rgba(255,255,255,0.5); } /* 縱向虛線 */ .wx-cropper-dashed-v{ position: absolute; left: 33.33333333%; top: 0; width: 33.33333333%; height: 100%; border-left: 1px dashed rgba(255,255,255,0.5); border-right: 1px dashed rgba(255,255,255,0.5); } /* 四個方向的線 為了之后的拖動事件*/ .wx-cropper-line-t{ position: absolute; display: block; width: 100%; background-color: #69f; top: 0; left: 0; height: 1px; opacity: 0.1; cursor: n-resize; } .wx-cropper-line-t::before{ content: ''; position: absolute; top: 50%; right: 0rpx; width: 100%; -webkit-transform: translate3d(0,-50%,0); transform: translate3d(0,-50%,0); bottom: 0; height: 41rpx; background: transparent; z-index: 11; } .wx-cropper-line-r{ position: absolute; display: block; background-color: #69f; top: 0; right: 0px; width: 1px; opacity: 0.1; height: 100%; cursor: e-resize; } .wx-cropper-line-r::before{ content: ''; position: absolute; top: 0; left: 50%; width: 41rpx; -webkit-transform: translate3d(-50%,0,0); transform: translate3d(-50%,0,0); bottom: 0; height: 100%; background: transparent; z-index: 11; } .wx-cropper-line-b{ position: absolute; display: block; width: 100%; background-color: #69f; bottom: 0; left: 0; height: 1px; opacity: 0.1; cursor: s-resize; } .wx-cropper-line-b::before{ content: ''; position: absolute; top: 50%; right: 0rpx; width: 100%; -webkit-transform: translate3d(0,-50%,0); transform: translate3d(0,-50%,0); bottom: 0; height: 41rpx; background: transparent; z-index: 11; } .wx-cropper-line-l{ position: absolute; display: block; background-color: #69f; top: 0; left: 0; width: 1px; opacity: 0.1; height: 100%; cursor: w-resize; } .wx-cropper-line-l::before{ content: ''; position: absolute; top: 0; left: 50%; width: 41rpx; -webkit-transform: translate3d(-50%,0,0); transform: translate3d(-50%,0,0); bottom: 0; height: 100%; background: transparent; z-index: 11; } .wx-cropper-point{ width: 5px; height: 5px; background-color: #69f; opacity: .75; position: absolute; z-index: 3; } .point-t{ top: -3px; left: 50%; margin-left: -3px; cursor: n-resize; } .point-tr{ top: -3px; left: 100%; margin-left: -3px; cursor: n-resize; } .point-r{ top: 50%; left:100%; margin-left: -3px; margin-top: -3px; cursor: n-resize; } .point-rb{ left: 100%; top: 100%; -webkit-transform: translate3d(-50%,-50%,0); transform: translate3d(-50%,-50%,0); cursor: n-resize; width: 24rpx; height: 24rpx; background-color: #69f; position: absolute; z-index: 1112; opacity: 1; } .point-b{ left:50%; top: 100%; margin-left: -3px; margin-top: -3px; cursor: n-resize; } .point-bl{ left:0%; top: 100%; margin-left: -3px; margin-top: -3px; cursor: n-resize; } .point-l{ left:0%; top: 50%; margin-left: -3px; margin-top: -3px; cursor: n-resize; } .point-lt{ left:0%; top: 0%; margin-left: -3px; margin-top: -3px; cursor: n-resize; } /* 裁剪框預覽內容 */ .wx-cropper-viewer{ position: relative; width: 100%; height: 100%; overflow: hidden; } .wx-cropper-viewer image{ position: absolute; z-index: 2; }
支付寶小程序
<!--圖片展示 --> <view> <view onTap='upEwm'> <view>頭像</view> <image style='width:200rpx;height:200rpx;background-color:red' src='{{headImg}}'></image> </view> </view> <!--裁剪圖片浮層--> <view class='fixed-upimg' a:if="{{imageFixed}}"> <view class="wx-content-info"> <view a:if="{{isShowImg}}" class="wx-corpper" style="width:{{cropperInitW}}rpx;height:{{cropperInitH}}rpx;background:#000"> <view onTap='upLoad' class="wx-corpper-content" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx;left:{{cropperL}}rpx;top:{{cropperT}}rpx"> <image src="{{imageSrc}}" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx"></image> <view class="wx-corpper-crop-box" onTouchStart="contentStartMove" onTouchMove="contentMoveing" style="width:{{cutW}}rpx;height:{{cutH}}rpx;left:{{cutL}}rpx;top:{{cutT}}rpx"> <view class="wx-cropper-view-box"> <view class="wx-cropper-dashed-h"></view> <view class="wx-cropper-dashed-v"></view> <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"></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> <canvas id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}rpx;height:{{imageH}}rpx;top:-9999px;left:-9999px;"></canvas> <button type="primary" onTap="getImageInfo" style="position:fixed;bottom:120rpx;width:90%;left:50%;transform:translate3d(-50%,0,0)"> 確認提交 </button> </view> </view>
js
var windowWRPX = 750 // 拖動時候的 pageX var pageX = 0 // 拖動時候的 pageY var pageY = 0 var pixelRatio = my.getSystemInfoSync().pixelRatio console.log(pixelRatio) // 調整大小時候的 pageX var sizeConfPageX = 0 // 調整大小時候的 pageY var sizeConfPageY = 0 var initDragCutW = 0 var initDragCutL = 0 var initDragCutH = 0 var initDragCutT = 0 // 移動時 手勢位移與 實際元素位移的比 var dragScaleP = 2 Page({ data: { imageNum: '', //上傳的圖片id headImg: '', //頭像上傳 ewmImg: '', //二維碼上傳 imageFixed: false, //裁剪浮層 //imageSrc: 'http://topmdrt-static.oss-cn-shenzhen.aliyuncs.com/images/testimg2.jpeg', imageSrc: '', //要裁剪的圖片 returnImage: '', isShowImg: false, // 初始化的寬高 cropperInitW: windowWRPX, cropperInitH: windowWRPX, // 動態的寬高 cropperW: windowWRPX, cropperH: windowWRPX, // 動態的left top值 cropperL: 0, cropperT: 0, // 圖片縮放值 scaleP: 0, imageW: 0, imageH: 0, // 裁剪框 寬高 cutW: 400, cutH: 400, cutL: 0, cutT: 0, }, onLoad: function () { var _this = this my.getImageInfo({ src: _this.data.imageSrc, success: function success(res) { console.log(res) var innerAspectRadio = res.width / res.height; console.log(innerAspectRadio) // 根據圖片的寬高顯示不同的效果 保證圖片可以正常顯示 if (innerAspectRadio >= 1) { _this.setData({ cropperW: windowWRPX, cropperH: windowWRPX / innerAspectRadio, // 初始化left right cropperL: Math.ceil((windowWRPX - windowWRPX) / 2), cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2), // 裁剪框 寬高 // cutW: windowWRPX - 200, // cutH: windowWRPX / innerAspectRadio - 200, cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2), cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2), // 圖片縮放值 scaleP: res.width * pixelRatio / windowWRPX, // 圖片原始寬度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio }) } else { _this.setData({ cropperW: windowWRPX * innerAspectRadio, cropperH: windowWRPX, // 初始化left right cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2), cropperT: Math.ceil((windowWRPX - windowWRPX) / 2), // 裁剪框的寬高 // cutW: windowWRPX * innerAspectRadio - 66, // cutH: 400, cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2), cutT: Math.ceil((windowWRPX - 340) / 2), // 圖片縮放值 scaleP: res.width * pixelRatio / windowWRPX, // 圖片原始寬度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio }) } _this.setData({ isShowImg: true }) my.hideLoading() } }) }, // 拖動時候觸發的touchStart事件 contentStartMove(e) { pageX = e.touches[0].pageX pageY = e.touches[0].pageY }, // 拖動時候觸發的touchMove事件 contentMoveing(e) { var _this = this // _this.data.cutL + (e.touches[0].pageX - pageX) console.log(e.touches[0].pageX) // console.log(e.touches[0].pageX - pageX) var dragLengthX = (pageX - e.touches[0].pageX) * dragScaleP var dragLengthY = (pageY - e.touches[0].pageY) * dragScaleP var minX = Math.max(_this.data.cutL - (dragLengthX), 0) var minY = Math.max(_this.data.cutT - (dragLengthY), 0) var maxX = _this.data.cropperW - _this.data.cutW var maxY = _this.data.cropperH - _this.data.cutH this.setData({ cutL: Math.min(maxX, minX), cutT: Math.min(maxY, minY), }) console.log(`${maxX} ----- ${minX}`) pageX = e.touches[0].pageX pageY = e.touches[0].pageY }, // 獲取圖片 getImageInfo() { var _this = this console.log('shengcheng:' + _this.data.imageSrc) my.showLoading({ title: '圖片生成中...', }) // 將圖片寫入畫布 const ctx = my.createCanvasContext('myCanvas') console.log(1) my.getImageInfo({ src:_this.data.imageSrc, success:(res)=>{ console.log(res) } }) console.log(11,_this.data.cropperW,_this.data.cropperH) ctx.drawImage(_this.data.imageSrc,0,0,_this.data.imageW/pixelRatio,_this.data.imageH/pixelRatio) var canvasW = (_this.data.cutW / _this.data.cropperW) * (_this.data.imageW / pixelRatio) var canvasH = (_this.data.cutH / _this.data.cropperH) * (_this.data.imageH / pixelRatio) var canvasL = (_this.data.cutL / _this.data.cropperW) * (_this.data.imageW / pixelRatio) var canvasT = (_this.data.cutT / _this.data.cropperH) * (_this.data.imageH / pixelRatio) console.log(`canvasW:${canvasW} --- canvasH: ${canvasH} --- canvasL: ${canvasL} --- canvasT: ${canvasT} -------- _this.data.imageW: ${_this.data.imageW} ------- _this.data.imageH: ${_this.data.imageH} ---- pixelRatio ${pixelRatio}`) console.log(2) ctx.draw(true, function () { console.log(3, true) ctx.toTempFilePath({ x: canvasL, y: canvasT, width: canvasW, height: canvasH, destWidth: canvasW, destHeight: canvasH, success: function (res) { my.hideLoading() // 成功獲得地址的地方 console.log(4, res) console.log('end:' + res.apFilePath) // 判斷時上傳頭像還是二維碼 _this.setData({ imageFixed: false, headImg: res.apFilePath }) } }) }) console.log(5) // } /* , () => { // 獲取畫布要裁剪的位置和寬度 均為百分比 * 畫布中圖片的寬度 保證了在微信小程序中裁剪的圖片模糊 位置不對的問題 } */ // }) }, // 設置大小的時候觸發的touchStart事件 dragStart(e) { var _this = this sizeConfPageX = e.touches[0].pageX sizeConfPageY = e.touches[0].pageY initDragCutW = _this.data.cutW initDragCutL = _this.data.cutL initDragCutT = _this.data.cutT initDragCutH = _this.data.cutH }, // 設置大小的時候觸發的touchMove事件 dragMove(e) { var _this = this var dragType = e.target.dataset.drag switch (dragType) { case 'right': var dragLength = (sizeConfPageX - e.touches[0].pageX) * dragScaleP if (initDragCutW >= dragLength) { // 如果 移動小於0 說明是在往下啦 放大裁剪的高度 這樣一來 圖片的高度 最大 等於 圖片的top值加 當前圖片的高度 否則就說明超出界限 if (dragLength < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) { this.setData({ cutW: initDragCutW - dragLength }) } // 如果是移動 大於0 說明在縮小 只需要縮小的距離小於原本裁剪的高度就ok if (dragLength > 0) { this.setData({ cutW: initDragCutW - dragLength }) } else { return } } else { return } break; case 'left': var dragLength = (dragLength = sizeConfPageX - e.touches[0].pageX) * dragScaleP console.log(dragLength) if (initDragCutW >= dragLength && initDragCutL > dragLength) { if (dragLength < 0 && Math.abs(dragLength) >= initDragCutW) return this.setData({ cutL: initDragCutL - dragLength, cutW: initDragCutW + dragLength }) } else { return; } break; case 'top': var dragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP if (initDragCutH >= dragLength && initDragCutT > dragLength) { if (dragLength < 0 && Math.abs(dragLength) >= initDragCutH) return this.setData({ cutT: initDragCutT - dragLength, cutH: initDragCutH + dragLength }) } else { return; } break; case 'bottom': var dragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP // console.log(_this.data.cropperH > _this.data.cutT + _this.data.cutH) console.log(dragLength) console.log(initDragCutH >= dragLength) console.log(_this.data.cropperH > initDragCutT + _this.data.cutH) // 必須是 dragLength 向上縮小的時候必須小於原本的高度 if (initDragCutH >= dragLength) { // 如果 移動小於0 說明是在往下啦 放大裁剪的高度 這樣一來 圖片的高度 最大 等於 圖片的top值加 當前圖片的高度 否則就說明超出界限 if (dragLength < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) { this.setData({ cutH: initDragCutH - dragLength }) } // 如果是移動 大於0 說明在縮小 只需要縮小的距離小於原本裁剪的高度就ok if (dragLength > 0) { this.setData({ cutH: initDragCutH - dragLength }) } else { return } } else { return } break; case 'rightBottom': var dragLengthX = (sizeConfPageX - e.touches[0].pageX) * dragScaleP var dragLengthY = (sizeConfPageY - e.touches[0].pageY) * dragScaleP if (initDragCutH >= dragLengthY && initDragCutW >= dragLengthX) { // bottom 方向的變化 if ((dragLengthY < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) || (dragLengthY > 0)) { this.setData({ cutH: initDragCutH - dragLengthY }) } // right 方向的變化 if ((dragLengthX < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) || (dragLengthX > 0)) { this.setData({ cutW: initDragCutW - dragLengthX }) } else { return } } else { return } break; default: break; } }, upEwm: function () { var _this = this my.chooseImage({ count: 1, // 默認9 sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有 sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有 success: function (res) { console.log(res) // 返回選定照片的本地文件路徑列表,tempFilePath可以作為img標簽的src屬性顯示圖片 var tempFilePaths = res.apFilePaths[0]; // var mode = parseFloat(e.currentTarget.dataset.current); console.log('shangchuan:' + tempFilePaths) _this.setData({ imageFixed: true, imageSrc: tempFilePaths }) // start my.getImageInfo({ src: _this.data.imageSrc, success: function success(res) { console.log('getImageInfo',res) var innerAspectRadio = res.width / res.height; console.log('bili' + innerAspectRadio) // 根據圖片的寬高顯示不同的效果 保證圖片可以正常顯示 if (innerAspectRadio == '1') { _this.setData({ imageFixed: false, headImg: tempFilePaths.join() }) } else if (innerAspectRadio > 1) { console.log(res.width ,pixelRatio) _this.setData({ cropperW: windowWRPX, cropperH: windowWRPX / innerAspectRadio, // 初始化left right cropperL: Math.ceil((windowWRPX - windowWRPX) / 2), cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2), // 裁剪框 寬高 // cutW: windowWRPX - 200, // cutH: windowWRPX / innerAspectRadio - 200, cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2), cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2), // 圖片縮放值 scaleP: res.width * pixelRatio / windowWRPX, // 圖片原始寬度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio }) } else { _this.setData({ cropperW: windowWRPX * innerAspectRadio, cropperH: windowWRPX, // 初始化left right cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2), cropperT: Math.ceil((windowWRPX - windowWRPX) / 2), // 裁剪框的寬高 // cutW: windowWRPX * innerAspectRadio - 66, // cutH: 400, cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2), cutT: Math.ceil((windowWRPX - 340) / 2), // 圖片縮放值 scaleP: res.width * pixelRatio / windowWRPX, // 圖片原始寬度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio }) } _this.setData({ isShowImg: true }) // my.hideLoading() } }) } }) }, }) /*Page({ data: { src: '/imgs/timg.jpg', height: 375, width: 375, windowWidth: '', kuang:{ left:0, top:100 } }, onLoad(query) { // 頁面加載 my.setCanPullDown({ canPullDown: false }) // my.getSystemInfo({ // success:function(res){ // windowWidth: res.windowWidth // } // }) // 頁面顯示 // console.info(my.getSystemInfoSync().windowHeight); }, onReady() { // 頁面加載完成 }, onMovableViewChange(e) { console.log(1, e) }, onMovableViewChangeEnd(e) { console.log(2, e) }, onShow() { let _this = this; }, qq1() { let _t = this; var ctx = my.createCanvasContext('canvasid'); ctx.setFillStyle('#fff'); let path = _t.data.src; ctx.drawImage(path, 0, 0, _t.data.width, _t.data.height);//我們要在canvas中畫一張和放大之后的圖片寬高一樣的圖片 // ctx.save(); // ctx.setStrokeStyle('blue'); // ctx.rect(0, 0, 200,200); // ctx.stroke(); ctx.draw(); }, move(e){ console.log(e.touches[0]) var that = this; var canvasW = 200; var canvasH = 200; let touches =e.touches[0]; var x = touches.x; var y = touches.y; that.setData({ ['kuang.left']:x, ['kuang.top']:y }) }, //上傳圖片 qq(e) { console.log(e) let _this = this; my.chooseImage({ count: 1, sizeType: ['original'], success: function (res) { console.log(res) _this.setData({ src: res.apFilePaths[0] }) _this.aa(res.apFilePaths[0]) } }) }, aa(q) { let _this = this; my.getImageInfo({ src: q, success: (res) => { console.log(1, res) var str = res.width / res.height; console.log('width', str) if (str > 1) { console.log(11111) _this.setData({ height: 200, width: str * 200 }) } else if (str < 1) {//豎版圖片 console.log(22222) _this.setData({ width: 200, height: str * 200 }) } else if (str == 1) { console.log(33333) _this.setData({ width: 200, height:200 }) } } }) }, generate: function () { var _this = this; const ctx_A = my.createCanvasContext('myCanvas_A'); var baseWidth = _this.data.baseWidth * _this.data.Scale;//圖片放大之后的寬 var baseHeight = _this.data.baseHeight * _this.data.Scale;//圖片放大之后的高 ctx_A.drawImage(_this.data.src, 0, 0, baseWidth, baseHeight);//我們要在canvas中畫一張和放大之后的圖片寬高一樣的圖片 ctx_A.draw(); my.showToast({ title: '截取中...', icon: 'loading', duration: 10000 });// setTimeout(function () {//給延時是因為canvas畫圖需要時間 ctx_A.toTempFilePath({//調用方法,開始截取 x: _this.data.x, y: _this.data.y, width: 400, height: 400, destWidth: 400, destHeight: 400, canvasId: 'myCanvas_A', success: function (res) { console.log(res.tempFilePath); } }) }, 2000) }, onHide() { // 頁面隱藏 }, onUnload() { // 頁面被關閉 }, onTitleClick() { // 標題被點擊 }, onPullDownRefresh() { // 頁面被下拉 }, onReachBottom() { // 頁面被拉到底部 }, onShareAppMessage() { // 返回自定義分享信息 return { title: 'My App', desc: 'My App description', path: 'pages/index/index', }; }, }); */