daShangDao_scanBook/pages/upload/camera_capture.nvue

354 lines
8.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="cc-page">
<!-- 正方形相机预览 -->
<view class="cc-camera-box" :style="'width:' + camSize + 'px;height:' + camSize + 'px;'">
<ima-camera-view
ref="cameraRef"
style="width:100%;height:100%;"
flash="off"
facing="back"
:widthRatio="1"
:heightRatio="1"
@onPictureTaken="onPictureTaken"
@onCameraOpened="onCameraOpened"
></ima-camera-view>
</view>
<!-- ═══ 顶部栏 ═══ -->
<view class="cc-topbar">
<view class="cc-topbar-left">
<view class="cc-topbar-back" @click="goBack">
<text class="cc-back-icon">✕</text>
</view>
</view>
<view class="cc-topbar-center">
<text class="cc-topbar-title">{{ capturedList.length > 0 ? '已拍 ' + capturedList.length + '/9' : '拍照' }}</text>
</view>
<view class="cc-topbar-right">
<!-- 翻转按钮移到了右上角 -->
<view class="cc-flip-btn" @click="flipCamera">
<text class="cc-flip-icon">↺</text>
<text class="cc-flip-label">翻转</text>
</view>
</view>
</view>
<!-- ═══ 底部操作栏 ═══ -->
<view class="cc-footer">
<!-- 左侧:缩略图预览 -->
<view class="cc-footer-left">
<view class="cc-thumb-preview" v-if="capturedList.length > 0" @click="confirmCapture">
<image class="cc-thumb-last" :src="capturedList[capturedList.length-1]" mode="aspectFill"></image>
<text class="cc-thumb-badge">{{ capturedList.length }}</text>
</view>
</view>
<!-- 中间:拍照按钮(放大) -->
<view class="cc-footer-center">
<view class="cc-capture-outer">
<view class="cc-capture-btn" @click="capturePhoto"></view>
</view>
</view>
<!-- 右侧:完成按钮(拍完显示) -->
<view class="cc-footer-right">
<text class="cc-confirm-btn" @click="confirmCapture" v-if="capturedList.length > 0">完成</text>
</view>
</view>
<!-- ═══ 缩略图横条超过1张时 ═══ -->
<view class="cc-thumb-bar" v-if="capturedList.length > 1">
<scroll-view scroll-x="true" show-scrollbar="false" style="flex-direction:row;">
<view style="flex-direction:row;">
<view class="cc-thumb-item" v-for="(img, idx) in capturedList" :key="idx">
<image class="cc-thumb-img" :src="img" mode="aspectFill"></image>
<view class="cc-thumb-del" @click.stop="deletePhoto(idx)">
<text class="cc-del-icon">✕</text>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
capturedList: [],
cameraReady: false,
facing: 'back',
camSize: 750
}
},
onLoad() {
var that = this
uni.getSystemInfo({
success: function(res) {
that.camSize = res.windowWidth
}
})
},
methods: {
onCameraOpened() {
this.cameraReady = true
console.log('相机已就绪')
},
capturePhoto() {
if (this.capturedList.length >= 9) {
uni.showToast({ title: '最多拍9张', icon: 'none' })
return
}
if (!this.cameraReady) {
uni.showToast({ title: '相机未就绪', icon: 'none' })
return
}
this.$refs.cameraRef.takePhoto()
},
onPictureTaken(e) {
var path = ''
if (e.detail) {
path = e.detail.path || ''
}
if (path) {
this.capturedList.push(path)
}
},
flipCamera() {
this.facing = this.facing === 'back' ? 'front' : 'back'
this.$refs.cameraRef.changeFacing(this.facing)
},
deletePhoto(idx) {
this.capturedList.splice(idx, 1)
},
goBack() {
if (this.capturedList.length > 0) {
uni.showModal({
title: '提示',
content: '确定退出拍照?已拍照片将丢失',
success: function(res) {
if (res.confirm) { uni.navigateBack() }
}
})
} else {
uni.navigateBack()
}
},
confirmCapture() {
if (this.capturedList.length === 0) {
uni.showToast({ title: '请先拍照', icon: 'none' })
return
}
var pages = getCurrentPages()
var prevPage = pages[pages.length - 2]
if (prevPage) {
prevPage.$vm.capturedPhotoList = this.capturedList
}
uni.navigateBack()
}
}
}
</script>
<style>
.cc-page {
flex: 1;
background-color: #000000;
align-items: center;
}
/* 正方形相机区域,居中显示 */
.cc-camera-box {
margin-top: 110px;
background-color: #111111;
}
/* ═══ 顶部栏 ═══ */
.cc-topbar {
position: absolute;
top: 0; left: 0; right: 0;
height: 110px;
padding-top: 50px;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding-left: 24rpx;
padding-right: 24rpx;
z-index: 8;
background: linear-gradient(to bottom, rgba(0,0,0,0.5), transparent);
}
.cc-topbar-left {
width: 90rpx;
}
.cc-topbar-back {
width: 60rpx; height: 60rpx;
border-radius: 60rpx;
background-color: rgba(0,0,0,0.35);
align-items: center; justify-content: center;
}
.cc-back-icon {
color: #ffffff;
font-size: 34rpx;
line-height: 60rpx;
text-align: center;
}
.cc-topbar-center {
flex: 1;
align-items: center;
}
.cc-topbar-title {
color: #ffffff;
font-size: 32rpx;
font-weight: 500;
}
.cc-topbar-right {
width: 120rpx;
align-items: flex-end;
}
/* 翻转按钮(在右上角) */
.cc-flip-btn {
width: 80rpx; height: 64rpx;
border-radius: 32rpx;
border-width: 2rpx;
border-color: rgba(255,255,255,0.3);
border-style: solid;
align-items: center; justify-content: center;
background-color: rgba(0,0,0,0.25);
}
.cc-flip-icon {
color: #ffffff;
font-size: 30rpx;
line-height: 36rpx;
text-align: center;
}
.cc-flip-label {
color: rgba(255,255,255,0.7);
font-size: 18rpx;
line-height: 22rpx;
text-align: center;
}
/* ═══ 底部操作栏 ═══ */
.cc-footer {
position: absolute;
bottom: 0; left: 0; right: 0;
height: 240rpx;
padding-bottom: 40rpx;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding-left: 40rpx;
padding-right: 40rpx;
z-index: 8;
background: linear-gradient(to top, rgba(0,0,0,0.6), transparent);
}
.cc-footer-left {
width: 120rpx;
align-items: flex-start;
}
.cc-footer-center {
flex: 1;
align-items: center;
justify-content: center;
}
.cc-footer-right {
width: 120rpx;
align-items: flex-end;
}
/* 拍照按钮(放大) */
.cc-capture-outer {
width: 100rpx; height: 100rpx;
border-radius: 100rpx;
border-width: 4rpx;
border-color: rgba(255,255,255,0.6);
border-style: solid;
align-items: center; justify-content: center;
}
.cc-capture-btn {
width: 88rpx; height: 88rpx;
border-radius: 88rpx;
background-color: #ffffff;
}
.cc-capture-btn:active {
background-color: #dddddd;
}
/* 完成按钮(在底部右侧) */
.cc-confirm-btn {
color: #ffffff;
font-size: 30rpx;
font-weight: bold;
padding-left: 30rpx; padding-right: 30rpx;
padding-top: 14rpx; padding-bottom: 14rpx;
border-radius: 40rpx;
background-color: #409eff;
}
/* 缩略图预览(最新一张) */
.cc-thumb-preview {
width: 80rpx; height: 80rpx;
border-radius: 10rpx;
overflow: hidden;
position: relative;
border-width: 2rpx;
border-color: rgba(255,255,255,0.3);
border-style: solid;
}
.cc-thumb-last {
width: 80rpx; height: 80rpx;
}
.cc-thumb-badge {
position: absolute;
top: -6rpx; right: -6rpx;
min-width: 30rpx; height: 30rpx;
border-radius: 30rpx;
background-color: #409eff;
color: #ffffff;
font-size: 20rpx;
text-align: center;
line-height: 30rpx;
padding-left: 4rpx; padding-right: 4rpx;
}
/* 缩略图横条 */
.cc-thumb-bar {
position: absolute;
bottom: 260rpx; left: 0; right: 0;
padding-left: 24rpx; padding-right: 24rpx;
padding-top: 14rpx; padding-bottom: 14rpx;
z-index: 8;
}
.cc-thumb-item {
width: 120rpx; height: 120rpx;
border-radius: 10rpx;
overflow: hidden;
position: relative;
border-width: 2rpx;
border-color: rgba(255,255,255,0.3);
border-style: solid;
margin-right: 16rpx;
background-color: #333333;
}
.cc-thumb-img {
width: 120rpx; height: 120rpx;
}
.cc-thumb-del {
position: absolute;
top: -8rpx; right: -8rpx;
width: 40rpx; height: 40rpx;
border-radius: 40rpx;
background-color: rgba(0,0,0,0.55);
align-items: center; justify-content: center;
border-width: 2rpx;
border-color: rgba(255,255,255,0.3);
border-style: solid;
}
.cc-del-icon {
color: #ffffff;
font-size: 22rpx;
}
</style>