项目遇到拍照要增加取景框的场景,找了写资料,写一下心得。
需要用到camera,cover-view,cover-image
<template>
<view class="camera">
<camera device-position="back" flash="off" style="width: 100%; height: 90vh">
<cover-view class="mask" style="" v-if="cardType === 'card_z'">
<cover-image src="/static/img/idcard_front.png" class="co_img"></cover-image>
</cover-view>
<cover-view class="mask" v-else>
<cover-image src="/static/img/idcard_back.png"></cover-image>
</cover-view>
</camera>
<view class="flex_be_c" style="position: relative; bottom: 0; left: 0; padding: 40rpx">
<view @tap="back">取消</view>
<view class="take_photo" @tap="takeCameraPhoto"></view>
<view @tap="selectAlbum">相册</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
const cameraContext = ref({});
const cardType = ref();
onLoad((options) => {
cardType.value = options.type; // 上一级页面传递过来的证件类型
if(uni.createCameraContext){
cameraContext.value = uni.createCameraContext();
}else{
uni.showToast({
title:'微信版本过低,请升级版本',
icon:'none'
})
}
});
const back = () => {
uni.navigateBack();
};
// 拍照
const takeCameraPhoto = () => {
cameraContext.value.takePhoto({
quality:'high',
success:(res) => {
uni.$emit('isCamera',[cardType.value,res.tempImagePath,true])
uni.navigateBack({
delta:1
})
},
fail:(err) => {}
})
};
// 选择相册
const selectAlbum = () => {
uni.chooseMedia({
count: 1,
sourceType: 'album',
success: (res) => {
console.log('53', res);
uni.$emit('isCamera',[cardType.value,res.tempFiles[0].tempFilePath,true])
uni.navigateBack({
delta: 1
});
}
});
};
</script>
<style lang="scss">
.camera {
height: 100%;
.take_photo {
border-radius: 50%;
padding: 50rpx;
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.4);
}
.mask {
width: 170%;
height: 42%;
transform: rotate(90deg);
position: relative;
top: 400rpx;
left: -260rpx;
.co_img {
width: 100%;
height: 100%;
}
}
}
</style>
返回上一层的时候,有一个getCurrentPages()的api,但是只能在app上使用,小程序不支持,找了很久也没有其他方法,最后只能使用uni.$emit()和uni.$on()
因为要把获取的图片,传递给上一页上传回显,所以通过emit触发上一页的方法,把参数也传递过去
<template>
<view class="flex_be">
<view>
<view class="flex_di" @tap="seletType" data-type="card_z" v-if="!cardZ">
<image class="card_img" style="" src="/static/img/card_z.png"></image>
<text class="card_label">请上传身份证正面</text>
</view>
<view class="flex_di" v-else>
<image class="card_img" :data-url="baseUrl+cardZ" :src="baseUrl+cardZ" @tap="previewImg"></image>
<text class="card_label" @tap="reset" data-type="card_z">重新上传</text>
</view>
</view>
<view>
<view class="flex_di" @tap="seletType" data-type="card_f" v-if="!cardF">
<image class="card_img" src="/static/img/card_f.png"></image>
<text class="card_label">请上传身份证反面</text>
</view>
<view class="flex_di" v-else>
<image class="card_img" :data-url="baseUrl+cardF" :src="baseUrl+cardF" @tap="previewImg"></image>
<text class="card_label" @tap="reset" data-type="card_f">重新上传</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onShow } from '@dcloudio/uni-app'
import { baseUrl } from '/config.js'; // 设置的url
onShow(() =>{
uni.$on('isCamera',function(data){
uploadImage(...data)
uni.$off(['isCamera'])
})
})
const active = ref(1);
const idcardArr = ref([])
// 选择方式
const seletType = (e) => {
uni.showActionSheet({
itemList:['拍个照','从相册中选择'],
itemColor:'#',
success:(res) => {
if(res.tapIndex === 0){
uni.navigateTo({url: '/pages/my/camera?type='+e.currentTarget.dataset.type});
}else if(res.tapIndex === 1){
uni.chooseMedia({
count:1,
sourceType:['album'],
mediaType:'image',
success:(resp) => {
let filePath = resp.tempFiles[0].tempFilePath
uploadImage(e.currentTarget.dataset.type,filePath,true)
}
})
}
}
})
};
// 上传图片
const cardZ = ref()
const cardF = ref()
const uploadImage = (type, filePath, immediate) => {
if (immediate) {
uni.uploadFile({
url: baseUrl + '/system/file/upload',
filePath: filePath,
name:'file',
formData:{},
success:(res) => {
if(res.statusCode === 200){
let data = JSON.parse(res.data)
switch(type){
case 'card_z':
idcardArr.value.push(baseUrl+data.data.url)
cardZ.value = data.data.url
break;
case 'card_f':
idcardArr.value.push(baseUrl+data.data.url)
cardF.value = data.data.url
break;
}
}
}
});
}
};
// 重置图片
const reset = (e) => {
let type = e.currentTarget.dataset.type
if(type === 'card_z'){
cardZ.value = ''
}else{
cardF.value = ''
}
}
// 预览图片
const previewImg = (e) => {
let {url} = e.currentTarget.dataset
uni.previewImage({
current:url,
urls:idcardArr.value
})
}
</script>