|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- <template>
- <view style="width: 100%;height: 100vh;position: fixed;left: 0;top:0;z-index: 111111;">
- <view ref="targetView" class="container viewfinder">
- <view v-if="phoneType == 1"
- style="display: flex;align-items: center;justify-content: flex-end;width: 100%;height: 100%;">
- <image :src="fileURL + 'image/index/etc_bd_ocr_id_card_locator_front.png'"
- style="height: 220rpx;margin-right: 30rpx;" mode="heightFix"></image>
- </view>
- <view v-if="phoneType == 2" style="margin: 30rpx 0 0 30rpx;">
- <image :src="fileURL + 'image/index/etc_bd_ocr_id_card_locator_back.png'" style="height: 160rpx;"
- mode="heightFix">
- </image>
- </view>
- <view v-if="phoneType == 3"
- style="margin: -30rpx 0 0 30rpx;display: flex;height: 100%;align-self: flex-end;flex-direction: column;justify-content: flex-end;">
- <view style="border: 1px solid #fff;height: 160rpx;width: 160rpx;">
-
- </view>
- </view>
- <view v-if="phoneType == 4"
- style="margin: -30rpx 30rpx 0 0;display: flex;height: 100%;justify-content: flex-end;align-items: flex-end;">
- <view style="border: 1px solid #fff;height: 60rpx;width: 300rpx;">
-
- </view>
- </view>
- <canvas canvas-id="canvasbg" id="canvasbg" style="width: 100%;height: 100%;"></canvas>
- </view>
- <!-- camera -->
- <camera v-if="startPhoto" id="camera" style="height: 70vh;width: 100vh;background-color: black;width: 100%;"
- mode="normal" :device-position="cameraPosition" :flash="flash" @stop="cameraStop" @error="cameraError" />
-
- <view v-if="!startPhoto" style="height: 70vh;background-color: black;">
- <canvas canvas-id="canvasId" id="canvasId" style="height: 100vh;width: 100vh;"
- @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"
- :style="{ transform: `translate(${offsetX}px, ${offsetY}px) rotate(${rotateDegree}deg) scale(${scale})`, transition: 'transform ' + transitionDuration + 's' }"></canvas>
- </view>
-
- <view style="background-color: #A5A5A5;top: 60%;width: 100%;height: 40%;position: absolute;">
- <view style="display: flex;flex-direction: row;justify-content: center;align-items: center;height: 100%;">
- <view style="flex: 1;"></view>
- <image @click="camera" :src="fileURL + 'image/index/etc_bd_ocr_cancel.png'"
- style="width: 50rpx;height: 50rpx;"></image>
- <view style="flex: 1;"></view>
- <image @click="takePhoto" :src="fileURL + 'image/index/etc_bd_ocr_take_photo_normal.png'"
- :style="startPhoto ? 'width: 140rpx;height: 140rpx;' : 'width: 80rpx;height: 80rpx;'"></image>
- <view style="flex: 1;"></view>
- <image v-if="false" @click="success" :src="fileURL + 'image/index/etc_bd_ocr_confirm.png'"
- style="width: 50rpx;height: 50rpx;"></image>
- <view style="flex: 1;"></view>
- </view>
- </view>
- </view>
- </template>
-
- <script setup lang="ts">
- import {
- ref,
- getCurrentInstance,
- onMounted,
- nextTick
- } from 'vue'
- import {
- fileURL
- } from "@/datas/fileURL.js";
- let prop = defineProps({
- phoneType: {
- type: Number,
- default: function () {
- return 3 //1 身份证正面 2 身份证反面 3 行驶证正面 4 行驶证反面
- }
- },
- showStartPhoto: {
- type: Boolean,
- default: function () {
- return true
- }
- },
- images: {
- type: String
- }
- });
-
- console.log('输出内容', prop.phoneType)
-
- const emit = defineEmits<{
- (e : "confirmReturn", content : any) : void;
- (e : "failReturn", content : any) : void;
- (e : "camera") : void;
- }>();
-
-
- let cameraPosition = 'back' // 'back'为后置摄像头,'front'为前置摄像头
- let flash = 'off' // 'off'为关闭闪光灯,'on'为打开闪光灯
- let scaleStep = 0.5 //每次缩放的最大增量
- let srcImg = ref(prop.images)
- let rotateDegree = ref(0)
- let touchStartDistance = ref(0)
- let touchMoveDistance = ref(0)
- let scale = ref(1)
- let transitionDuration = ref(0)
- let startPhoto = ref(prop.showStartPhoto)
- const startX = ref(0);
- const startY = ref(0);
- const offsetX = ref(0);
- const offsetY = ref(0);
- const dragging = ref(false);
- const canvasId = 'canvasId';
- const targetView = ref();
- const currentInstance = ref();
-
- onMounted(() => {
- currentInstance.value = getCurrentInstance()
- if (!prop.showStartPhoto) {
- emit('confirmReturn', { tempImagePath: prop.images })
- }
- })
-
- const handleTouchStart = (event : TouchEvent) => {
- console.log('手柄触摸启动', '==1')
- if (event.touches.length === 1) {
- startX.value = event.changedTouches[0].pageX - offsetX.value;
- startY.value = event.changedTouches[0].pageY - offsetY.value;
- dragging.value = true;
- transitionDuration.value = 0.15
- } else if (event.touches.length === 2) {
- touchStartDistance.value = getTouchDistance(event.touches);
- transitionDuration.value = 0.5
- }
- };
-
- const handleTouchMove = (event : TouchEvent) => {
- console.log('手柄触摸启动', '==2')
- if (event.touches.length === 2) {
- touchMoveDistance.value = getTouchDistance(event.touches);
- updateScale();
- } else {
- if (dragging.value) {
- offsetX.value = event.changedTouches[0].pageX - startX.value;
- offsetY.value = event.changedTouches[0].pageY - startY.value;
- }
- }
- };
-
- function getTouchDistance(touches) {
- const x = touches[0].clientX - touches[1].clientX;
- const y = touches[0].clientY - touches[1].clientY;
- return Math.sqrt(x * x + y * y);
- }
-
- const handleTouchEnd = () => {
- console.log('手柄触摸启动', '==3')
- touchStartDistance.value = 0;
- touchMoveDistance.value = 0;
- dragging.value = false;
- };
-
- function updateScale() {
- // 计算缩放的增量
- const scales = (touchMoveDistance.value - touchStartDistance.value) * scaleStep;
- scale.value = Math.max(0.5, Math.min(scale.value + scales, 1)); // 设置缩放的范围,这里设置最小为1,最大为3
- }
-
- function takePhoto() {
- uni.authorize({
- scope: 'scope.camera',
- complete(res) {
- console.log("res===",res)
- // 打开了拍照权限
- if(res.errMsg=="authorize:ok"){
- console.log('输出内容', rotateDegree.value)
- if (prop.showStartPhoto) {
- let cameraContext = null
- // #ifdef MP-WEIXIN
- cameraContext = uni.createCameraContext();
- // #endif
- // #ifdef MP-ALIPAY
- cameraContext = uni.createCameraContext('camera');
- // #endif
- // 调用拍照方法
- cameraContext.takePhoto({
- quality: 'normal',
- success: (res : any) => {
- // 在这里处理拍照成功后的逻辑,res.tempImagePath 为拍照的图片路径
- // srcImg.value = res.tempImagePath
- startPhoto.value = false
- cameraContext.stopRecord();
- emit('confirmReturn', res)
- // getViewPosition(res.tempImagePath)
- return
- // console.log('拍照成功:', res.tempImagePath);
- },
- fail: (error) => {
- console.error('拍照失败:', error);
- emit('failReturn', error);
- },
- });
- } else {
- rotateDegree.value += 90
- }
- }else{
- uni.showModal({
- title: '提示',
- content: '请打开摄像头权限',
- success: function (res) {
- if (res.confirm) {
- uni.openSetting({
- success(res) {
- console.log("2222")
- console.log(res.authSetting)
- }
- });
- } else if (res.cancel) {
- console.log('用户点击取消');
- }
- }
- });
- }
- }
- })
-
-
- // console.log('输出内容', '===123')
-
- }
-
- const getViewPosition = (src : any) => {
- const context = uni.createCanvasContext(canvasId, currentInstance.value)
- const query = uni.createSelectorQuery().in(currentInstance.value)
- // query.in(this)
- query.select('.container').boundingClientRect((rect : any) => {
- if (rect) {
- uni.getSystemInfo({
- success: (res) => {
- console.log(res, '===============', res.windowHeight, res.windowWidth)
- // 获取图片信息
- uni.getImageInfo({
- src: src,
- success: (imgS) => {
- //((res.windowHeight - res.statusBarHeight) * 0.33)
- console.log('====', rect, '输出内容======', imgS.width, imgS.height) //140 1.8(res.windowHeight * 0.23)
- // canvas.drawImage(img, 起始 x 坐标, 起始 y 坐标, 宽度, 高度, 绘制到 Canvas 的起始 x 坐标, 绘制到 Canvas 的起始 y 坐标, 裁剪后的宽度, 裁剪后的高度);
- context.drawImage(src, imgS.width * 0.1, imgS.height * 0.3, rect.width * 2.2, rect.height * 2.2, rect.left, rect.top, rect.width, rect.height);
- context.draw(false, () => {
- uni.canvasToTempFilePath({
- canvasId: canvasId,
- x: rect.left,
- y: rect.top,
- width: rect.width,
- height: rect.height,
- destWidth: rect.width,
- destHeight: rect.height,
- success(res : any) {
- // res.tempFilePath 是转换后的图片路径
- res.tempImagePath = res.tempFilePath
- emit('confirmReturn', res)
- },
- fail(err) {
- console.error('canvasToTempFilePath failed', err);
- }
- }, currentInstance.value)
- });
- },
- fail: (error) => {
- console.error('获取图片信息失败', error);
- },
- });
- }
- })
-
-
-
-
- //把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。在自定义组件下,第二个参数传入自定义组件实例,以操作组件内 <canvas> 组件。
- console.log('视图的位置信息:', rect);
- console.log('视图的 x 坐标:', rect.left);
- console.log('视图的 y 坐标:', rect.top);
- console.log('视图的宽度:', rect.width);
- console.log('视图的高度:', rect.height);
- }
- }).exec();
- };
-
- //成功
- function success() {
-
- }
-
- //获取节点信息
- function boundingClientRect(fun : any) {
- const query = uni.createSelectorQuery().in(currentInstance.value)
- query.select('.container').boundingClientRect((rect : any) => {
- if (rect) {
- //把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。在自定义组件下,第二个参数传入自定义组件实例,以操作组件内 <canvas> 组件。
- console.log('视图的位置信息:', rect);
- console.log('视图的 x 坐标:', rect.left);
- console.log('视图的 y 坐标:', rect.top);
- console.log('视图的宽度:', rect.width);
- console.log('视图的高度:', rect.height);
- fun(rect)
- }
- }).exec();
- }
-
- //重新拍摄
- function camera() {
- emit('camera')
- }
-
- function cameraStop() {
- // 相机停止时的回调
- console.log('相机已停止');
- }
-
- function cameraError(e) {
- // 相机出错时的回调
- console.error('相机错误:', e.detail.errMsg);
- }
- </script>
-
- <style>
- .viewfinder {
- pointer-events: none;
- position: absolute;
- top: 180px;
- left: 40px;
- width: 80%;
- height: 200px;
- border: 2px solid #fff;
- box-sizing: border-box;
- border-radius: 16rpx;
- z-index: 2;
- }
- </style>
|