Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

viewfinder.vue 6.8KB

vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
vor 1 Jahr
vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
vor 1 Jahr
vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
vor 11 Monaten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <template>
  2. <view style="width: 100%;height: 100vh;position: fixed;left: 0;top:0;z-index: 111111;">
  3. <view class="viewfinder">
  4. <view v-if="phoneType == 1"
  5. style="display: flex;align-items: center;justify-content: flex-end;width: 100%;height: 100%;">
  6. <image :src="fileURL + 'image/index/etc_bd_ocr_id_card_locator_front.png'"
  7. style="height: 220rpx;margin-right: 30rpx;" mode="heightFix"></image>
  8. </view>
  9. <view v-if="phoneType == 2" style="margin: 30rpx 0 0 30rpx;">
  10. <image :src="fileURL + 'image/index/etc_bd_ocr_id_card_locator_back.png'" style="height: 160rpx;"
  11. mode="heightFix">
  12. </image>
  13. </view>
  14. <view v-if="phoneType == 3"
  15. style="margin: -30rpx 0 0 30rpx;display: flex;height: 100%;align-self: flex-end;flex-direction: column;justify-content: flex-end;">
  16. <view style="border: 1px solid #fff;height: 160rpx;width: 160rpx;">
  17. </view>
  18. </view>
  19. <view v-if="phoneType == 4"
  20. style="margin: -30rpx 30rpx 0 0;display: flex;height: 100%;justify-content: flex-end;align-items: flex-end;">
  21. <view style="border: 1px solid #fff;height: 60rpx;width: 300rpx;">
  22. </view>
  23. </view>
  24. </view>
  25. <!-- camera -->
  26. <camera v-if="showStartPhoto" id="camera" style="height: 70vh;width: 100vh;background-color: black;width: 100%;"
  27. mode="normal" :device-position="cameraPosition" :flash="flash" @stop="cameraStop" @error="cameraError" />
  28. <view v-if="!showStartPhoto" style="height: 70vh;background-color: black;">
  29. <image style="position: absolute;top: 20%;left: 10%;touch-action: none;" :src="srcImg"
  30. @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"
  31. :style="{ transform: `translate(${offsetX}px, ${offsetY}px) rotate(${rotateDegree}deg) scale(${scale})`, transition: 'transform ' + transitionDuration + 's' }">
  32. </image>
  33. </view>
  34. <view style="background-color: #A5A5A5;top: 60%;width: 100%;height: 40%;position: absolute;">
  35. <view style="display: flex;flex-direction: row;justify-content: center;align-items: center;height: 100%;">
  36. <view style="flex: 1;"></view>
  37. <image @click="camera" :src="fileURL + 'image/index/etc_bd_ocr_cancel.png'"
  38. style="width: 50rpx;height: 50rpx;"></image>
  39. <view style="flex: 1;"></view>
  40. <image @click="takePhoto" :src="fileURL + 'image/index/etc_bd_ocr_take_photo_normal.png'"
  41. :style="startPhoto ? 'width: 140rpx;height: 140rpx;' : 'width: 80rpx;height: 80rpx;'"></image>
  42. <view style="flex: 1;"></view>
  43. <image v-if="false" @click="success" :src="fileURL + 'image/index/etc_bd_ocr_confirm.png'"
  44. style="width: 50rpx;height: 50rpx;"></image>
  45. <view style="flex: 1;"></view>
  46. </view>
  47. </view>
  48. </view>
  49. </template>
  50. <script setup lang="ts">
  51. import {
  52. fileURL
  53. } from "@/datas/fileURL.js";
  54. import {
  55. ref
  56. } from 'vue'
  57. let prop = defineProps({
  58. phoneType: {
  59. type: Number,
  60. default: function () {
  61. return 3 //1 身份证正面 2 身份证反面 3 行驶证正面 4 行驶证反面
  62. }
  63. },
  64. showStartPhoto: {
  65. type: Boolean,
  66. default: function () {
  67. return true
  68. }
  69. },
  70. images: {
  71. type: String
  72. }
  73. });
  74. console.log('输出内容', prop.phoneType)
  75. const emit = defineEmits<{
  76. (e : "confirmReturn", content : any) : void;
  77. (e : "failReturn", content : any) : void;
  78. (e : "camera") : void;
  79. }>();
  80. let cameraPosition = 'back' // 'back'为后置摄像头,'front'为前置摄像头
  81. let flash = 'off' // 'off'为关闭闪光灯,'on'为打开闪光灯
  82. let scaleStep = 0.5 //每次缩放的最大增量
  83. let srcImg = ref(prop.images)
  84. let rotateDegree = ref(0)
  85. let touchStartDistance = ref(0)
  86. let touchMoveDistance = ref(0)
  87. let scale = ref(1)
  88. let transitionDuration = ref(0)
  89. const startX = ref(0);
  90. const startY = ref(0);
  91. const offsetX = ref(0);
  92. const offsetY = ref(0);
  93. const dragging = ref(false);
  94. const handleTouchStart = (event : TouchEvent) => {
  95. console.log('手柄触摸启动', '==1')
  96. if (event.touches.length === 1) {
  97. startX.value = event.changedTouches[0].pageX - offsetX.value;
  98. startY.value = event.changedTouches[0].pageY - offsetY.value;
  99. dragging.value = true;
  100. transitionDuration.value = 0.15
  101. } else if (event.touches.length === 2) {
  102. touchStartDistance.value = getTouchDistance(event.touches);
  103. transitionDuration.value = 0.5
  104. }
  105. };
  106. const handleTouchMove = (event : TouchEvent) => {
  107. console.log('手柄触摸启动', '==2')
  108. if (event.touches.length === 2) {
  109. touchMoveDistance.value = getTouchDistance(event.touches);
  110. updateScale();
  111. } else {
  112. if (dragging.value) {
  113. offsetX.value = event.changedTouches[0].pageX - startX.value;
  114. offsetY.value = event.changedTouches[0].pageY - startY.value;
  115. }
  116. }
  117. };
  118. function getTouchDistance(touches) {
  119. const x = touches[0].clientX - touches[1].clientX;
  120. const y = touches[0].clientY - touches[1].clientY;
  121. return Math.sqrt(x * x + y * y);
  122. }
  123. const handleTouchEnd = () => {
  124. console.log('手柄触摸启动', '==3')
  125. touchStartDistance.value = 0;
  126. touchMoveDistance.value = 0;
  127. dragging.value = false;
  128. };
  129. function updateScale() {
  130. // 计算缩放的增量
  131. const scales = (touchMoveDistance.value - touchStartDistance.value) * scaleStep;
  132. scale.value = Math.max(0.5, Math.min(scale.value + scales, 1)); // 设置缩放的范围,这里设置最小为1,最大为3
  133. }
  134. function takePhoto() {
  135. console.log('输出内容', rotateDegree.value)
  136. if (prop.showStartPhoto) {
  137. let cameraContext = null
  138. // #ifdef MP-WEIXIN
  139. cameraContext = uni.createCameraContext();
  140. // #endif
  141. // #ifdef MP-ALIPAY
  142. cameraContext = my.createCameraContext('camera');
  143. // #endif
  144. // 调用拍照方法
  145. cameraContext.takePhoto({
  146. quality: 'normal',
  147. success: (res) => {
  148. // 在这里处理拍照成功后的逻辑,res.tempImagePath 为拍照的图片路径
  149. console.log('拍照成功:', res.tempImagePath);
  150. srcImg.value = res.tempImagePath
  151. // showStartPhoto.value = false
  152. cameraContext.stopRecord();
  153. emit('confirmReturn', res)
  154. console.log("1111")
  155. },
  156. fail: (error) => {
  157. console.error('拍照失败:', error);
  158. emit('failReturn', error);
  159. },
  160. });
  161. } else {
  162. rotateDegree.value += 90
  163. }
  164. // console.log('输出内容', '===123')
  165. }
  166. //成功
  167. function success() {
  168. console.log('图片地址', srcImg.value);
  169. emit('confirmReturn', {
  170. tempImagePath: srcImg.value
  171. })
  172. }
  173. //重新拍摄
  174. function camera() {
  175. emit('camera')
  176. }
  177. function cameraStop() {
  178. // 相机停止时的回调
  179. console.log('相机已停止');
  180. }
  181. function cameraError(e) {
  182. // 相机出错时的回调
  183. console.error('相机错误:', e.detail.errMsg);
  184. }
  185. </script>
  186. <style>
  187. .viewfinder {
  188. pointer-events: none;
  189. position: absolute;
  190. top: 20%;
  191. left: 10%;
  192. width: 80%;
  193. height: 400rpx;
  194. border: 2px solid #fff;
  195. box-sizing: border-box;
  196. border-radius: 16rpx;
  197. z-index: 2;
  198. }
  199. </style>