微信小程序·上传头像剪切图片到本地
微信小程序·上传头像剪切图片到本地
组件化

.wxml 子组件文件
<view class="container">
<view class="top {{moving?'bg-5':'bg-9'}}" style="height:{{(systemInfo.windowHeight-300)/2}}px;"></view>
<view class="left {{moving?'bg-5':'bg-9'}}" style="width: {{(systemInfo.windowWidth-300)/2}}px;top: {{(systemInfo.windowHeight-300)/2}}px;height: 300px;"></view>
<view class="right {{moving?'bg-5':'bg-9'}}" style="width: {{(systemInfo.windowWidth-300)/2}}px;top: {{(systemInfo.windowHeight-300)/2}}px;height: 300px;"></view>
<view class="bottom {{moving?'bg-5':'bg-9'}}" style="top:{{(systemInfo.windowHeight-300)/2+300}}px;"></view>
<canvas canvas-id="myCanvas" class="canvas">
</canvas>
<movable-area scale-area class="movable-area" style="top: {{(systemInfo.windowHeight-300)/2}}px;left: {{(systemInfo.windowWidth-300)/2}}px;">
<movable-view scale-min="1" animation="{{false}}" bindscale="onScale" bindchange="onMove" x="{{x}}" y="{{y}}" scale direction="all" style="width: {{image_w}}px;height: {{image_h}}px;">
<image class="image" bindload="onImageLoad" src="{{imageUrl}}"></image>
</movable-view>
</movable-area>
<view class="footer">
<view class="button" bindtap="cancel">取消</view>
<view class="button" style="background-color: #4CE0E0;color: #fff;" bindtap="getImage">确定</view>
</view>
</view>.wxss 子组件文件
.container {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
background: #000;
z-index: 80;
}
.top {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 99;
}
.left {
position: fixed;
left: 0;
z-index: 99;
}
.right {
position: fixed;
right: 0;
z-index: 99;
}
.bottom {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
z-index: 99;
}
.bg-5 {
background: rgba(0, 0, 0, 0.3);
}
.bg-9 {
background: rgba(0, 0, 0, 0.8);
transition-duration: .5s;
transition-property: background;
}
.canvas {
position: absolute;
top: 0;
left: -1000px;
width: 300px;
height: 300px;
}
.movable-area {
position: fixed;
width: 300px;
height: 300px;
}
.image {
width: 100%;
height: 100%;
display: flex;
}
.footer {
position: absolute;
left: 0;
bottom: 0;
padding-bottom: env(safe-area-inset-bottom);
height: calc(140rpx + env(safe-area-inset-bottom));
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
z-index: 100;
background-color: rgba(0, 0, 0, 0.8);
box-sizing: border-box;
}
.button {
width: 300rpx;
height: 100rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
border-radius: 100rpx;
margin-left: 50rpx;
}.js 子组件文件
const debounce = function (fn, delay = 3000) {
let timer = null
const _debounce = function (...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
return _debounce
}
Component({
properties: {
imageUrl: {
type: String,
value: ''
},
show: {
type: Boolean,
value: false
}
},
data: {
moving: false,
},
lifetimes: {
ready() {
this.context = wx.createCanvasContext('myCanvas', this);
this.setData({
systemInfo: wx.getSystemInfoSync()
})
}
},
methods: {
// 初始化图片大小
onImageLoad: function (e) {
let {
width,
height
} = e.detail, h = 300, w = 300, x = 0, y = 0;
if (width < height) {
h = height * w / width;
y = -(h - 300) / 2;
}
if (height < width) {
w = width * h / height;
x = -(w - 300) / 2;
}
this.x = x;
this.y = y;
this.scale = 1;
this.setData({
image_w: w,
image_h: h,
original_w: width,
original_h: height,
x,
y
})
this.getDramParams();
},
getDramParams: function () {
let {
original_w,
original_h,
image_w,
image_h
} = this.data, {
x,
y,
scale
} = this;
//console.log(x, y, scale)
let sourceX = Math.abs(original_h * x / image_h),
sourceY = Math.abs(original_w * y / image_w);
this.context.drawImage(this.properties.imageUrl, sourceX / scale, sourceY / scale, Math.min(original_h, original_w) / scale, Math.min(original_h, original_w) / scale, 0, 0, 300, 300);
this.context.draw()
},
// 获取图片
getImage: function () {
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
success: res => {
//console.log(res)
this.setData({
image: res.tempFilePath,
show: false
})
this.triggerEvent('returnImageUrl', {
imageUrl: res.tempFilePath
})
}
}, this)
},
// 拖动图片
onMove: function (e) {
//console.log(e)
let {
x,
y
} = e.detail;
this.x = x;
this.y = y;
this.setBg();
debounce(this.getDramParams(), 300)
},
onScale: function (e) {
let {
x,
y,
scale
} = e.detail;
this.x = x;
this.y = y;
this.scale = scale;
this.setBg();
debounce(this.getDramParams(), 300)
},
setBg: function () {
if (!this.data.moving) {
this.setData({
moving: true
})
}
if (this.timer) clearInterval(this.timer);
let count = 0;
this.timer = setInterval(() => {
count += 1000;
if (count >= 1000) {
clearInterval(this.timer);
this.setData({
moving: false
})
}
}, 1000);
},
cancel: function (e) {
this.setData({
show: false
})
}
}
})父组件 引用方式: imageUrl 本地图像图片地址 bind:returnImageUrl 为接收剪切后保存图片地址
<img_photo imageUrl="{{url}}" bind:returnImageUrl="putImageUrl" ></img_photo>