| @@ -45,9 +45,9 @@ | |||||
| "navigationBarBackgroundColor": "#F8F8F8", | "navigationBarBackgroundColor": "#F8F8F8", | ||||
| "backgroundColor": "#F8F8F8", | "backgroundColor": "#F8F8F8", | ||||
| "navigationStyle": "custom", | "navigationStyle": "custom", | ||||
| "rpxCalcMaxDeviceWidth": 1080, | |||||
| "rpxCalcBaseDeviceWidth": 1080, | |||||
| "rpxCalcIncludeWidth": 1080 | |||||
| "rpxCalcMaxDeviceWidth": 2160, | |||||
| "rpxCalcBaseDeviceWidth": 2160, | |||||
| "rpxCalcIncludeWidth": 2160 | |||||
| }, | }, | ||||
| "app": { | "app": { | ||||
| "requiredBackgroundModes": [ | "requiredBackgroundModes": [ | ||||
| @@ -1,80 +1,350 @@ | |||||
| <template> | <template> | ||||
| <div class="page"> | <div class="page"> | ||||
| <!-- Top section --> | |||||
| <div class="top"> | <div class="top"> | ||||
| <div class="tips">提示区</div> | |||||
| <div class="showModel">展示模版</div> | |||||
| <div class="example"> | |||||
| <div>文案与模板提示区域</div> | |||||
| </div> | |||||
| <div class="model"> | |||||
| <img :src="modelUrl" alt="" /> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <!-- Bottom section --> | |||||
| <div class="bottom"> | <div class="bottom"> | ||||
| <div class="camera"> | |||||
| <video | |||||
| id="videoPlayer" | |||||
| class="video-js" | |||||
| width="600" | |||||
| height="400" | |||||
| controls | |||||
| muted | |||||
| > | |||||
| <source src="" /> | |||||
| </video> | |||||
| <video muted></video> | |||||
| <div v-show="photoUrl" id="results"></div> | |||||
| <video | |||||
| v-if="!isSuccess" | |||||
| id="video" | |||||
| muted | |||||
| autoplay="autoplay" | |||||
| :controls="false" | |||||
| ></video> | |||||
| <div v-if="!isSuccess"> | |||||
| <div class="selectImg"> | |||||
| <img src="../../assets/img/selectImg.png" /> | |||||
| <div class="uploadText">上传照片</div> | |||||
| </div> | |||||
| <div id="action" @click="takePicture"> | |||||
| <div class="circleInside"></div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <div class="btnBox"> | |||||
| <div class="takeBtn" @click="takePhoto">拍照</div> | |||||
| <div v-show="photoUrl" class="takeBtn" @click="photoUrl = null"> | |||||
| 重拍 | |||||
| <div v-if="isSuccess"> | |||||
| <div class="selectImg"> | |||||
| <img src="../../assets/img/selectImg.png" /> | |||||
| <div class="uploadText">上传照片</div> | |||||
| </div> | |||||
| <div class="confirm" @click="confirmPhoto"> | |||||
| <img src="../../assets/img/success.png" /> | |||||
| <div class="uploadText">就这张了</div> | |||||
| </div> | |||||
| <div class="reTry" @click="reTry"> | |||||
| <img src="../../assets/img/reTry.png" /> | |||||
| <div class="uploadText">重新拍摄</div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <canvas | |||||
| v-if="isShowCanvas" | |||||
| id="canvas" | |||||
| style="width: 1530; height: 950" | |||||
| ></canvas> | |||||
| <div v-if="isSuccess" class="preview"> | |||||
| <img :src="imgSrc" /> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <!-- Top section --> | |||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| <script setup> | <script setup> | ||||
| import { ref, onMounted } from "vue"; | import { ref, onMounted } from "vue"; | ||||
| import videojs from "video.js"; | |||||
| let player; | |||||
| const photoUrl = ref(null); | |||||
| let videoElement; | |||||
| async function initCamera() { | |||||
| try { | |||||
| videoElement = document.getElementById("videoPlayer"); | |||||
| console.log(videoElement); | |||||
| player = videojs(videoElement, {}, function () {}); | |||||
| const stream = await navigator.mediaDevices.getUserMedia({ video: true }); | |||||
| // Attach the stream to the video element | |||||
| videoElement.srcObject = stream; | |||||
| videoElement.play(); | |||||
| // Initialize Video.js with the video element | |||||
| } catch (error) { | |||||
| console.error("Error accessing camera:", error); | |||||
| import { onLoad, onShow, onUnload } from "@dcloudio/uni-app"; | |||||
| let imgSrc = ref(""); | |||||
| let isSuccess = ref(false); | |||||
| let isShowCanvas = ref(true); | |||||
| let modelUrl = ref(""); | |||||
| const startCamera = () => { | |||||
| function getUserMedia(constraints, success, error) { | |||||
| if (navigator.mediaDevices.getUserMedia) { | |||||
| //最新的标准API | |||||
| navigator.mediaDevices | |||||
| .getUserMedia({ | |||||
| audio: { | |||||
| echoCancellation: true, | |||||
| }, | |||||
| video: { | |||||
| facingMode: "user", | |||||
| }, | |||||
| }) | |||||
| .then(success) | |||||
| .catch(error); | |||||
| } else if (navigator.webkitGetUserMedia) { | |||||
| //webkit核心浏览器 | |||||
| navigator.webkitGetUserMedia(constraints, success, error); | |||||
| } else if (navigator.mozGetUserMedia) { | |||||
| //firfox浏览器 | |||||
| navigator.mozGetUserMedia(constraints, success, error); | |||||
| } else if (navigator.getUserMedia) { | |||||
| //旧版API | |||||
| navigator.getUserMedia(constraints, success, error); | |||||
| } | |||||
| } | } | ||||
| } | |||||
| function takePhoto() { | |||||
| // Capture a photo | |||||
| const videoElement = document.getElementById("videoPlayer"); | |||||
| const canvas = document.createElement("canvas"); | |||||
| canvas.width = videoElement.videoWidth; | |||||
| canvas.height = videoElement.videoHeight; | |||||
| const context = canvas.getContext("2d"); | |||||
| context.drawImage(videoElement, 0, 0, canvas.width, canvas.height); | |||||
| // Set the photo URL | |||||
| photoUrl.value = canvas.toDataURL("image/png"); | |||||
| } | |||||
| const video = document.querySelector("video.uni-video-video"); | |||||
| let canvas = document.querySelector("canvas.uni-canvas-canvas"); | |||||
| const action = document.querySelector("#action"); | |||||
| let context = canvas.getContext("2d"); | |||||
| function success(stream) { | |||||
| //兼容webkit核心浏览器 | |||||
| let CompatibleURL = window.URL || window.webkitURL; | |||||
| //将视频流设置为video元素的源 | |||||
| console.log(stream); | |||||
| //video.src = CompatibleURL.createObjectURL(stream); | |||||
| video.srcObject = stream; | |||||
| video.play(); | |||||
| } | |||||
| function error(error) { | |||||
| console.log(`访问用户媒体设备失败${error.name}, ${error.message}`); | |||||
| } | |||||
| if ( | |||||
| navigator.mediaDevices.getUserMedia || | |||||
| navigator.getUserMedia || | |||||
| navigator.webkitGetUserMedia || | |||||
| navigator.mozGetUserMedia | |||||
| ) { | |||||
| //调用用户媒体设备, 访问摄像头 | |||||
| getUserMedia( | |||||
| { | |||||
| audio: false, | |||||
| video: true, | |||||
| }, | |||||
| success, | |||||
| error | |||||
| ); | |||||
| } else { | |||||
| alert("不支持访问用户媒体"); | |||||
| } | |||||
| action.addEventListener("click", function () { | |||||
| canvas.width = 1530; | |||||
| canvas.height = 950; | |||||
| context.drawImage(video, 0, 0); | |||||
| const dataURL = canvas.toDataURL("image/png"); | |||||
| imgSrc.value = dataURL; | |||||
| setTimeout(() => { | |||||
| isShowCanvas.value = false; | |||||
| isSuccess.value = true; | |||||
| }, 10); | |||||
| }); | |||||
| // 备用方案 | |||||
| // action.addEventListener("click", function () { | |||||
| // context.drawImage(video, -50, -50, 310, 220); | |||||
| // const dataURL = canvas.toDataURL("image/png"); | |||||
| // imgSrc.value = dataURL; | |||||
| // setTimeout(() => { | |||||
| // isShowCanvas.value = false; | |||||
| // isSuccess.value = true; | |||||
| // }, 10); | |||||
| // console.log(dataURL); | |||||
| // }); | |||||
| }; | |||||
| const takePicture = () => { | |||||
| console.log("Take Picture !"); | |||||
| }; | |||||
| const confirmPhoto = () => {}; | |||||
| const reTry = () => { | |||||
| isSuccess.value = false; | |||||
| isShowCanvas.value = true; | |||||
| imgSrc.value = ""; | |||||
| setTimeout(() => { | |||||
| startCamera(); | |||||
| }, 10); | |||||
| }; | |||||
| onLoad((options) => { | |||||
| console.log(options, "options"); | |||||
| modelUrl.value = options.modelUrl; | |||||
| }); | |||||
| onMounted(() => { | onMounted(() => { | ||||
| initCamera(); | |||||
| console.log(this); | |||||
| startCamera(); | |||||
| }); | }); | ||||
| </script> | </script> | ||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||
| /* Your styles remain the same */ | |||||
| .page { | |||||
| width: 100vw; | |||||
| height: 100vh; | |||||
| padding: 0; | |||||
| .top { | |||||
| display: flex; | |||||
| width: 100%; | |||||
| height: 32%; | |||||
| .example { | |||||
| width: 60%; | |||||
| height: 100%; | |||||
| color: #000; | |||||
| background-color: #fff; | |||||
| } | |||||
| .model { | |||||
| position: relative; | |||||
| width: 40%; | |||||
| height: 100%; | |||||
| background-color: #000000; | |||||
| img { | |||||
| position: absolute; | |||||
| top: 50%; | |||||
| left: 50%; | |||||
| transform: translate(-50%, -50%); | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| } | |||||
| } | |||||
| } | |||||
| .bottom { | |||||
| position: relative; | |||||
| width: 100%; | |||||
| height: 68%; | |||||
| video { | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| } | |||||
| .selectImg { | |||||
| position: absolute; | |||||
| left: 65rpx; | |||||
| bottom: 75rpx; | |||||
| width: 68rpx; | |||||
| height: 68rpx; | |||||
| border: 5rpx solid #ffffff; | |||||
| border-radius: 5rpx; | |||||
| z-index: 99; | |||||
| img { | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| bottom: 50%; | |||||
| transform: translate(-50%, 50%); | |||||
| width: 70%; | |||||
| height: 70%; | |||||
| } | |||||
| .uploadText { | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| bottom: -40rpx; | |||||
| width: 150%; | |||||
| font-size: 20rpx; | |||||
| transform: translateX(-40%); | |||||
| } | |||||
| } | |||||
| #action { | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| bottom: 45rpx; | |||||
| width: 120rpx; | |||||
| height: 120rpx; | |||||
| transform: translateX(-50%); | |||||
| background-color: #ffffff; | |||||
| border-radius: 60rpx; | |||||
| z-index: 99; | |||||
| .circleInside { | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| bottom: 50%; | |||||
| transform: translate(-50%, 50%); | |||||
| width: 100rpx; | |||||
| height: 100rpx; | |||||
| background-color: #ffffff; | |||||
| border-radius: 50%; | |||||
| border: 6rpx solid #000; | |||||
| } | |||||
| } | |||||
| .confirm { | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| bottom: 75rpx; | |||||
| width: 80rpx; | |||||
| height: 80rpx; | |||||
| // border: 5rpx solid #ffffff; | |||||
| transform: translateX(-50%); | |||||
| border-radius: 60rpx; | |||||
| z-index: 99; | |||||
| img { | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| bottom: 50%; | |||||
| transform: translate(-50%, 50%); | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| } | |||||
| .uploadText { | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| bottom: -40rpx; | |||||
| width: 150%; | |||||
| font-size: 20rpx; | |||||
| transform: translateX(-32%); | |||||
| } | |||||
| } | |||||
| .reTry { | |||||
| position: absolute; | |||||
| right: 65rpx; | |||||
| bottom: 75rpx; | |||||
| width: 68rpx; | |||||
| height: 68rpx; | |||||
| border: 5rpx solid #ffffff; | |||||
| border-radius: 5rpx; | |||||
| z-index: 99; | |||||
| img { | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| bottom: 50%; | |||||
| transform: translate(-50%, 50%); | |||||
| width: 70%; | |||||
| height: 70%; | |||||
| } | |||||
| .uploadText { | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| bottom: -40rpx; | |||||
| width: 150%; | |||||
| font-size: 20rpx; | |||||
| transform: translateX(-40%); | |||||
| } | |||||
| } | |||||
| .preview { | |||||
| position: relative; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| z-index: 1; | |||||
| img { | |||||
| position: absolute; | |||||
| top: 110rpx; | |||||
| width: 120%; | |||||
| height: 60%; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | </style> | ||||
| @@ -1,177 +0,0 @@ | |||||
| <template> | |||||
| <view class="page"> | |||||
| <!-- 顶部 --> | |||||
| <view class="top"> | |||||
| <view class="tips">提示区</view> | |||||
| <view class="showModel">展示模版</view> | |||||
| </view> | |||||
| <!-- 底部 --> | |||||
| <view class="bottom"> | |||||
| <view class="camera"> | |||||
| <video | |||||
| src="" | |||||
| muted="muted" | |||||
| id="videoElement" | |||||
| autoplay="autoplay" | |||||
| playsinline="playsinline" | |||||
| ></video> | |||||
| <!-- <view v-show="!photoUrl" id="my_camera"></view> | |||||
| <view v-show="photoUrl" id="results"></view> --> | |||||
| </view> | |||||
| <view class="btnBox"> | |||||
| <view v-show="!photoUrl" class="takeBtn" @click="takePhoto">拍照</view> | |||||
| <view v-show="photoUrl" class="takeBtn" @click="photoUrl = null" | |||||
| >重拍</view | |||||
| > | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| </template> | |||||
| // js部分 | |||||
| <script setup> | |||||
| //#region 引入 | |||||
| import { ref, watch, onMounted } from "vue"; | |||||
| // import Webcam from "webcamjs"; | |||||
| import Webcam from "../../utils/webcam"; | |||||
| //#endregion ---------------------------- | |||||
| //#region 摄像头 | |||||
| setTimeout(() => { | |||||
| navigator.mediaDevices | |||||
| .getUserMedia({ video: true }) | |||||
| .then(function (stream) { | |||||
| console.log(stream); | |||||
| // 获取到摄像头的视频流 | |||||
| const video = document.getElementById("videoElement"); | |||||
| video.srcObject = stream; | |||||
| }) | |||||
| .catch((error) => { | |||||
| console.error("调用摄像头失败", error); | |||||
| }); | |||||
| }, 1000); | |||||
| //#endregion --------------------------------- | |||||
| //#region 相机 | |||||
| // 拍照 | |||||
| const photoUrl = ref(null); | |||||
| function takePhoto() { | |||||
| // console.log(Webcam.snap); | |||||
| uni.chooseImage({ | |||||
| sourceType: ["camera"], | |||||
| success: function (res) { | |||||
| console.log(JSON.stringify(res.tempFilePaths)); | |||||
| }, | |||||
| fail: (err) => { | |||||
| console.error("选择图片失败", err); | |||||
| uni.showToast({ | |||||
| title: "选择图片失败, 请稍后重试", | |||||
| icon: "none", | |||||
| }); | |||||
| }, | |||||
| }); | |||||
| return; | |||||
| Webcam.snap((res) => { | |||||
| // Webcam.freeze(); | |||||
| photoUrl.value = res; | |||||
| document.getElementById("results").innerHTML = | |||||
| '<img style="width: 100%;height: 100%;" src="' + res + '"/>'; | |||||
| }); | |||||
| } | |||||
| // 关闭 | |||||
| function closeCamera() { | |||||
| Webcam.reset(); | |||||
| } | |||||
| //#endregion ---------------------------- | |||||
| //#region 初始化配置相机 | |||||
| onMounted(() => { | |||||
| Webcam.set({ | |||||
| // width: 864, //实时摄像机查看器的宽度 | |||||
| // height: 1536, //实时摄像机查看器的高度 | |||||
| width: 864, //实时摄像机查看器的宽度 | |||||
| height: 1536, //实时摄像机查看器的高度 | |||||
| dest_width: 392, //捕获相机图像的宽 | |||||
| dest_height: 698, //捕获相机图像的高 | |||||
| dest_width: 720, //捕获相机图像的宽 | |||||
| dest_height: 720, //捕获相机图像的高 | |||||
| // crop_width: 700, //最终裁剪图像的宽度(以像素为单位),默认为dest_width。 | |||||
| // crop_height: 700, //最终裁剪图像的高度(以像素为单位),默认为dest_height。 | |||||
| image_format: "png", //捕获图像的期望图像格式,可以是“jpeg”或“png”。 | |||||
| jpeg_quality: 90, //对于JPEG图像,这是理想的质量,从0(最差)到100(最好)。 | |||||
| enable_flash: true, //启用或禁用Flash回退,如果没有本机网络摄像头访问。 | |||||
| force_flash: false, //将此设置为true将始终在adobeflash回退模式下运行。 | |||||
| flip_horiz: false, //将此设置为true将水平翻转图像(镜像模式)。 | |||||
| fps: 30, //设置所需的fps(帧/秒)捕获速率。 | |||||
| swfURL: "./webcam.swf", //为adobeflash回退SWF文件设置一个备用位置 | |||||
| flashNotDetectedText: "未检测到flash播放器的文本/html。", //未检测到flash播放器的文本/html。 | |||||
| unfreeze_snap: true, //是否在拍照后解冻相机 | |||||
| upload_name: "webcam", //在上传摄像头图像文件时使用哪个HTTP POST参数名 | |||||
| flip_horiz: true, //是否镜像 | |||||
| }); | |||||
| // DOM元素必须已经创建并且为空。将ID或CSS选择器传递给Webcam.attach()函数(挂载dom) | |||||
| // Webcam.attach("#my_camera"); | |||||
| }); | |||||
| //#endregion ----------------------------- | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| padding: 0; | |||||
| width: 100vw; | |||||
| height: 100vh; | |||||
| // overflow: hidden; | |||||
| } | |||||
| .top { | |||||
| display: flex; | |||||
| width: 100vw; | |||||
| height: 30vh; | |||||
| .tips { | |||||
| width: 60%; | |||||
| height: 30vh; | |||||
| background-color: #000; | |||||
| text-align: center; | |||||
| } | |||||
| .showModel { | |||||
| width: 40%; | |||||
| height: 30vh; | |||||
| background-color: red; | |||||
| text-align: center; | |||||
| } | |||||
| } | |||||
| .bottom { | |||||
| video { | |||||
| width: 100% !important; | |||||
| height: 100% !important; | |||||
| } | |||||
| display: flex; | |||||
| width: 100vw; | |||||
| height: 70vh; | |||||
| .camera { | |||||
| width: 80vw; | |||||
| height: 70vh; | |||||
| background-color: green; | |||||
| // #my_camera { | |||||
| // width: 100% !important; | |||||
| // height: 100% !important; | |||||
| // } | |||||
| // #results { | |||||
| // width: 100% !important; | |||||
| // height: 100% !important; | |||||
| // } | |||||
| } | |||||
| .btnBox { | |||||
| width: 20vw; | |||||
| height: 70vh; | |||||
| background-color: skyblue; | |||||
| .takeBtn { | |||||
| width: 15vw; | |||||
| height: 15vw; | |||||
| border-radius: 50%; | |||||
| background-color: #444; | |||||
| line-height: 15vw; | |||||
| text-align: center; | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | |||||
| @@ -1,82 +0,0 @@ | |||||
| <template> | |||||
| <div class="page"> | |||||
| <!-- Top section --> | |||||
| <div class="top"> | |||||
| <div class="tips">提示区</div> | |||||
| <div class="showModel">展示模版</div> | |||||
| </div> | |||||
| <!-- Bottom section --> | |||||
| <div class="bottom"> | |||||
| <div class="camera"> | |||||
| <video | |||||
| ref="video" | |||||
| class="video-js vjs-default-skin" | |||||
| width="600" | |||||
| height="400" | |||||
| controls | |||||
| > | |||||
| <source src="https://playtv-live.ifeng.com/live/06OLEGEGM4G.m3u8" /> | |||||
| </video> | |||||
| <video | |||||
| ref="videoElement" | |||||
| id="videoPlayer" | |||||
| class="video-js" | |||||
| muted | |||||
| ></video> | |||||
| <div v-show="photoUrl" id="results"></div> | |||||
| </div> | |||||
| <div class="btnBox"> | |||||
| <div class="takeBtn" @click="takePhoto">拍照</div> | |||||
| <div v-show="photoUrl" class="takeBtn" @click="photoUrl = null"> | |||||
| 重拍 | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <script setup> | |||||
| import { ref, onMounted } from "vue"; | |||||
| import videojs from "video.js"; | |||||
| let player; | |||||
| const photoUrl = ref(null); | |||||
| async function initCamera() { | |||||
| try { | |||||
| const videoElement = document.getElementById("videoPlayer"); | |||||
| player = videojs(videoElement, {}, function () {}); | |||||
| const stream = await navigator.mediaDevices.getUserMedia({ video: true }); | |||||
| // Attach the stream to the video element | |||||
| videoElement.srcObject = stream; | |||||
| videoElement.play(); | |||||
| // Initialize Video.js with the video element | |||||
| } catch (error) { | |||||
| console.error("Error accessing camera:", error); | |||||
| } | |||||
| } | |||||
| function takePhoto() { | |||||
| // Capture a photo | |||||
| const videoElement = document.getElementById("videoPlayer"); | |||||
| const canvas = document.createElement("canvas"); | |||||
| canvas.width = videoElement.videoWidth; | |||||
| canvas.height = videoElement.videoHeight; | |||||
| const context = canvas.getContext("2d"); | |||||
| context.drawImage(videoElement, 0, 0, canvas.width, canvas.height); | |||||
| // Set the photo URL | |||||
| photoUrl.value = canvas.toDataURL("image/png"); | |||||
| } | |||||
| onMounted(() => { | |||||
| initCamera(); | |||||
| }); | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| /* Your styles remain the same */ | |||||
| </style> | |||||
| @@ -1,143 +0,0 @@ | |||||
| <template> | |||||
| <view class="page"> | |||||
| <!-- 顶部 --> | |||||
| <view class="top"> | |||||
| <view class="tips">提示区</view> | |||||
| <view class="showModel">展示模版</view> | |||||
| </view> | |||||
| <!-- 底部 --> | |||||
| <view class="bottom"> | |||||
| <view class="camera"> | |||||
| <view v-show="!photoUrl" id="my_camera"></view> | |||||
| <view v-show="photoUrl" id="results"></view> | |||||
| </view> | |||||
| <view class="btnBox"> | |||||
| <view class="takeBtn" @click="takePhoto">拍照</view> | |||||
| <view v-show="photoUrl" class="takeBtn" @click="photoUrl = null" | |||||
| >重拍</view | |||||
| > | |||||
| </view> | |||||
| </view> | |||||
| <!-- <view id="results"></view> | |||||
| <view id="my_camera"></view> | |||||
| <view @click="takePhoto">拍照</view> | |||||
| <view @click="closeCamera">关闭</view> --> | |||||
| </view> | |||||
| </template> | |||||
| // js部分 | |||||
| <script setup> | |||||
| //#region 引入 | |||||
| import { ref, watch, onMounted } from "vue"; | |||||
| // import Webcam from "webcamjs"; | |||||
| import Webcam from "../../utils/webcam"; | |||||
| //#endregion ---------------------------- | |||||
| //#region 相机 | |||||
| // 拍照 | |||||
| const photoUrl = ref(null); | |||||
| function takePhoto() { | |||||
| // console.log(Webcam.snap); | |||||
| Webcam.snap((res) => { | |||||
| photoUrl.value = res; | |||||
| document.getElementById("results").innerHTML = | |||||
| '<img style="width: 100%;height: 100%;" src="' + res + '"/>'; | |||||
| }); | |||||
| } | |||||
| // 关闭 | |||||
| function closeCamera() { | |||||
| Webcam.reset(); | |||||
| } | |||||
| //#endregion ---------------------------- | |||||
| //#region 初始化配置相机 | |||||
| onMounted(() => { | |||||
| Webcam.set({ | |||||
| // width: 864, //实时摄像机查看器的宽度 | |||||
| // height: 1536, //实时摄像机查看器的高度 | |||||
| width: 864, //实时摄像机查看器的宽度 | |||||
| height: 1536, //实时摄像机查看器的高度 | |||||
| // dest_width: 392, //捕获相机图像的宽 | |||||
| // dest_height: 698, //捕获相机图像的高 | |||||
| dest_width: 720, //捕获相机图像的宽 | |||||
| dest_height: 720, //捕获相机图像的高 | |||||
| // crop_width: 700, //最终裁剪图像的宽度(以像素为单位),默认为dest_width。 | |||||
| // crop_height: 700, //最终裁剪图像的高度(以像素为单位),默认为dest_height。 | |||||
| image_format: "png", //捕获图像的期望图像格式,可以是“jpeg”或“png”。 | |||||
| jpeg_quality: 90, //对于JPEG图像,这是理想的质量,从0(最差)到100(最好)。 | |||||
| enable_flash: true, //启用或禁用Flash回退,如果没有本机网络摄像头访问。 | |||||
| force_flash: false, //将此设置为true将始终在adobeflash回退模式下运行。 | |||||
| flip_horiz: false, //将此设置为true将水平翻转图像(镜像模式)。 | |||||
| fps: 30, //设置所需的fps(帧/秒)捕获速率。 | |||||
| swfURL: "./webcam.swf", //为adobeflash回退SWF文件设置一个备用位置 | |||||
| flashNotDetectedText: "未检测到flash播放器的文本/html。", //未检测到flash播放器的文本/html。 | |||||
| unfreeze_snap: true, //是否在拍照后解冻相机 | |||||
| upload_name: "webcam", //在上传摄像头图像文件时使用哪个HTTP POST参数名 | |||||
| flip_horiz: true, //是否镜像 | |||||
| }); | |||||
| // DOM元素必须已经创建并且为空。将ID或CSS选择器传递给Webcam.attach()函数(挂载dom) | |||||
| Webcam.attach("#my_camera"); | |||||
| }); | |||||
| //#endregion ----------------------------- | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| padding: 0; | |||||
| width: 100vw; | |||||
| height: 100vh; | |||||
| overflow: hidden; | |||||
| } | |||||
| .top { | |||||
| display: flex; | |||||
| width: 100vw; | |||||
| height: 30vh; | |||||
| .tips { | |||||
| width: 60%; | |||||
| height: 30vh; | |||||
| background-color: #000; | |||||
| text-align: center; | |||||
| } | |||||
| .showModel { | |||||
| width: 40%; | |||||
| height: 30vh; | |||||
| background-color: red; | |||||
| text-align: center; | |||||
| } | |||||
| } | |||||
| .bottom { | |||||
| video { | |||||
| width: 100% !important; | |||||
| height: 100% !important; | |||||
| } | |||||
| display: flex; | |||||
| width: 100vw; | |||||
| height: 70vh; | |||||
| .camera { | |||||
| width: 80vw; | |||||
| height: 70vh; | |||||
| background-color: green; | |||||
| // #my_camera { | |||||
| // width: 100% !important; | |||||
| // height: 100% !important; | |||||
| // } | |||||
| // #results { | |||||
| // width: 100% !important; | |||||
| // height: 100% !important; | |||||
| // } | |||||
| } | |||||
| .btnBox { | |||||
| width: 20vw; | |||||
| height: 70vh; | |||||
| background-color: skyblue; | |||||
| .takeBtn { | |||||
| width: 15vw; | |||||
| height: 15vw; | |||||
| border-radius: 50%; | |||||
| background-color: #444; | |||||
| line-height: 15vw; | |||||
| text-align: center; | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | |||||
| @@ -273,7 +273,10 @@ onUnload(() => { | |||||
| //#region | //#region | ||||
| function toCamera() { | function toCamera() { | ||||
| uni.navigateTo({ url: "/pages/camera/index" }); | |||||
| const url = styleData.value.coverImg; | |||||
| uni.navigateTo({ | |||||
| url: `/pages/camera/index?modelUrl=${url}`, | |||||
| }); | |||||
| } | } | ||||
| //#endregion --------------------- | //#endregion --------------------- | ||||
| @@ -23,7 +23,19 @@ function toChooseStyle() { | |||||
| //#region getImei | //#region getImei | ||||
| function Imei() { | function Imei() { | ||||
| getIMEI(); | |||||
| try { | |||||
| const IMEI = getIMEI(); | |||||
| uni.showToast({ | |||||
| title: IMEI, | |||||
| icon: "success", | |||||
| }); | |||||
| } catch (error) { | |||||
| uni.showToast({ | |||||
| title: "Error", | |||||
| icon: "error", | |||||
| }); | |||||
| } | |||||
| // cordova.exec( | // cordova.exec( | ||||
| // function (imei) { | // function (imei) { | ||||
| // console.log("IMEI:", imei); | // console.log("IMEI:", imei); | ||||
| @@ -63,7 +75,7 @@ function Imei() { | |||||
| align-items: center; | align-items: center; | ||||
| padding: 100rpx 0; | padding: 100rpx 0; | ||||
| width: 100%; | width: 100%; | ||||
| height: 400rpx; | |||||
| height: 300rpx; | |||||
| background-color: rgba($color: #000000, $alpha: 0.5); | background-color: rgba($color: #000000, $alpha: 0.5); | ||||
| .IMEI { | .IMEI { | ||||
| position: absolute; | position: absolute; | ||||
| @@ -47,6 +47,8 @@ view { | |||||
| } | } | ||||
| .orangeBtn { | .orangeBtn { | ||||
| position: absolute; | |||||
| bottom: 100rpx; | |||||
| background-color: #FF4F00; | background-color: #FF4F00; | ||||
| width: 520rpx; | width: 520rpx; | ||||
| height: 100rpx; | height: 100rpx; | ||||