ceshi.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <div class="saoma">
  3. <qrcode-stream
  4. @decode="onDecode"
  5. @init="onInit"
  6. style="height: 90vh; width: 100vw"
  7. >
  8. <div>
  9. <div class="qr-scanner">
  10. <div class="box">
  11. <div class="line"></div>
  12. <div class="angle"></div>
  13. </div>
  14. </div>
  15. </div>
  16. </qrcode-stream>
  17. </div>
  18. </template>
  19. <script>
  20. export default {
  21. data() {
  22. return {
  23. result: '', // 扫码结果信息
  24. error: '' // 错误信息
  25. }
  26. },
  27. methods: {
  28. onDecode(result) {
  29. if (result) {
  30. this.$router.push({
  31. path: '/',
  32. query: {
  33. code: result,
  34. }
  35. })
  36. }
  37. },
  38. async onInit(promise) {
  39. try {
  40. await promise
  41. } catch (error) {
  42. if (error.name === 'NotAllowedError') {
  43. window.alert('您需要授予相机访问权限')
  44. this.$router.push({ path: '/' })
  45. } else if (error.name === 'NotFoundError') {
  46. this.$router.push({ path: '/' })
  47. window.alert('这个设备上没有摄像头')
  48. } else if (error.name === 'NotSupportedError') {
  49. this.$router.push({ path: '/' })
  50. window.alert('所需的安全上下文(HTTPS、本地主机)')
  51. } else if (error.name === 'NotReadableError') {
  52. this.$router.push({ path: '/' })
  53. window.alert('相机被占用')
  54. } else if (error.name === 'OverconstrainedError') {
  55. this.$router.push({ path: '/' })
  56. window.alert('安装摄像头不合适')
  57. } else if (error.name === 'StreamApiNotSupportedError') {
  58. this.$router.push({ path: '/' })
  59. window.alert('此浏览器不支持流API')
  60. }
  61. }
  62. },
  63. }
  64. }
  65. </script>
  66. <style scoped>
  67. .saoma {
  68. width: 100vw;
  69. height: 100vh;
  70. }
  71. .qr-scanner {
  72. background-image: linear-gradient(
  73. 0deg,
  74. transparent 24%,
  75. rgba(32, 255, 77, 0.1) 25%,
  76. rgba(32, 255, 77, 0.1) 26%,
  77. transparent 27%,
  78. transparent 74%,
  79. rgba(32, 255, 77, 0.1) 75%,
  80. rgba(32, 255, 77, 0.1) 76%,
  81. transparent 77%,
  82. transparent
  83. ),
  84. linear-gradient(
  85. 90deg,
  86. transparent 24%,
  87. rgba(32, 255, 77, 0.1) 25%,
  88. rgba(32, 255, 77, 0.1) 26%,
  89. transparent 27%,
  90. transparent 74%,
  91. rgba(32, 255, 77, 0.1) 75%,
  92. rgba(32, 255, 77, 0.1) 76%,
  93. transparent 77%,
  94. transparent
  95. );
  96. background-size: 3rem 3rem;
  97. background-position: -1rem -1rem;
  98. width: 100%;
  99. /* height: 100%; */
  100. height: 100vh;
  101. position: relative;
  102. background-color: #1110;
  103. /* background-color: #111; */
  104. }
  105. .qr-scanner .box {
  106. width: 213px;
  107. height: 213px;
  108. position: absolute;
  109. left: 50%;
  110. top: 50%;
  111. transform: translate(-50%, -50%);
  112. overflow: hidden;
  113. border: 0.1rem solid rgba(0, 255, 51, 0.2);
  114. /* background: url('http://resource.beige.world/imgs/gongconghao.png') no-repeat center center; */
  115. }
  116. .qr-scanner .line {
  117. height: calc(100% - 2px);
  118. width: 100%;
  119. background: linear-gradient(180deg, rgba(0, 255, 51, 0) 43%, #00ff33 211%);
  120. border-bottom: 3px solid #00ff33;
  121. transform: translateY(-100%);
  122. animation: radar-beam 2s infinite alternate;
  123. animation-timing-function: cubic-bezier(0.53, 0, 0.43, 0.99);
  124. animation-delay: 1.4s;
  125. }
  126. .qr-scanner .box:after,
  127. .qr-scanner .box:before,
  128. .qr-scanner .angle:after,
  129. .qr-scanner .angle:before {
  130. content: "";
  131. display: block;
  132. position: absolute;
  133. width: 3vw;
  134. height: 3vw;
  135. border: 0.2rem solid transparent;
  136. }
  137. .qr-scanner .box:after,
  138. .qr-scanner .box:before {
  139. top: 0;
  140. border-top-color: #00ff33;
  141. }
  142. .qr-scanner .angle:after,
  143. .qr-scanner .angle:before {
  144. bottom: 0;
  145. border-bottom-color: #00ff33;
  146. }
  147. .qr-scanner .box:before,
  148. .qr-scanner .angle:before {
  149. left: 0;
  150. border-left-color: #00ff33;
  151. }
  152. .qr-scanner .box:after,
  153. .qr-scanner .angle:after {
  154. right: 0;
  155. border-right-color: #00ff33;
  156. }
  157. @keyframes radar-beam {
  158. 0% {
  159. transform: translateY(-100%);
  160. }
  161. 100% {
  162. transform: translateY(0);
  163. }
  164. }
  165. </style>