邃芒智像大屏项目
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

874 řádky
22 KiB

  1. <template>
  2. <div class="page">
  3. <div class="bottom">
  4. <video
  5. v-if="!isSuccess"
  6. id="video"
  7. muted
  8. autoplay="autoplay"
  9. :controls="false"
  10. :enable-progress-gesture="false"
  11. ></video>
  12. <div v-if="!isSuccess">
  13. <div class="selectImg" @click="uploadImg">
  14. <img src="../../assets/img/selectImg.png" />
  15. <div class="uploadText">上传照片</div>
  16. </div>
  17. <div id="action" @click="takePicture">
  18. <div class="circleInside"></div>
  19. </div>
  20. </div>
  21. <div v-if="isSuccess">
  22. <div class="selectImg" @click="uploadImg">
  23. <img src="../../assets/img/selectImg.png" />
  24. <div class="uploadText">上传照片</div>
  25. </div>
  26. <div class="confirm" @click="confirmPhoto">
  27. <!-- <img src="../../assets/img/success.png" /> -->
  28. <div class="sure">确定</div>
  29. <div class="uploadText">
  30. 就这张了 <img src="../../assets/img/success.png" />
  31. </div>
  32. </div>
  33. <div class="reTry" @click="reTry">
  34. <img src="../../assets/img/reTry.png" />
  35. <div class="uploadText">重新拍摄</div>
  36. </div>
  37. </div>
  38. <canvas
  39. v-if="isShowCanvas"
  40. id="canvas"
  41. style="width: 1530; height: 950"
  42. ></canvas>
  43. <div v-if="isSuccess" class="preview">
  44. <img v-if="!isUpload" class="fromCamera" :src="CimgSrc" />
  45. <img v-if="isUpload" class="fromUpload" :src="UimgSrc" />
  46. </div>
  47. </div>
  48. <div class="top">
  49. <div class="example">
  50. <img src="../../assets/img/c867236efb4fc5707257ef8daf26db4.png" />
  51. </div>
  52. <div class="model" @click="goSelectModel">
  53. <img :src="modelUrl" alt="" />
  54. <div class="reSelect">点击重新选择模板</div>
  55. </div>
  56. </div>
  57. <!-- Top section -->
  58. <u-overlay class="overlay" :show="showQrCode" opacity="0.9">
  59. <view class="content">
  60. <view class="imageBox">
  61. <image :src="QRCodeUrl" mode="scaleToFill" />
  62. </view>
  63. <text>打开微信扫码上传照片</text>
  64. <view class="orangeBtn" style="margin-top: 100rpx" @click="cancelUplaod"
  65. >取&nbsp;消</view
  66. >
  67. </view>
  68. </u-overlay>
  69. </div>
  70. </template>
  71. <script setup>
  72. import { ref, onMounted } from "vue";
  73. import { BASE_URL } from "../../utils/request";
  74. import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
  75. import { getImageQrcode, findImage } from "../../api/camera.js";
  76. let CimgSrc = ref(""); // 相机拍照的图片路径,上传前需校验
  77. let CimgSrcYASUO = ref(""); // 压缩后的图片
  78. let UimgSrc = ref(""); // 用户上传的图片路径,上传无需校验
  79. let isSuccess = ref(false);
  80. let isShowCanvas = ref(true);
  81. let isUpload = ref(false);
  82. let modelUrl = ref("");
  83. let modelId = ref("");
  84. let modelMouldType = ref("");
  85. let QRCodeUrl = ref("");
  86. let showQrCode = ref(false);
  87. let timer = ref(null);
  88. const getView = () => {
  89. uni.getSystemInfo({
  90. success: (res) => {
  91. const viewportWidth = res.windowWidth; // 视口宽度
  92. const viewportHeight = res.windowHeight; // 视口高度
  93. alert(viewportWidth);
  94. alert(viewportHeight);
  95. },
  96. });
  97. };
  98. const startCamera = () => {
  99. function getUserMedia(constraints, success, error) {
  100. if (navigator.mediaDevices.getUserMedia) {
  101. //最新的标准API
  102. navigator.mediaDevices
  103. .getUserMedia({
  104. audio: false,
  105. video: {
  106. facingMode: "user",
  107. // width: 1000,
  108. // height: 1000,
  109. width: 1080,
  110. height: 1305,
  111. // width: 2100,
  112. // height: 2100,
  113. },
  114. })
  115. .then(success)
  116. .catch(error);
  117. } else if (navigator.webkitGetUserMedia) {
  118. //webkit核心浏览器
  119. navigator.webkitGetUserMedia(constraints, success, error);
  120. } else if (navigator.mozGetUserMedia) {
  121. //firfox浏览器
  122. navigator.mozGetUserMedia(constraints, success, error);
  123. } else if (navigator.getUserMedia) {
  124. //旧版API
  125. navigator.getUserMedia(constraints, success, error);
  126. }
  127. }
  128. const video = document.querySelector("video.uni-video-video");
  129. let canvas = document.querySelector("canvas.uni-canvas-canvas");
  130. const action = document.querySelector("#action");
  131. let context = canvas.getContext("2d");
  132. function success(stream) {
  133. //兼容webkit核心浏览器
  134. let CompatibleURL = window.URL || window.webkitURL;
  135. //将视频流设置为video元素的源
  136. console.log(stream);
  137. //video.src = CompatibleURL.createObjectURL(stream);
  138. video.srcObject = stream;
  139. video.play();
  140. }
  141. function error(error) {
  142. console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
  143. }
  144. if (
  145. navigator.mediaDevices.getUserMedia ||
  146. navigator.getUserMedia ||
  147. navigator.webkitGetUserMedia ||
  148. navigator.mozGetUserMedia
  149. ) {
  150. //调用用户媒体设备, 访问摄像头
  151. getUserMedia(
  152. {
  153. audio: false,
  154. video: {
  155. facingMode: "user",
  156. // width: 240,
  157. // height: 450,
  158. width: 1080,
  159. height: 1305,
  160. // width: 2100,
  161. // height: 2100,
  162. },
  163. },
  164. success,
  165. error
  166. );
  167. } else {
  168. alert("不支持访问用户媒体");
  169. }
  170. action.addEventListener("click", function () {
  171. uni.showToast({
  172. title: "准备好了吗?",
  173. icon: "success",
  174. });
  175. setTimeout(() => {
  176. let i = 3;
  177. const timer = setInterval(() => {
  178. uni.showLoading({
  179. title: i,
  180. });
  181. i--;
  182. console.log(i);
  183. if (i == 0) {
  184. clearInterval(timer);
  185. setTimeout(async () => {
  186. uni.hideLoading();
  187. // canvas.width = 1530;
  188. // canvas.height = 950;
  189. canvas.width = 1500;
  190. canvas.height = 1500;
  191. context.drawImage(video, 0, 0);
  192. let dataURL = canvas.toDataURL("image/png");
  193. console.log(dataURL);
  194. CimgSrc.value = dataURL;
  195. UimgSrc.value = "";
  196. setTimeout(() => {
  197. isShowCanvas.value = false;
  198. isSuccess.value = true;
  199. }, 10);
  200. }, 1000);
  201. }
  202. }, 1100);
  203. }, 1000);
  204. });
  205. // 备用方案
  206. // action.addEventListener("click", function () {
  207. // context.drawImage(video, -50, -50, 310, 220);
  208. // const dataURL = canvas.toDataURL("image/png");
  209. // imgSrc.value = dataURL;
  210. // setTimeout(() => {
  211. // isShowCanvas.value = false;
  212. // isSuccess.value = true;
  213. // }, 10);
  214. // console.log(dataURL);
  215. // });
  216. };
  217. //压缩图片
  218. function compressBase64Image(base64String, maxWidth, maxHeight) {
  219. return new Promise((resolve, reject) => {
  220. const img = new Image();
  221. img.src = base64String;
  222. img.onload = function () {
  223. const canvas = document.createElement("canvas");
  224. let width = img.width;
  225. let height = img.height;
  226. if (width > maxWidth) {
  227. height *= maxWidth / width;
  228. width = maxWidth;
  229. }
  230. if (height > maxHeight) {
  231. width *= maxHeight / height;
  232. height = maxHeight;
  233. }
  234. const ctx = canvas.getContext("2d");
  235. canvas.width = width;
  236. canvas.height = height;
  237. ctx.drawImage(img, 0, 0, width, height);
  238. const compressedBase64 = canvas.toDataURL("image/jpeg");
  239. resolve(compressedBase64);
  240. };
  241. img.onerror = function (error) {
  242. reject(error);
  243. };
  244. });
  245. }
  246. const takePicture = () => {
  247. console.log("Take Picture !");
  248. };
  249. const goSelectModel = () => {
  250. uni.navigateTo({
  251. url: `/pages/chooseStyle/index`,
  252. });
  253. };
  254. // 确认照片
  255. const confirmPhoto = () => {
  256. // alert("点击确定");
  257. // alert(UimgSrc.value, "UimgSrc.value");
  258. // alert(CimgSrc.value, "CimgSrc.value");
  259. try {
  260. if (UimgSrc.value) {
  261. uni.navigateTo({
  262. url: `/pages/createing/index?imageUrl=${UimgSrc.value}&id=${modelId.value}`,
  263. });
  264. } else if (CimgSrc.value) {
  265. // 本地存储中的拍照照片
  266. // alert(uni.getStorageSync("CcurrentUrl"), "CcurrentUrl");
  267. // // let CimageUrl = uni.getStorageSync("CcurrentUrl");
  268. // // 用户上一次使用相机拍照的照片,从本地回显,已通过校验,直接放行
  269. if (uni.getStorageSync("CcurrentUrl")) {
  270. uni.navigateTo({
  271. url: `/pages/createing/index?imageUrl=${CimgSrc.value}&id=${modelId.value}`,
  272. });
  273. // // 用户使用相机拍照的照片,未校验,走完校验流程放行
  274. } else {
  275. dealImage(CimgSrc.value);
  276. }
  277. // dealImage(CimgSrcYASUO.value);
  278. }
  279. } catch (e) {
  280. uni.showToast({
  281. title: e,
  282. icon: "success",
  283. mask: true,
  284. });
  285. }
  286. // 用户上传的照片,已通过校验,直接放行
  287. };
  288. const dealImage = async (imageUrl) => {
  289. try {
  290. uni.showLoading({
  291. title: "上传中,马上就好",
  292. });
  293. await compressBase64Image(imageUrl, 1200, 1200)
  294. .then((compressedBase64) => {
  295. CimgSrcYASUO.value = compressedBase64;
  296. })
  297. .catch((error) => {
  298. console.error("压缩失败", error);
  299. });
  300. // 将二进制数据转换为 Blob 对象
  301. // let blob = await dataURLtoBlob(imageUrl);
  302. // checkImageByBaidu(blob);
  303. // let blob = await dataURLtoBlob(imageUrl);
  304. // console.log(dataURLtoBlob(imageUrl));
  305. checkImageByBaidu(dataURLtoBlob(CimgSrcYASUO.value));
  306. } catch (error) {
  307. console.error("压缩失败", error);
  308. }
  309. };
  310. /**
  311. * Base64字符串转二进制流
  312. * @param {String} dataurl Base64字符串(字符串包含Data URI scheme,例如:data:image/png;base64, )
  313. */
  314. const dataURLtoBlob = (dataurl) => {
  315. var arr = dataurl.split(","),
  316. mime = arr[0].match(/:(.*?);/)[1],
  317. bstr = atob(arr[1]),
  318. n = bstr.length,
  319. u8arr = new Uint8Array(n);
  320. while (n--) {
  321. u8arr[n] = bstr.charCodeAt(n);
  322. }
  323. return new Blob([u8arr], {
  324. type: mime,
  325. });
  326. };
  327. // 百度图片校验
  328. const checkImageByBaidu = async (file) => {
  329. try {
  330. uni.showLoading({
  331. title: "正在检测图片合法性 1/3",
  332. });
  333. uni.uploadFile({
  334. url: BASE_URL + "api/baidu/checkPhoto",
  335. file,
  336. header: {
  337. authorization: uni.getStorageSync("token"),
  338. },
  339. timeout: 30000,
  340. // formData: data,
  341. success: (res) => {
  342. console.log(res, "上传成功");
  343. const data = JSON.parse(res.data);
  344. if (data.code == 200) {
  345. uni.hideLoading();
  346. checkImageByMetavatar(file);
  347. } else {
  348. uni.hideLoading();
  349. uni.showToast({
  350. title: "图片不合规哦,请更换一张",
  351. icon: "error",
  352. });
  353. }
  354. },
  355. fail: (res) => {
  356. uni.hideLoading();
  357. uni.showToast({
  358. title: "上传失败,请稍后再试",
  359. icon: "none",
  360. });
  361. console.log(res, "上传失败");
  362. },
  363. });
  364. } catch (error) {
  365. uni.hideLoading();
  366. uni.showToast({
  367. title: "请求失败,请稍后再试",
  368. icon: "none",
  369. });
  370. }
  371. };
  372. // 邃芒人脸校验
  373. const checkImageByMetavatar = async (file) => {
  374. uni.showLoading({
  375. title: "正在检测人脸位置 2/3",
  376. });
  377. uni.uploadFile({
  378. url: BASE_URL + "api/userDigital/checkPhoto",
  379. file,
  380. header: {
  381. authorization: uni.getStorageSync("token"),
  382. },
  383. timeout: 30000,
  384. // formData: data,
  385. success: (res) => {
  386. console.log(res, "上传成功");
  387. const data = JSON.parse(res.data);
  388. if (data.code == 200) {
  389. uni.hideLoading();
  390. uoloadImageAws(file);
  391. } else {
  392. uni.hideLoading();
  393. uni.showToast({
  394. title: "请参考提示区域调整站位哦",
  395. icon: "error",
  396. });
  397. }
  398. },
  399. fail: (res) => {
  400. uni.hideLoading();
  401. uni.showToast({
  402. title: "上传失败,请稍后再试",
  403. icon: "none",
  404. });
  405. console.log(res, "上传失败");
  406. },
  407. });
  408. };
  409. // 上传图片到服务器(两步校验通过后)
  410. const uoloadImageAws = async (file) => {
  411. uni.showLoading({
  412. title: "检测完成,上传中 3/3",
  413. });
  414. uni.uploadFile({
  415. url: BASE_URL + "api/upload/awsImgUpload",
  416. file,
  417. header: {
  418. authorization: uni.getStorageSync("token"),
  419. },
  420. timeout: 30000,
  421. // formData: data,
  422. success: (res) => {
  423. console.log(res, "上传成功");
  424. uni.hideLoading();
  425. const data = JSON.parse(res.data);
  426. if (data.code == 200) {
  427. uni.showToast({
  428. title: "上传成功!",
  429. icon: "success",
  430. duration: 1500,
  431. });
  432. setTimeout(() => {
  433. // 将拍照照片地址存储到本地并清空上传照片地址
  434. // uni.setStorageSync("CcurrentUrl", data.data.url);
  435. uni.setStorageSync("CcurrentUrl", data.data.url);
  436. uni.setStorageSync("UcurrentUrl", null);
  437. uni.navigateTo({
  438. url: `/pages/createing/index?imageUrl=${data.data.url}&id=${modelId.value}`,
  439. });
  440. }, 1000);
  441. } else {
  442. uni.hideLoading();
  443. uni.showToast({
  444. title: "网络波动,请稍后再试",
  445. icon: "error",
  446. });
  447. }
  448. },
  449. fail: (res) => {
  450. uni.hideLoading();
  451. uni.showToast({
  452. title: "上传失败,请稍后再试",
  453. icon: "none",
  454. });
  455. console.log(res, "上传失败");
  456. },
  457. });
  458. };
  459. // 不满意,重新拍一张
  460. const reTry = () => {
  461. isSuccess.value = false;
  462. isUpload.value = false;
  463. isShowCanvas.value = true;
  464. CimgSrc.value = "";
  465. UimgSrc.value = "";
  466. CimgSrcYASUO.value = "";
  467. uni.setStorageSync("CcurrentUrl", null);
  468. setTimeout(() => {
  469. startCamera();
  470. }, 10);
  471. };
  472. // 点击上传照片按钮
  473. const uploadImg = async () => {
  474. const data = {
  475. machineQrcodeId: localStorage.getItem("UserId"),
  476. mouldType: modelMouldType.value,
  477. };
  478. // const UserId = localStorage.getItem("UserId");
  479. // const mouldType = modelMouldType.value;
  480. try {
  481. const res = await getImageQrcode(data);
  482. QRCodeUrl.value = res.data.wxQrcode;
  483. showQrCode.value = true;
  484. // 成功展示二维码之后,轮询获取上传照片状态
  485. timer.value = setInterval(() => {
  486. refreshUploadStatus(res.data.id);
  487. }, 1000);
  488. console.log(res, "res");
  489. } catch (error) {
  490. console.log(error, "error");
  491. }
  492. };
  493. // 刷新状态,直到返回用户上传的图片url
  494. const refreshUploadStatus = async (id) => {
  495. try {
  496. const res = await findImage(id);
  497. console.log(res, "res");
  498. if (res.data.imageList && res.data.imageList.length) {
  499. const imageUrl = res.data.imageList[0];
  500. clearInterval(timer.value);
  501. uni.showToast({
  502. title: "上传成功!",
  503. icon: "success",
  504. });
  505. showQrCode.value = false;
  506. UimgSrc.value = imageUrl;
  507. CimgSrc.value = "";
  508. CimgSrcYASUO.value = "";
  509. isShowCanvas.value = false;
  510. isSuccess.value = true;
  511. isUpload.value = true;
  512. // 将上传照片地址存储到本地并清空拍照照片地址
  513. uni.setStorageSync("CcurrentUrl", null);
  514. uni.setStorageSync("UcurrentUrl", UimgSrc.value);
  515. }
  516. } catch (error) {
  517. console.log(error, "error");
  518. }
  519. };
  520. // 点击取消,关闭二维码弹窗并取消轮询
  521. const cancelUplaod = () => {
  522. showQrCode.value = false;
  523. clearInterval(timer.value);
  524. };
  525. onLoad((options) => {
  526. console.log(options, "options");
  527. modelUrl.value = options.modelUrl;
  528. modelId.value = options.id;
  529. modelMouldType.value = options.mouldType;
  530. });
  531. onMounted(() => {
  532. clearInterval(timer.value);
  533. startCamera();
  534. const CimageUrl = uni.getStorageSync("CcurrentUrl");
  535. const UimageUrl = uni.getStorageSync("UcurrentUrl");
  536. if (CimageUrl || UimageUrl) {
  537. setTimeout(async () => {
  538. showQrCode.value = false;
  539. if (CimageUrl) {
  540. UimgSrc.value = "";
  541. CimgSrc.value = CimageUrl;
  542. isUpload.value = false;
  543. } else if (UimageUrl) {
  544. UimgSrc.value = UimageUrl;
  545. CimgSrc.value = "";
  546. CimgSrcYASUO.value = "";
  547. isUpload.value = true;
  548. }
  549. isShowCanvas.value = false;
  550. isSuccess.value = true;
  551. }, 1000);
  552. }
  553. });
  554. //#region 页面初始化和卸载
  555. const resetTimer = ref(null);
  556. onMounted(() => {
  557. window.document.addEventListener("touchstart", () => {
  558. // 用户点击时,清除之前的定时器
  559. clearTimeout(resetTimer.value);
  560. // 重新设定120秒后触发的定时器
  561. resetTimer.value = setTimeout(() => {
  562. userInfoModulesPinia.clearStorage();
  563. window.webview.raiseEvent("pageRefresh", "test_params");
  564. uni.redirectTo({ url: "/pages/login/index" });
  565. }, 300000);
  566. });
  567. resetTimer.value = setTimeout(() => {
  568. userInfoModulesPinia.clearStorage();
  569. window.webview.raiseEvent("pageRefresh", "test_params");
  570. uni.redirectTo({ url: "/pages/login/index" });
  571. }, 300000);
  572. });
  573. onUnload(() => {
  574. uni.hideLoading();
  575. clearTimeout(resetTimer.value);
  576. });
  577. //#endregion -----------------------
  578. </script>
  579. <style lang="scss" scoped>
  580. .page {
  581. width: 100vw;
  582. height: 100vh;
  583. padding: 0;
  584. .top {
  585. display: flex;
  586. width: 100%;
  587. height: 32%;
  588. .example {
  589. width: 60%;
  590. height: 100%;
  591. color: #000;
  592. background-color: #fff;
  593. img {
  594. width: 100%;
  595. height: 100%;
  596. }
  597. }
  598. .model {
  599. position: relative;
  600. width: 40%;
  601. height: 100%;
  602. background-color: #000000;
  603. img {
  604. position: absolute;
  605. top: 50%;
  606. left: 50%;
  607. transform: translate(-50%, -50%);
  608. width: 100%;
  609. height: 100%;
  610. }
  611. .reSelect {
  612. position: absolute;
  613. width: 250rpx;
  614. left: 50%;
  615. bottom: 10rpx;
  616. text-align: center;
  617. transform: translateX(-50%);
  618. }
  619. }
  620. }
  621. .bottom {
  622. position: relative;
  623. width: 100%;
  624. height: 68%;
  625. overflow: hidden;
  626. video {
  627. width: 100%;
  628. height: 100%;
  629. // width: 1080px;
  630. // height: 1305px;
  631. :deep(.uni-video-video) {
  632. position: absolute;
  633. left: 0;
  634. top: -50px;
  635. width: 100% !important;
  636. height: 720px !important;
  637. }
  638. }
  639. .selectImg {
  640. position: absolute;
  641. left: 65rpx;
  642. bottom: 75rpx;
  643. width: 68rpx;
  644. height: 68rpx;
  645. border: 5rpx solid #ffffff;
  646. border-radius: 5rpx;
  647. z-index: 99;
  648. img {
  649. position: absolute;
  650. left: 50%;
  651. bottom: 50%;
  652. transform: translate(-50%, 50%);
  653. width: 70%;
  654. height: 70%;
  655. }
  656. .uploadText {
  657. position: absolute;
  658. left: 50%;
  659. bottom: -40rpx;
  660. width: 150%;
  661. font-size: 20rpx;
  662. transform: translateX(-40%);
  663. }
  664. }
  665. #action {
  666. position: absolute;
  667. left: 50%;
  668. bottom: 45rpx;
  669. width: 120rpx;
  670. height: 120rpx;
  671. transform: translateX(-50%);
  672. background-color: #ffffff;
  673. border-radius: 60rpx;
  674. z-index: 99;
  675. .circleInside {
  676. position: absolute;
  677. left: 50%;
  678. bottom: 50%;
  679. transform: translate(-50%, 50%);
  680. width: 100rpx;
  681. height: 100rpx;
  682. background-color: #ffffff;
  683. border-radius: 50%;
  684. border: 6rpx solid #000;
  685. }
  686. }
  687. .confirm {
  688. position: absolute;
  689. left: 50%;
  690. bottom: 75rpx;
  691. width: 180rpx;
  692. height: 80rpx;
  693. // border: 5rpx solid #ffffff;
  694. transform: translateX(-50%);
  695. border-radius: 60rpx;
  696. z-index: 9999999;
  697. img {
  698. // position: absolute;
  699. // left: 50%;
  700. // bottom: 50%;
  701. // transform: translate(-50%, 50%);
  702. width: 100%;
  703. height: 100%;
  704. width: 30rpx;
  705. height: 30rpx;
  706. vertical-align: text-top;
  707. }
  708. .sure {
  709. margin-top: 30rpx;
  710. text-align: center;
  711. width: 100%;
  712. height: 50rpx;
  713. line-height: 50rpx;
  714. background-color: #2ba245;
  715. border-radius: 15rpx;
  716. }
  717. .uploadText {
  718. // position: absolute;
  719. // left: 50%;
  720. // bottom: -40rpx;
  721. // width: 150%;
  722. width: 100%;
  723. height: 30rpx;
  724. line-height: 30rpx;
  725. font-size: 20rpx;
  726. // transform: translateX(-32%);
  727. text-align: center;
  728. }
  729. }
  730. .reTry {
  731. position: absolute;
  732. right: 65rpx;
  733. bottom: 75rpx;
  734. width: 68rpx;
  735. height: 68rpx;
  736. border: 5rpx solid #ffffff;
  737. border-radius: 5rpx;
  738. z-index: 99;
  739. img {
  740. position: absolute;
  741. left: 50%;
  742. bottom: 50%;
  743. transform: translate(-50%, 50%);
  744. width: 70%;
  745. height: 70%;
  746. }
  747. .uploadText {
  748. position: absolute;
  749. left: 50%;
  750. bottom: -40rpx;
  751. width: 150%;
  752. font-size: 20rpx;
  753. transform: translateX(-40%);
  754. }
  755. }
  756. .preview {
  757. position: relative;
  758. width: 100%;
  759. height: 100%;
  760. z-index: 1;
  761. .fromCamera {
  762. // position: absolute;
  763. // top: 110rpx;
  764. // left: 130rpx;
  765. width: 100%;
  766. }
  767. .fromUpload {
  768. position: absolute;
  769. top: 110rpx;
  770. left: 50%;
  771. transform: translateX(-50%);
  772. width: 45%;
  773. }
  774. }
  775. }
  776. .overlay {
  777. .content {
  778. width: 100%;
  779. height: 100vh;
  780. display: flex;
  781. flex-direction: column;
  782. align-items: center;
  783. text-align: center;
  784. .imageBox {
  785. position: relative;
  786. margin-top: 200rpx;
  787. width: 300rpx;
  788. height: 300rpx;
  789. border-radius: 30rpx;
  790. background-color: #fff;
  791. .mask {
  792. position: absolute;
  793. width: 100%;
  794. height: 100%;
  795. border-radius: 30rpx;
  796. background-color: rgba($color: #000000, $alpha: 0.7);
  797. z-index: 2;
  798. }
  799. image {
  800. width: 100%;
  801. height: 100%;
  802. border-radius: 30rpx;
  803. background-color: #fff;
  804. }
  805. }
  806. text {
  807. margin-top: 20rpx;
  808. font-weight: 900;
  809. font-size: 32rpx;
  810. }
  811. // .orangeBtn {
  812. // margin-top: 100rpx;
  813. // }
  814. }
  815. }
  816. }
  817. </style>