微信小程序裁剪头像插件
想吃番茄的西红柿 人气:0用户上传头像,需要裁剪成正方形,结合在网上找到裁剪图片方法,封装为微信小程序组件。调用很方便。
参数介绍:
- image_url:需要裁剪的图片链接
- showCutImage:是否显示裁剪图片组件
wxml调用:
<cutImage imageUrl="{{image_url}}" bind:returnImageUrl="returnImageUrl" wx:if="{{showCutImage}}" > </cutImage>
js调用:
returnImageUrl: function (e) { //e.detail.imageUrl,e.detail.showCutImage }
wxml代码:
<view class='fixed-upimg'> <view class="wx-content-info" > <view class="iamge-box" style="width:100%;height:{{imageBoxHeight}}px;"> <image style="height:{{imageHeight}}px;width:{{imageWidth}}px;" src="{{imageUrl}}"></image> <view class="wx-corpper-crop-box" bindtouchstart="contentStartMove" bindtouchmove="contentMoveing" style="width:{{cutW}}px;height:{{cutH}}px;left:{{cutL}}px;top:{{cutT}}px"> <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> <canvas canvas-id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}px;height:{{imageH}}px;top:-9999px;left:-9999px;"></canvas> <view class='button-tjtp' bindtap="getImageInfo" style="position:fixed;bottom:0rpx;"> 提交图片 </view> </view> </view>
wxss代码:
.button-tjtp{ width: 300rpx; height: 45px; border-radius: 50rpx; color: #151D37; background-color: #fff; margin: 20px 225rpx; font-size: 30rpx; display: flex; justify-content: center; align-items: center; } .fixed-upimg{ position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: #000; z-index: 9999; } .wx-content-info{ position: fixed; top: 0rpx; left: 0; right: 0; bottom: 0; } .iamge-box{ display: flex; justify-content: center; align-items: center; } .wx-corpper-crop-box{ position: absolute; width: 500rpx; height: 500rpx; background: rgba(255,255,255,0.3); z-index: 2; } .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; }
js代码:
var pageX = 0 // 拖动时候的 pageY var pageY = 0 // 移动时 手势位移与 实际元素位移的比 var dragScaleP = 2 var pixelRatio = wx.getSystemInfoSync().pixelRatio Component({ /** * 组件的属性列表 */ properties: { imageUrl:{ type:String, value:'' } }, /** * 组件的初始数据 */ data: { imageBoxHeight:0, windowWidth: 0, imageUrl:'' }, lifetimes: { // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 attached: function () { this.getSysInfo(); this.getImageDetail(); }, }, created: function () { this.getSysInfo(); }, /** * 组件的方法列表 */ methods: { // 获取设备信息 getSysInfo () { wx.getSystemInfo({ success: (res) => { console.log(res) this.setData({ imageBoxHeight: res.windowHeight - 85, windowWidth: res.windowWidth }) }, }) }, getImageDetail(){ wx.getImageInfo({ src: this.data.imageUrl, success: (res) => { this.setData({ imageW: res.width / 2, imageH: res.height / 2 }) if (res.width >= res.height) { var h = (res.height * this.data.windowWidth) / res.width; this.setData({ imageWidth: this.data.windowWidth, imageHeight: h, cutW: h, cutH: h, cutL: (this.data.windowWidth - h) / 2, cutT: (this.data.imageBoxHeight - h) / 2 }) } else { var w = (this.data.imageBoxHeight * res.width) / res.height; this.setData({ imageWidth: w, imageHeight: this.data.imageBoxHeight, cutW: w, cutH: w, cutL: (this.data.windowWidth - w) / 2, cutT: (this.data.imageBoxHeight - w) / 2 }) } } }) }, // 拖动时候触发的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) var dragLengthY = (pageY - e.touches[0].pageY) var minX = Math.max(_this.data.cutL - (dragLengthX), 0) var minY = Math.max(_this.data.cutT - (dragLengthY), 0) var maxX = _this.data.imageWidth - _this.data.cutW var maxY = _this.data.imageHeight - _this.data.cutH if (_this.data.imageWidth == _this.data.cutW) { this.setData({ cutT: Math.min(maxY, minY), }) } else if (_this.data.imageHeight == _this.data.cutH) { this.setData({ cutL: Math.min(maxX, minX) }) } console.log(`${maxX} ----- ${minX}`) pageX = e.touches[0].pageX pageY = e.touches[0].pageY }, // 拖动时候触发的touchStart事件 contentStartMove(e) { pageX = e.touches[0].pageX pageY = e.touches[0].pageY }, // 裁剪图片 getImageInfo() { var _this = this console.log('shengcheng:' + _this.data.imageUrl) wx.showLoading({ title: '图片生成中...', }) // wx.downloadFile({ // url:_this.data.imageSrc, //仅为示例,并非真实的资源 // success: function (res) { // 将图片写入画布 const ctx = wx.createCanvasContext('myCanvas', _this) // ctx.drawImage(res.tempFilePath) ctx.drawImage(_this.data.imageUrl, 0, 0, _this.data.imageW, _this.data.imageH) ctx.draw(true, () => { // 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题 var canvasW = (_this.data.cutW / _this.data.imageWidth) * (_this.data.imageW) var canvasH = (_this.data.cutH / _this.data.imageHeight) * (_this.data.imageH) var canvasL, canvasT; if (_this.data.imageHeight == _this.data.imageBoxHeight) { canvasL = (0 / _this.data.imageWidth) * (_this.data.imageW) } else { canvasL = (_this.data.cutL / _this.data.imageWidth) * (_this.data.imageW) } if (_this.data.imageWidth == _this.data.windowWidth) { canvasT = (0 / _this.data.imageHeight) * (_this.data.imageH) } else { canvasT = (_this.data.cutT / _this.data.imageHeight) * (_this.data.imageH) } 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) { // 成功获得地址的地方 var tempFilePath = res.tempFilePath; wx.hideLoading() _this.returnImageUrl(tempFilePath) }, fail: function (res) { console.log(res) wx.hideLoading() wx.showModal({ content: '抱歉,图片上传失败!图片过大可能导致图片上传失败!', showCancel: false, confirmText: '我知道了', confirmColor: "#151D37", success: function (res) { if (res.confirm) { _this.setData({ imageFixed: false, tempFilePath: res.tempFilePath }) } } }) } }, _this) }) }, returnImageUrl: function (url) { this.triggerEvent('returnImageUrl', { imageUrl: url, showCutImage:false }) } } })
加载全部内容