|
@@ -0,0 +1,751 @@
|
|
|
|
+<template>
|
|
|
|
+ <div style="width: 100%; height: calc(100%); background: #fff">
|
|
|
|
+ <div class="img">
|
|
|
|
+ <div class="left" style="width: 380px"></div>
|
|
|
|
+ <div class="controlZ">
|
|
|
|
+ <div id="fan" ref="fan">
|
|
|
|
+ <img :src="img[0]" alt />
|
|
|
|
+ </div>
|
|
|
|
+ <div id="fanB">
|
|
|
|
+ <img :src="img[6]" alt />
|
|
|
|
+ </div>
|
|
|
|
+ <div id="motor">
|
|
|
|
+ <img :src="img[1]" alt />
|
|
|
|
+ </div>
|
|
|
|
+ <div id="base">
|
|
|
|
+ <img :src="img[2]" alt />
|
|
|
|
+ </div>
|
|
|
|
+ <div id="a4">
|
|
|
|
+ <img :src="img[3]" alt />
|
|
|
|
+ </div>
|
|
|
|
+ <div id="screan">
|
|
|
|
+ <img :src="img[4]" alt />
|
|
|
|
+ <!--图片展示-->
|
|
|
|
+ <video
|
|
|
|
+ ref="video"
|
|
|
|
+ id="video_cam"
|
|
|
|
+ width="178"
|
|
|
|
+ height="142.4"
|
|
|
|
+ class="face"
|
|
|
|
+ autoplay
|
|
|
|
+ v-show="isCamera"
|
|
|
|
+ ></video>
|
|
|
|
+ <canvas
|
|
|
|
+ ref="canvasDOM"
|
|
|
|
+ width="178"
|
|
|
|
+ height="142.4"
|
|
|
|
+ class="kuang"
|
|
|
|
+ v-show="isCamera"
|
|
|
|
+ ></canvas>
|
|
|
|
+ </div>
|
|
|
|
+ <div id="line">
|
|
|
|
+ <img :src="img[5]" alt />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="cameraZ">
|
|
|
|
+ <!--开启摄像头-->
|
|
|
|
+ <div class="cameraBtn">
|
|
|
|
+ <!-- <div class="open" @click="callCamera" v-if="!isCamera">
|
|
|
|
+ <img src="../assets/img/open.png" alt />
|
|
|
|
+ </div> -->
|
|
|
|
+ <div class="open" @click="start()" v-if="!isZuan">
|
|
|
|
+ <img src="../assets/img/fan/icon.png" alt />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="close" @click="closeCamera()" v-else>
|
|
|
|
+ <img src="../assets/img/fan/icon2.png" alt />
|
|
|
|
+ </div>
|
|
|
|
+ <!-- <div class="save" @click="photograph" v-if="isCamera">
|
|
|
|
+ <img src="../assets/img/shibie.png" alt />
|
|
|
|
+ </div> -->
|
|
|
|
+ </div>
|
|
|
|
+ <!--确认-->
|
|
|
|
+ <div v-show="false" class="isPhoto">
|
|
|
|
+ <!--canvas截取流-->
|
|
|
|
+ <canvas ref="canvas" width="300" height="240" v-show="false"></canvas>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <!-- <div v-if="isCamera" class="isPhoto">
|
|
|
|
+ <span>截取的图片</span>
|
|
|
|
+ <div
|
|
|
|
+ style="width: 98%; overflow: auto; display: flex; margin: 20px 0 0 10px"
|
|
|
|
+ >
|
|
|
|
+ <div v-for="(res, index) in sampleArr" :key="index" class="gdt">
|
|
|
|
+ <img
|
|
|
|
+ :src="res.img[0]"
|
|
|
|
+ alt=""
|
|
|
|
+ style="margin-right: 10px; width: 178px; height: 142.4px"
|
|
|
|
+ />
|
|
|
|
+ <div class="spotNumber">{{ res.name }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ </div> -->
|
|
|
|
+ <el-dialog
|
|
|
|
+ title="设置名称"
|
|
|
|
+ :visible.sync="updateMessage"
|
|
|
|
+ :append-to-body="true"
|
|
|
|
+ width="300px"
|
|
|
|
+ :before-close="handleClose"
|
|
|
|
+ class="dialog_diy"
|
|
|
|
+ >
|
|
|
|
+ <el-form class="over1">
|
|
|
|
+ <el-form-item
|
|
|
|
+ label="名称"
|
|
|
|
+ :label-width="formLabelWidth"
|
|
|
|
+ style="font-size: 16px !important"
|
|
|
|
+ >
|
|
|
|
+ <!-- {{ this.gameInfo.name }} -->
|
|
|
|
+ <el-input
|
|
|
|
+ clearable
|
|
|
|
+ type="primary"
|
|
|
|
+ v-model="upName"
|
|
|
|
+ style="width: 150px"
|
|
|
|
+ class="inputStyle"
|
|
|
|
+ ></el-input>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-form>
|
|
|
|
+ <el-button class="update" @click="update">添加</el-button>
|
|
|
|
+ <el-button @click="cancel" style="font-size: 16px !important"
|
|
|
|
+ >取消</el-button
|
|
|
|
+ >
|
|
|
|
+ </el-dialog>
|
|
|
|
+ <!-- <el-dialog
|
|
|
|
+ title="识别"
|
|
|
|
+ :visible.sync="closeUpdateMessage"
|
|
|
|
+ :append-to-body="true"
|
|
|
|
+ width="300px"
|
|
|
|
+ :before-close="handleClose"
|
|
|
|
+ class="dialog_diy"
|
|
|
|
+ >
|
|
|
|
+ <div style="text-align: center; font-size: 16px !important">
|
|
|
|
+ 已识别到"{{ this.resultImg.name }}"的图片
|
|
|
|
+ </div>
|
|
|
|
+ <el-button
|
|
|
|
+ @click="closeUpdateMessage = false"
|
|
|
|
+ style="margin: 20px 0 0 35%; font-size: 16px !important"
|
|
|
|
+ >确认</el-button
|
|
|
|
+ >
|
|
|
|
+ </el-dialog> -->
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+<script>
|
|
|
|
+//import tracking from "@/assets/js/tracking-min.js";
|
|
|
|
+//import "@/assets/js/face-min.js";
|
|
|
|
+//import * as faceapi from "face-api.js";
|
|
|
|
+
|
|
|
|
+import * as handPoseDetection from "@tensorflow-models/hand-pose-detection";
|
|
|
|
+
|
|
|
|
+import "@tensorflow/tfjs-backend-webgl";
|
|
|
|
+import * as mpHands from "@mediapipe/hands";
|
|
|
|
+
|
|
|
|
+//import * as tfjsWasm from '@tensorflow/tfjs-backend-wasm';
|
|
|
|
+
|
|
|
|
+// tfjsWasm.setWasmPaths(
|
|
|
|
+// `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tfjsWasm.version_wasm}/dist/`);
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ that: this,
|
|
|
|
+ img: [
|
|
|
|
+ require("../assets/img/fan/fan.png"),
|
|
|
|
+ require("../assets/img/fan/2.png"),
|
|
|
|
+ require("../assets/img/fan/3.png"),
|
|
|
|
+ require("../assets/img/fan/4.png"),
|
|
|
|
+ require("../assets/img/fan/5.png"),
|
|
|
|
+ require("../assets/img/fan/6.png"),
|
|
|
|
+ require("../assets/img/fan/fanB.png"),
|
|
|
|
+ ],
|
|
|
|
+ shibieImg: require("../assets/img/face.png"),
|
|
|
|
+ isCamera: false,
|
|
|
|
+ isZuan: false,
|
|
|
|
+ count: 0,
|
|
|
|
+ change: 0,
|
|
|
|
+ closeUpdateMessage: false,
|
|
|
|
+ updateMessage: false,
|
|
|
|
+ upName: "",
|
|
|
|
+ number: 0,
|
|
|
|
+ isdetected: "请您保持脸部在画面中央",
|
|
|
|
+ videoEl: {},
|
|
|
|
+ canvasEL: {},
|
|
|
|
+ formLabelWidth: "100px",
|
|
|
|
+ resultImg: {
|
|
|
|
+ img: [],
|
|
|
|
+ name: "",
|
|
|
|
+ },
|
|
|
|
+ // 预设样本图,支持本地,网络,beas64
|
|
|
|
+ sampleArr: [
|
|
|
|
+ // {
|
|
|
|
+ // name: "编号1",
|
|
|
|
+ // img: []
|
|
|
|
+ // }
|
|
|
|
+ ],
|
|
|
|
+ // 匹配图,支持本地,网络,beas64
|
|
|
|
+ detArr: [
|
|
|
|
+ //"" 图片1
|
|
|
|
+ ],
|
|
|
|
+ numberOne: 0,
|
|
|
|
+ // 匹配结果
|
|
|
|
+ resultArr: [],
|
|
|
|
+ // 人脸匹配矩阵数组对象转码结果
|
|
|
|
+ faceMatcher: null,
|
|
|
|
+ rotate: 0,
|
|
|
|
+ timer: null,
|
|
|
|
+ detector: null,
|
|
|
|
+ hand: 0,
|
|
|
|
+ isC: false,
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ cancel() {
|
|
|
|
+ this.updateMessage = false;
|
|
|
|
+ this.sampleArr[this.sampleArr.length - 1].name = "编号:" + this.number;
|
|
|
|
+ if (this.sampleArr.length > 0) {
|
|
|
|
+ // var a = document.getElementsByClassName("spot");
|
|
|
|
+ // a[0].style.display = "block";
|
|
|
|
+ this.fnsample();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ start() {
|
|
|
|
+ this.isZuan = true;
|
|
|
|
+ this.isCamera = true;
|
|
|
|
+ let video = this.$refs["video"];
|
|
|
|
+ setInterval(() => {
|
|
|
|
+ this.handsFind(video);
|
|
|
|
+ // window.requestAnimationFrame(this.start);
|
|
|
|
+ }, 1000);
|
|
|
|
+ },
|
|
|
|
+ zhuan(num) {
|
|
|
|
+ var _fan = this.$refs.fan;
|
|
|
|
+ if (this.timer || num == 0) {
|
|
|
|
+ clearInterval(this.timer);
|
|
|
|
+ this.timer = null;
|
|
|
|
+ } else {
|
|
|
|
+ this.timer = setInterval(() => {
|
|
|
|
+ this.rotate += num;
|
|
|
|
+ _fan.style.transform = `rotate(${this.rotate}deg)`;
|
|
|
|
+ }, 100);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ update() {
|
|
|
|
+ this.change = 1;
|
|
|
|
+ this.number = this.number + 1;
|
|
|
|
+ if (this.change == 1) {
|
|
|
|
+ if (this.sampleArr.length > 0) {
|
|
|
|
+ this.sampleArr[this.sampleArr.length - 1].name = this.upName;
|
|
|
|
+ this.isdetected = "已识别到" + this.resultImg.name + "的图片";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (this.sampleArr.length > 0) {
|
|
|
|
+ // var a = document.getElementsByClassName("spot");
|
|
|
|
+ // a[0].style.display = "block";
|
|
|
|
+ this.fnsample();
|
|
|
|
+ }
|
|
|
|
+ this.updateMessage = false;
|
|
|
|
+ },
|
|
|
|
+ async handsFind(video) {
|
|
|
|
+ let hands = await this.detector.estimateHands(video, {
|
|
|
|
+ flipHorizontal: false,
|
|
|
|
+ });
|
|
|
|
+ // console.log(hands);
|
|
|
|
+ if (hands.length > 0 && this.isCamera) {
|
|
|
|
+ let handsA = hands[0].keypoints;
|
|
|
|
+ let _58y = handsA[5].y / handsA[8].y;
|
|
|
|
+ let _912y = handsA[9].y / handsA[12].y;
|
|
|
|
+ let _1316y = handsA[13].y / handsA[16].y;
|
|
|
|
+ let _1720y = handsA[17].y / handsA[20].y;
|
|
|
|
+
|
|
|
|
+ /*石头剪刀布的转速 */
|
|
|
|
+ let buNum = 20;
|
|
|
|
+ let sNum = 0;
|
|
|
|
+ let jNum = 100;
|
|
|
|
+ /**1布2石头3剪刀 */
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (_58y > 1 && _912y > 1 && _1316y > 1 && _1720y > 1) {
|
|
|
|
+ console.log("布");
|
|
|
|
+ if (this.hand == 1) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ this.hand = 1;
|
|
|
|
+ if (this.timer) {
|
|
|
|
+ clearInterval(this.timer);
|
|
|
|
+ this.timer = null;
|
|
|
|
+ this.zhuan(buNum);
|
|
|
|
+ } else {
|
|
|
|
+ this.zhuan(buNum);
|
|
|
|
+ }
|
|
|
|
+ } else if (_58y < 1 && _912y < 1 && _1316y < 1 && _1720y < 1) {
|
|
|
|
+ console.log("石头");
|
|
|
|
+ if (this.hand == 2) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ this.hand = 2;
|
|
|
|
+ if (this.timer) {
|
|
|
|
+ clearInterval(this.timer);
|
|
|
|
+ this.timer = null;
|
|
|
|
+ this.zhuan(sNum);
|
|
|
|
+ } else {
|
|
|
|
+ this.zhuan(sNum);
|
|
|
|
+ }
|
|
|
|
+ } else if (_58y > 1 && _912y > 1 && _1316y < 1 && _1720y < 1) {
|
|
|
|
+ console.log("剪刀");
|
|
|
|
+ if (this.hand == 3) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ this.hand = 3;
|
|
|
|
+
|
|
|
|
+ if (this.timer) {
|
|
|
|
+ clearInterval(this.timer);
|
|
|
|
+ this.timer = null;
|
|
|
|
+ this.zhuan(jNum);
|
|
|
|
+ } else {
|
|
|
|
+ this.zhuan(jNum);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 调用摄像头
|
|
|
|
+ callCamera() {
|
|
|
|
+ let _this = this;
|
|
|
|
+ // H5调用电脑摄像头API
|
|
|
|
+ window.navigator.mediaDevices
|
|
|
|
+ .getUserMedia({
|
|
|
|
+ video: true,
|
|
|
|
+ })
|
|
|
|
+ .then((success) => {
|
|
|
|
+ // 摄像头开启成功
|
|
|
|
+ _this.$refs["video"].srcObject = success;
|
|
|
|
+ // 实时拍照效果
|
|
|
|
+ _this.$refs["video"].play();
|
|
|
|
+ })
|
|
|
|
+ .catch((error) => {
|
|
|
|
+ // console.error("摄像头开启失败,请检查摄像头是否可用!");
|
|
|
|
+ _this.isC = false;
|
|
|
|
+ _this.$message.error("摄像头开启失败,请检查摄像头是否可用!");
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ // 拍照
|
|
|
|
+ photograph() {
|
|
|
|
+ let ctx = this.$refs["canvas"].getContext("2d");
|
|
|
|
+ // 把当前视频帧内容渲染到canvas上
|
|
|
|
+ ctx.drawImage(this.$refs["video"], 0, 0, 300, 240);
|
|
|
|
+ // 转base64格式、图片格式转换、图片质量压缩
|
|
|
|
+ let imgBase64 = this.$refs["canvas"].toDataURL("image/jpeg", 0.7); // 由字节转换为KB 判断大小
|
|
|
|
+
|
|
|
|
+ let str = imgBase64.replace("data:image/jpeg;base64,", "");
|
|
|
|
+ let strLength = str.length;
|
|
|
|
+ let fileLength = parseInt(strLength - (strLength / 8) * 2); // 图片尺寸 用于判断
|
|
|
|
+ let size = (fileLength / 1024).toFixed(2);
|
|
|
|
+ console.log(size); // 上传拍照信息 调用接口上传图片 .........
|
|
|
|
+
|
|
|
|
+ // this.detArr.push(imgBase64);
|
|
|
|
+ var json = { name: "", img: [] };
|
|
|
|
+ this.number = this.number + 1;
|
|
|
|
+ this.upName = "";
|
|
|
|
+ json.img.push(imgBase64);
|
|
|
|
+ this.sampleArr.push(json);
|
|
|
|
+ this.updateMessage = true;
|
|
|
|
+ },
|
|
|
|
+ // 关闭摄像头
|
|
|
|
+ closeCamera() {
|
|
|
|
+ // if (!this.$refs["video"].srcObject) {
|
|
|
|
+ // this.isCamera = false;
|
|
|
|
+ // return;
|
|
|
|
+ // }
|
|
|
|
+ // let stream = this.$refs["video"].srcObject;
|
|
|
|
+ // let tracks = stream.getTracks();
|
|
|
|
+ // tracks.forEach((track) => {
|
|
|
|
+ // track.stop();
|
|
|
|
+ // });
|
|
|
|
+ // this.$refs["video"].srcObject = null;
|
|
|
|
+ this.isCamera = false;
|
|
|
|
+
|
|
|
|
+ this.isZuan = false;
|
|
|
|
+ clearInterval(this.timer);
|
|
|
|
+ this.timer = null;
|
|
|
|
+ this.hand = 0;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ async fnInit() {
|
|
|
|
+ const model = handPoseDetection.SupportedModels.MediaPipeHands;
|
|
|
|
+ const detectorConfig = {
|
|
|
|
+ runtime: "mediapipe", // or 'tfjs'
|
|
|
|
+ modelType: "full",
|
|
|
|
+ // solutionPath: `https://cdn.jsdelivr.net/npm/@mediapipe/hands@${mpHands.VERSION}`,
|
|
|
|
+ solutionPath: `/static/hands`,
|
|
|
|
+ };
|
|
|
|
+ this.detector = await handPoseDetection.createDetector(
|
|
|
|
+ model,
|
|
|
|
+ detectorConfig
|
|
|
|
+ );
|
|
|
|
+ this.callCamera();
|
|
|
|
+ },
|
|
|
|
+ async fnsample() {
|
|
|
|
+ const labeledFaceDescriptors = await Promise.all(
|
|
|
|
+ this.sampleArr.map(async (item) => {
|
|
|
|
+ // 临时图片转码数据,将图片对象转数据矩阵对象
|
|
|
|
+ let descriptors = [];
|
|
|
|
+ for (let image of item.img) {
|
|
|
|
+ const imageEl = await faceapi.fetchImage(image);
|
|
|
|
+ descriptors.push(await faceapi.computeFaceDescriptor(imageEl));
|
|
|
|
+ }
|
|
|
|
+ // 返回图片用户和图片转码数组
|
|
|
|
+ return new faceapi.LabeledFaceDescriptors(item.name, descriptors);
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ // 人脸匹配矩阵数组对象转码结果
|
|
|
|
+ this.faceMatcher = new faceapi.FaceMatcher(labeledFaceDescriptors);
|
|
|
|
+ },
|
|
|
|
+ // 执行遍历识别匹配图片,数值误差越小越精确
|
|
|
|
+ fnRun() {
|
|
|
|
+ let ctx = this.$refs["canvas"].getContext("2d");
|
|
|
|
+ // 把当前视频帧内容渲染到canvas上
|
|
|
|
+ ctx.drawImage(this.$refs["video"], 0, 0, 300, 240);
|
|
|
|
+ // 转base64格式、图片格式转换、图片质量压缩
|
|
|
|
+ let imgBase64 = this.$refs["canvas"].toDataURL("image/jpeg", 0.7); // 由字节转换为KB 判断大小
|
|
|
|
+ this.detArr = [];
|
|
|
|
+ this.detArr.push(imgBase64);
|
|
|
|
+ this.detArr.forEach(async (img) => {
|
|
|
|
+ let ts = Date.now();
|
|
|
|
+ // 将图片对象转数据矩阵对象,进行匹配
|
|
|
|
+ const inputEl = await faceapi.fetchImage(img);
|
|
|
|
+ const inputDescriptor = await faceapi.computeFaceDescriptor(inputEl);
|
|
|
|
+ const bestMatch = await this.faceMatcher.findBestMatch(inputDescriptor);
|
|
|
|
+ // 结果
|
|
|
|
+ this.resultArr = [];
|
|
|
|
+ this.resultArr.push({
|
|
|
|
+ target: img,
|
|
|
|
+ result: bestMatch.toString(),
|
|
|
|
+ time: Date.now() - ts + "ms",
|
|
|
|
+ fps: Math.round(1000 / (Date.now() - ts)),
|
|
|
|
+ });
|
|
|
|
+ console.log(this.resultArr);
|
|
|
|
+ var a = document.getElementsByClassName("pFace");
|
|
|
|
+ for (var i = 0; i < this.sampleArr.length; i++) {
|
|
|
|
+ if (this.sampleArr[i].name == bestMatch.label) {
|
|
|
|
+ // this.closeUpdateMessage = true;
|
|
|
|
+ // if (this.change == 1) {
|
|
|
|
+ // this.resultImg.name = this.upName;
|
|
|
|
+ // } else {
|
|
|
|
+ // this.resultImg.name = this.sampleArr[i].name;
|
|
|
|
+ // }
|
|
|
|
+ this.isdetected = "已识别到" + this.sampleArr[i].name + "的图片";
|
|
|
|
+ this.shibieImg = this.sampleArr[i].img[0];
|
|
|
|
+ if (this.shibieImg.length > 0) {
|
|
|
|
+ a[0].style.width = "300px";
|
|
|
|
+ }
|
|
|
|
+ this.resultImg.img[0] = this.sampleArr[i].img[0];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ handleClose(done) {
|
|
|
|
+ done();
|
|
|
|
+ },
|
|
|
|
+ // 更换匹配图
|
|
|
|
+ async fnChange(e) {
|
|
|
|
+ if (!e.target.files.length) return;
|
|
|
|
+ this.detArr = [];
|
|
|
|
+ this.resultArr = [];
|
|
|
|
+ // 将文件显示为图像并识别
|
|
|
|
+ e.target.files.forEach(async (file) => {
|
|
|
|
+ let ts = Date.now();
|
|
|
|
+ let img = await faceapi.bufferToImage(file);
|
|
|
|
+ const inputDescriptor = await faceapi.computeFaceDescriptor(img);
|
|
|
|
+ const bestMatch = await this.faceMatcher.findBestMatch(inputDescriptor);
|
|
|
|
+ // 结果
|
|
|
|
+ this.detArr.push(img.src);
|
|
|
|
+ this.resultArr.push({
|
|
|
|
+ target: file.name,
|
|
|
|
+ result: bestMatch.toString(),
|
|
|
|
+ time: Date.now() - ts + "ms",
|
|
|
|
+ fps: Math.round(1000 / (Date.now() - ts)),
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ mounted() {
|
|
|
|
+ // console.log(this.$store.state.function);
|
|
|
|
+ // var _s3 = document.createElement("script");
|
|
|
|
+ // _s3.src = "/static/materialize/jquery-2.1.3.min.js";
|
|
|
|
+ // _s3.type = "text/javascript";
|
|
|
|
+ // document.head.appendChild(_s3);
|
|
|
|
+ // var _s2 = document.createElement("script");
|
|
|
|
+ // _s2.src = "/static/camera.283d5d54.js";
|
|
|
|
+ // _s2.type = "text/javascript";
|
|
|
|
+ // document.head.appendChild(_s2);
|
|
|
|
+ // var _s1 = document.createElement("script");
|
|
|
|
+ // _s1.src = "/static/bundle.js";
|
|
|
|
+ // _s1.type = "text/javascript";
|
|
|
|
+ // document.head.appendChild(_s1);
|
|
|
|
+ // console.log(this.$store.state.function);
|
|
|
|
+ // this.$nextTick(() => {
|
|
|
|
+ this.fnInit();
|
|
|
|
+ // this.fnInit().then(() => this.fnRun());
|
|
|
|
+ // });
|
|
|
|
+
|
|
|
|
+ // if (this.$store.state.function.indexOf("screen=1;") != -1) {
|
|
|
|
+ // // this.$message.error("摄像头开启失败,请检查摄像头是否可用!");
|
|
|
|
+ // this.callCamera();
|
|
|
|
+ // }
|
|
|
|
+ this.videoEl = this.$refs.video;
|
|
|
|
+ this.canvasEL = this.$refs.canvasDOM;
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style scoped>
|
|
|
|
+html,
|
|
|
|
+body {
|
|
|
|
+ margin: 0;
|
|
|
|
+ padding: 0;
|
|
|
|
+ width: 100%;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.dialog_diy >>> .el-form-item__label {
|
|
|
|
+ width: 50px !important;
|
|
|
|
+ margin-left: 35px !important;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.dialog_diy >>> .el-form-item__content {
|
|
|
|
+ margin-left: 0 !important;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.update {
|
|
|
|
+ margin-left: 20%;
|
|
|
|
+ font-size: 16px !important;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.tip {
|
|
|
|
+ margin: 25px 0 30px 20px;
|
|
|
|
+}
|
|
|
|
+#fan > img,
|
|
|
|
+#fanB > img,
|
|
|
|
+#motor > img,
|
|
|
|
+#base > img,
|
|
|
|
+#line > img,
|
|
|
|
+.right > img,
|
|
|
|
+#a4 > img,
|
|
|
|
+#screan > img {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ user-select: none;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.img {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: row;
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 500px;
|
|
|
|
+ position: relative;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#fan {
|
|
|
|
+ width: 425px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 5;
|
|
|
|
+ left: 150px;
|
|
|
|
+ top: 0;
|
|
|
|
+ transition: all 1s;
|
|
|
|
+ transform: rotate(0deg);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#fanB {
|
|
|
|
+ width: 116.6px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 4;
|
|
|
|
+ left: 300px;
|
|
|
|
+ top: 155px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#base {
|
|
|
|
+ width: 423.33px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 4;
|
|
|
|
+ top: 295px;
|
|
|
|
+ left: 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#motor {
|
|
|
|
+ width: 134.16px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 3;
|
|
|
|
+ left: 292px;
|
|
|
|
+ top: 175px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#a4 {
|
|
|
|
+ width: 210px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 5;
|
|
|
|
+ top: 517px;
|
|
|
|
+ left: 111px;
|
|
|
|
+}
|
|
|
|
+#screan {
|
|
|
|
+ width: 178.33px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: -19px;
|
|
|
|
+ top: 126px;
|
|
|
|
+}
|
|
|
|
+#line {
|
|
|
|
+ width: 470.83px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 2;
|
|
|
|
+ top: 245px;
|
|
|
|
+ left: -113px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.button {
|
|
|
|
+ color: #fff;
|
|
|
|
+ background: #8ca1de;
|
|
|
|
+ width: 550px;
|
|
|
|
+ height: 55px;
|
|
|
|
+ font-size: 20px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ line-height: 55px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ bottom: 10%;
|
|
|
|
+ left: 50%;
|
|
|
|
+ transform: translateX(-50%);
|
|
|
|
+ user-select: none;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.right {
|
|
|
|
+ width: 40px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: 55%;
|
|
|
|
+ top: 70%;
|
|
|
|
+ display: none;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.dark {
|
|
|
|
+ background: #5b79d0;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.controlZ {
|
|
|
|
+ width: 560px;
|
|
|
|
+ height: 620px;
|
|
|
|
+ /* margin-left: calc(50% - (490px / 2)); */
|
|
|
|
+ position: relative;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.cameraZ {
|
|
|
|
+ display: flex;
|
|
|
|
+ height: 340px;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ flex-wrap: nowrap;
|
|
|
|
+ width: 300px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.cameraBtn {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ align-items: center;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.cameraBtn button {
|
|
|
|
+ margin: 0 0 10px 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.face {
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 9999;
|
|
|
|
+ padding: 5px 0px;
|
|
|
|
+ left: 0;
|
|
|
|
+ top: 37px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.kuang {
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 10000;
|
|
|
|
+ padding: 26.5px 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ top: 37px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.pFace {
|
|
|
|
+ /* width: 300px; */
|
|
|
|
+ /* height: 240px; */
|
|
|
|
+ width: 150px;
|
|
|
|
+ margin: 0 auto;
|
|
|
|
+ margin-top: 220px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.close > img,
|
|
|
|
+.save > img,
|
|
|
|
+.pFace > img,
|
|
|
|
+.open > img,
|
|
|
|
+.spotPhoto > img {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.cameraBtn {
|
|
|
|
+ margin-top: 80px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.close {
|
|
|
|
+ margin-bottom: 25px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.isPhoto {
|
|
|
|
+ height: 410px;
|
|
|
|
+ padding: 80px 0 0 0;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ background: #fff;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.isPhoto > span {
|
|
|
|
+ font-size: 25px;
|
|
|
|
+ color: #ccc;
|
|
|
|
+ margin-left: 10px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.nav {
|
|
|
|
+ text-align: center;
|
|
|
|
+ font-size: 32px;
|
|
|
|
+ color: #ccc;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.spot {
|
|
|
|
+ background: #64ff64;
|
|
|
|
+ color: #fff;
|
|
|
|
+ width: 140px;
|
|
|
|
+ height: 40px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ line-height: 40px;
|
|
|
|
+ border-radius: 20px;
|
|
|
|
+ margin-top: 25px;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ display: none;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.spotNumber {
|
|
|
|
+ text-align: center;
|
|
|
|
+ margin: 0 auto;
|
|
|
|
+ font-size: 20px;
|
|
|
|
+ color: #8c8c8c;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.spotPhoto {
|
|
|
|
+ width: 300px;
|
|
|
|
+ height: 245px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.spotPhoto {
|
|
|
|
+ margin-top: 20px;
|
|
|
|
+ font-size: 20px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.gdt {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+}
|
|
|
|
+</style>
|