Index3-9e732855.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import { d as defineComponent, r as ref, a as computed, b as createElementBlock, e as createBaseVNode, c as createVNode, f as withCtx, k as createBlock, B as unref, C as createCommentVNode, j as openBlock, s as createTextVNode, _ as _export_sfc } from "./index-5e4623ce.js";
  2. import { B as Button } from "./index-b1054607.js";
  3. import { s as showNotify, F as Fi, k as ki } from "./vue-qrcode-reader-d831402f.js";
  4. import { I as Icon } from "./index-487cde8c.js";
  5. import "./use-route-726f0d0b.js";
  6. import "./index-217c49a0.js";
  7. import "./mount-component-2b0f7b23.js";
  8. import "./use-scope-id-0b5b8615.js";
  9. import "./index-eef3af38.js";
  10. import "./on-popup-reopen-c5ca1603.js";
  11. const _hoisted_1 = {
  12. key: 0,
  13. style: { "height": "100vh", "width": "100vw", "display": "flex", "flex-direction": "column", "overflow": "hidden" }
  14. };
  15. const _hoisted_2 = { style: { "padding": "10px 16px", "line-height": "0", "align-items": "center", "display": "flex", "justify-content": "space-between" } };
  16. const _hoisted_3 = { style: { "flex-grow": "1", "border-top": "1px solid #eee", "box-sizing": "border-box" } };
  17. const _sfc_main = /* @__PURE__ */ defineComponent({
  18. __name: "Index3",
  19. emits: ["success"],
  20. setup(__props, { expose: __expose, emit: __emit }) {
  21. const visiable = ref(true);
  22. const open = () => {
  23. visiable.value = true;
  24. };
  25. const stop = () => {
  26. visiable.value = false;
  27. };
  28. const onClose = () => {
  29. stop();
  30. };
  31. const emit = __emit;
  32. const onScanPicture = () => {
  33. const inputNode = document.querySelector("input[name]");
  34. inputNode.click();
  35. console.log(inputNode);
  36. };
  37. const result = ref("");
  38. function onDetect(detectedCodes) {
  39. console.log(detectedCodes);
  40. result.value = JSON.stringify(detectedCodes.map((code) => code.rawValue));
  41. emit("success", result.value);
  42. stop();
  43. }
  44. const selectedConstraints = ref({ facingMode: "environment" });
  45. const defaultConstraintOptions = [
  46. { label: "rear camera", constraints: { facingMode: "environment" } },
  47. { label: "front camera", constraints: { facingMode: "user" } }
  48. ];
  49. const constraintOptions = ref(defaultConstraintOptions);
  50. async function onCameraReady() {
  51. const devices = await navigator.mediaDevices.enumerateDevices();
  52. const videoDevices = devices.filter(({ kind }) => kind === "videoinput");
  53. constraintOptions.value = [
  54. ...defaultConstraintOptions,
  55. ...videoDevices.map(({ deviceId, label }) => ({
  56. label: `${label} (ID: ${deviceId})`,
  57. constraints: { deviceId }
  58. }))
  59. ];
  60. error.value = "";
  61. }
  62. function paintOutline(detectedCodes, ctx) {
  63. for (const detectedCode of detectedCodes) {
  64. const [firstPoint, ...otherPoints] = detectedCode.cornerPoints;
  65. ctx.strokeStyle = "red";
  66. ctx.beginPath();
  67. ctx.moveTo(firstPoint.x, firstPoint.y);
  68. for (const { x, y } of otherPoints) {
  69. ctx.lineTo(x, y);
  70. }
  71. ctx.lineTo(firstPoint.x, firstPoint.y);
  72. ctx.closePath();
  73. ctx.stroke();
  74. }
  75. }
  76. function paintBoundingBox(detectedCodes, ctx) {
  77. for (const detectedCode of detectedCodes) {
  78. const {
  79. boundingBox: { x, y, width, height }
  80. } = detectedCode;
  81. ctx.lineWidth = 2;
  82. ctx.strokeStyle = "#007bff";
  83. ctx.strokeRect(x, y, width, height);
  84. }
  85. }
  86. function paintCenterText(detectedCodes, ctx) {
  87. for (const detectedCode of detectedCodes) {
  88. const { boundingBox, rawValue } = detectedCode;
  89. const centerX = boundingBox.x + boundingBox.width / 2;
  90. const centerY = boundingBox.y + boundingBox.height / 2;
  91. const fontSize = Math.max(12, 50 * boundingBox.width / ctx.canvas.width);
  92. ctx.font = `bold ${fontSize}px sans-serif`;
  93. ctx.textAlign = "center";
  94. ctx.lineWidth = 3;
  95. ctx.strokeStyle = "#35495e";
  96. ctx.strokeText(detectedCode.rawValue, centerX, centerY);
  97. ctx.fillStyle = "#5cb984";
  98. ctx.fillText(rawValue, centerX, centerY);
  99. }
  100. }
  101. const trackFunctionOptions = [
  102. { text: "nothing (default)", value: void 0 },
  103. { text: "outline", value: paintOutline },
  104. { text: "centered text", value: paintCenterText },
  105. { text: "bounding box", value: paintBoundingBox }
  106. ];
  107. const trackFunctionSelected = ref(trackFunctionOptions[1]);
  108. const barcodeFormats = ref({
  109. aztec: false,
  110. code_128: false,
  111. code_39: false,
  112. code_93: false,
  113. codabar: false,
  114. databar: false,
  115. databar_expanded: false,
  116. data_matrix: false,
  117. dx_film_edge: false,
  118. ean_13: false,
  119. ean_8: false,
  120. itf: false,
  121. maxi_code: false,
  122. micro_qr_code: false,
  123. pdf417: false,
  124. qr_code: true,
  125. rm_qr_code: false,
  126. upc_a: false,
  127. upc_e: false,
  128. linear_codes: false,
  129. matrix_codes: false
  130. });
  131. const selectedBarcodeFormats = computed(() => {
  132. return Object.keys(barcodeFormats.value).filter((format) => barcodeFormats.value[format]);
  133. });
  134. const error = ref("");
  135. function onError(err) {
  136. error.value = `[${err.name}]: `;
  137. if (err.name === "NotAllowedError") {
  138. error.value += "you need to grant camera access permission";
  139. } else if (err.name === "NotFoundError") {
  140. error.value += "no camera on this device";
  141. } else if (err.name === "NotSupportedError") {
  142. error.value += "secure context required (HTTPS, localhost)";
  143. } else if (err.name === "NotReadableError") {
  144. error.value += "is the camera already in use?";
  145. } else if (err.name === "OverconstrainedError") {
  146. error.value += "installed cameras are not suitable";
  147. } else if (err.name === "StreamApiNotSupportedError") {
  148. error.value += "Stream API is not supported in this browser";
  149. } else if (err.name === "InsecureContextError") {
  150. error.value += "Camera access is only permitted in secure context. Use HTTPS or localhost rather than HTTP.";
  151. } else {
  152. error.value += err.message;
  153. }
  154. showNotify({ type: "danger", message: error.value });
  155. }
  156. __expose({
  157. open,
  158. stop
  159. });
  160. return (_ctx, _cache) => {
  161. const _component_van_button = Button;
  162. const _component_van_icon = Icon;
  163. return visiable.value ? (openBlock(), createElementBlock("div", _hoisted_1, [
  164. createBaseVNode("div", _hoisted_2, [
  165. createBaseVNode("div", null, [
  166. createVNode(_component_van_button, {
  167. plain: "",
  168. icon: "photo-o",
  169. type: "primary",
  170. size: "small",
  171. onClick: onScanPicture
  172. }, {
  173. default: withCtx(() => _cache[0] || (_cache[0] = [
  174. createTextVNode("打开图片")
  175. ])),
  176. _: 1
  177. })
  178. ]),
  179. createBaseVNode("div", null, [
  180. createVNode(_component_van_icon, {
  181. name: "close",
  182. size: "30",
  183. onClick: onClose
  184. })
  185. ])
  186. ]),
  187. createBaseVNode("div", _hoisted_3, [
  188. visiable.value ? (openBlock(), createBlock(unref(Fi), {
  189. key: 0,
  190. onDetect,
  191. capture: null
  192. })) : createCommentVNode("", true),
  193. visiable.value ? (openBlock(), createBlock(unref(ki), {
  194. key: 1,
  195. constraints: selectedConstraints.value,
  196. track: trackFunctionSelected.value.value,
  197. formats: selectedBarcodeFormats.value,
  198. onError,
  199. onDetect,
  200. onCameraOn: onCameraReady
  201. }, null, 8, ["constraints", "track", "formats"])) : createCommentVNode("", true)
  202. ])
  203. ])) : createCommentVNode("", true);
  204. };
  205. }
  206. });
  207. const Index3_vue_vue_type_style_index_0_scoped_e6e53448_lang = "";
  208. const Index3 = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-e6e53448"]]);
  209. export {
  210. Index3 as default
  211. };