From a345948ffe9fb916518903d469f9019eb0225422 Mon Sep 17 00:00:00 2001 From: rucky Date: Thu, 30 Dec 2021 18:39:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=BC=E5=AE=B9=20ios-=E5=BE=AE=E4=BF=A1=20w?= =?UTF-8?q?ebview=E7=8E=AF=E5=A2=83=20=E7=89=B9=E6=AE=8Avideo=20width=20he?= =?UTF-8?q?ight?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy.config.js | 2 +- src/page/index/HandTrack/index.vue | 301 +++++++++++++++++++---------- vue.config.js | 20 +- 3 files changed, 216 insertions(+), 107 deletions(-) diff --git a/deploy.config.js b/deploy.config.js index 11ba48e..e373f04 100644 --- a/deploy.config.js +++ b/deploy.config.js @@ -23,7 +23,7 @@ module.exports = { username: 'front', // 服务器登录用户名 password: 'XfhdFront', // 服务器登录密码 distPath: 'dist', // 本地打包生成目录 - webDir: '/mnt/cdn/scl/webglToy', + webDir: '/mnt1/cdn/cdn/scl/webglToy', // webDir: "/mnt/services/tomcat-8090-test/webapps/test/front", // test替换自己实际项目目录 服务器部署路径(不可为空或'/') isRemoveRemoteFile: true // 是否删除远程文件(默认true) }, diff --git a/src/page/index/HandTrack/index.vue b/src/page/index/HandTrack/index.vue index 81ed33d..d2b60b4 100644 --- a/src/page/index/HandTrack/index.vue +++ b/src/page/index/HandTrack/index.vue @@ -77,7 +77,7 @@ export default { progress: 0, progressText: "0%", //进度文字 BORDER_PADDING_FACTOR: 0.02, //边界阀值 - VIDEO_WIDTH_FACTOR: 0.8, //宽度阀值 + VIDEO_WIDTH_FACTOR: 0.9, //宽度阀值 videoRealSize: {}, handStatus: "未检测到手", handStep: 1, @@ -90,13 +90,60 @@ export default { }, }; }, - mounted() { + async mounted() { this.video = this.$refs.myVideo; this.canvas = this.$refs.canvas; this.checkUserDeviceSuitable(); + + setTimeout(() => { + this.initDemo(); + }, 2500); }, methods: { + // loadEngin + async initDemo() { + // 获取设备 + this.deviceId = await this.getBackCameraDeviceId(); + console.log("got deviceId:", this.deviceId); + // gsap.set(this.$refs.progressBar, { + // autoAlpha: 1, + // }); + + console.log("engine start load"); + this.engine = await this.CreateEngine(); + + console.log("engine model start load"); + await this.engine.DownloadModel((progress) => { + this.progress = Math.round(progress * 100); + this.progressText = `${this.progress}%`; + }); + console.log("engine model loaded"); + + this.engine.Configure({ + // Webcam video is usually flipped so we want the coordinates to be flipped as well. + flipX: this.pcDevice ? true : false, + // Crop away a small area at the border to prevent the user to move out of view + // when reaching for border areas on the canvas. + padding: this.BORDER_PADDING_FACTOR, + }); + + // ios需要预热 + // if (window.deviceInfo.system === "IOS") { + await this.engine.Warmup(); + // } + + gsap.to([this.$refs.progress, this.$refs.progressBar], { + autoAlpha: 0, + delay: 0.5, + onComplete: () => { + this.$refs.progress.style.display = "none"; + // this.$refs.myVideo.style.display = "block"; + gsap.set(this.$refs.myVideo, { left: "50%", top: "50%" }); + gsap.set(this.$refs.showVideoBtn, { autoAlpha: 1 }); + }, + }); + }, // 获取ios版本号 getIOSVersion() { let str = navigator.userAgent.toLowerCase(); @@ -241,9 +288,41 @@ export default { .catch(() => true) ); }, + // 获取摄像头媒体流 + getUserMedia(videoEnable, audioEnable, callback) { + navigator.getUserMedia = + navigator.getUserMedia || + navigator.webkitGetUserMedia || + navigator.mozGetUserMedia || + navigator.msGetUserMedia || + window.getUserMedia; + const constraints = { video: videoEnable, audio: audioEnable }; + if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { + navigator.mediaDevices + .getUserMedia(constraints) + .then((stream) => { + callback(true, stream); + }) + .catch((err) => { + callback(err); + }); + } else if (navigator.getUserMedia) { + navigator.getUserMedia( + constraints, + (stream) => { + callback(true, stream); + }, + (err) => { + callback(err); + } + ); + } else { + callback(new Error("Not support userMedia")); + } + }, // 获取摄像头设备id async getBackCameraDeviceId() { - await this.requestPermission(); + // await this.requestPermission(); let source = new Array(); console.log("start get camera devices"); let devices = await navigator.mediaDevices.enumerateDevices(); @@ -263,67 +342,52 @@ export default { }, // 初始化 video async initVideo(e) { - const constraints = { - video: { - deviceId: { exact: await this.getBackCameraDeviceId() }, + this.video.play(); + + this.getUserMedia( + { + deviceId: { exact: this.deviceId }, facingMode: "environment", - // width: { - // min: 480, - // }, - // height: { - // min: 640, - // }, }, - // video: { - // facingMode: { exact: "environment" }, - // width: { min: 375, ideal: 375, max: 750 }, - // height: { min: 590, ideal: 590, max: 1624 }, - // }, - }; - - try { - this.stream = await navigator.mediaDevices.getUserMedia( - constraints - ); - - gsap.to(e.target, { autoAlpha: 0 }); - e.target.disabled = true; - - // 处理成功回调 - this.handleSuccess(this.stream, constraints); - } catch (e) { - this.handleError(e); - } + false, + (status, stream) => { + if (status === true) { + gsap.set(e.target, { autoAlpha: 0 }); + e.target.disabled = true; + // 处理成功回调 + this.handleSuccess(stream); + } else { + this.handleError(status); + } + } + ); }, // 处理stream获取成功 async handleSuccess(stream, constraints) { - const videoTracks = stream.getVideoTracks(); - this.stream = stream; // make variable available to browser console + // const videoTracks = stream.getVideoTracks(); + // this.stream = stream; // make variable available to browser console let streamSize = this.GetStreamDimensions(stream); + // let handledSize = this.ScaleResolutionToWidth( + // { width: window.innerWidth, height: window.innerHeight }, + // window.innerWidth * this.VIDEO_WIDTH_FACTOR + // ); + // 设置视频 this.responseVideoAndCanvas(); - let handledSize = this.ScaleResolutionToWidth( - { width: this.video.width, height: this.video.height }, - window.innerWidth - ); - - this.videoRealSize = handledSize; + // this.videoRealSize = handledSize; // 初始化three this.initTHREELayer(streamSize); - console.log("Got stream with constraints:", constraints); - console.log(`Using video device: ${videoTracks[0].label}`); - console.log("Got stream size:", videoTracks); + // console.log("Got stream with constraints:", constraints); + // console.log(`Using video device: ${videoTracks[0].label}`); + // console.log("Got stream size:", videoTracks); console.log("Got stream size:", streamSize); - console.log( - "Got streamHandled size:", - window.innerHeight, - handledSize - ); + // console.log("Got streamHandled size:", handledSize); + // 将视频流赋予video对象src this.video.srcObject = stream; this.video.play(); @@ -337,8 +401,17 @@ export default { }, // 视频设置 responseVideoAndCanvas(size) { - this.video.width = window.innerWidth; - this.video.height = window.innerHeight; + if ( + window.deviceInfo.system === "IOS" + // && window.deviceInfo.app === "WX" + ) { + this.speSize = true; + this.video.width = 480; + this.video.height = 640; + } else { + this.video.width = window.innerWidth; + this.video.height = window.innerHeight; + } }, // 获得stream大小 GetStreamDimensions(stream) { @@ -373,6 +446,7 @@ export default { async CreateEngine() { let API = IHandTrackingApi; if (API) { + console.log("have API"); return API.CreateEngine(); } API = await Load("./yoha"); @@ -380,46 +454,36 @@ export default { }, // 开始识别 async startDraw() { - console.log("engine start load"); - gsap.to(this.$refs.progressBar, { - autoAlpha: 1, - delay: 0.5, - }); - this.engine = await this.CreateEngine(); + // console.log("engine start load"); + // gsap.set(this.$refs.progressBar, { + // autoAlpha: 1, + // }); + // this.engine = await this.CreateEngine(); - console.log("engine model start load"); - await this.engine.DownloadModel((progress) => { - this.progress = Math.round(progress * 100); - this.progressText = `${this.progress}%`; - }); - console.log("engine model loaded"); + // console.log("engine model start load"); + // await this.engine.DownloadModel((progress) => { + // this.progress = Math.round(progress * 100); + // this.progressText = `${this.progress}%`; + // }); + // console.log("engine model loaded"); - this.progressText = "引擎准备中…"; - this.engine.Configure({ - // Webcam video is usually flipped so we want the coordinates to be flipped as well. - flipX: this.pcDevice ? true : false, - // Crop away a small area at the border to prevent the user to move out of view - // when reaching for border areas on the canvas. - padding: this.BORDER_PADDING_FACTOR, - }); + // this.progressText = "引擎准备中…"; + // this.engine.Configure({ + // // Webcam video is usually flipped so we want the coordinates to be flipped as well. + // flipX: this.pcDevice ? true : false, + // // Crop away a small area at the border to prevent the user to move out of view + // // when reaching for border areas on the canvas. + // padding: this.BORDER_PADDING_FACTOR, + // }); - // ios需要预热 - if (window.deviceInfo.system === "IOS") { - await this.engine.Warmup(); - } + // // ios需要预热 + // if (window.deviceInfo.system === "IOS") { + // await this.engine.Warmup(); + // } this.engine.SetUpCustomTrackSource(this.video); // await this.engine.SetUpCameraTrackSource(); - this.progressText = "引擎已就绪"; - gsap.to([this.$refs.progress, this.$refs.progressBar], { - autoAlpha: 0, - delay: 0.5, - onComplete: () => { - this.$refs.progress.style.display = "none"; - this.$refs.myVideo.style.display = "block"; - }, - }); gsap.to([this.$refs.handDialog, this.$refs.info], { autoAlpha: 1, delay: 0.5, @@ -528,9 +592,9 @@ export default { this.container = this.$refs.container; this.camera_ = new THREE.PerspectiveCamera( 45, - this.video.width / this.video.height, + window.innerWidth / window.innerHeight, 0.1, - 1500 + 2000 ); const distance = @@ -540,9 +604,14 @@ export default { this.camera_.position.set( this.video.width / 2, this.video.height / 2, - -distance + -1000 + ); + console.log("distance:", distance); + this.camera_.lookAt( + window.innerWidth / 2, + window.innerHeight / 2, + 0 ); - this.camera_.lookAt(this.video.width / 2, this.video.height / 2, 0); // this.camera_ = new THREE.OrthographicCamera( // 0, @@ -579,14 +648,11 @@ export default { this.container.appendChild(this.stats.dom); // this.animate(); + // gsap.to(this.renderer_.domElement, { autoAlpha: 1 }); // this.drawPoint(); this.addLineBox(); }, - onWindowResize(event) { - this.camera_.aspect = window.innerWidth / window.innerHeight; - this.camera_.updateProjectionMatrix(); - this.renderer_.setSize(window.innerWidth, window.innerHeight); - }, + // 添加测试小球 addTestBall() { //light let mainLight = new THREE.HemisphereLight(0xffffff, 0x444444); @@ -628,6 +694,7 @@ export default { this.ambientLight = new THREE.AmbientLight(0x8a7e7e, 0.5); this.scene_.add(this.ambientLight); }, + // 添加线条 addLineBox() { const geometry = new THREE.BufferGeometry(); const material = new THREE.LineBasicMaterial({ @@ -670,10 +737,19 @@ export default { this.lineBox = new THREE.Line(geometry, material); this.scene_.add(this.lineBox); + this.lineBox.position.set( + window.innerWidth / 2, + window.innerHeight / 2, + 0 + ); + + // console.log(window.innerWidth, window.innerHeight); + this.lineBox.scale.x = 0.15; this.lineBox.scale.y = 0.15; this.lineBox.scale.z = 0.15; }, + // 线条重置 generateMorphTargets(geometry) { const data = []; const r = this.lineConfig.r; @@ -693,15 +769,33 @@ export default { }, // draw pointer drawPoint() { - this.geo_ = new THREE.RingGeometry(0, 10, 32); - this.mat_ = new THREE.MeshBasicMaterial({ + const geo_ = new THREE.RingGeometry(0, 10, 32); + const mat_ = new THREE.MeshBasicMaterial({ color: "red", side: THREE.DoubleSide, }); - this.mesh_ = new THREE.Mesh(this.geo_, this.mat_); + this.mesh_ = new THREE.Mesh(geo_, mat_); this.scene_.add(this.mesh_); - this.meshAdded = true; console.log("three mesh added"); + + // let delta = 100; + + // this.mesh_.position.set( + // window.innerWidth / 2 - 400, + // window.innerHeight / 2 + 400, + // 0 + // ); + + // let poss = [ + // [this.video.width / 2 + 200, this.video.height / 2 - 200, 0], + // [0, 0, 0], + // [this.video.width, this.video.height, 0], + // ]; + // for (let i = 0; i < 3; i++) { + // let mesh = new THREE.Mesh(geo_, mat_); + // this.scene_.add(mesh); + // mesh.position.set(...poss[i]); + // } }, // 更新场景内元素的位置 updatePosition(x, y, scale) { @@ -772,10 +866,10 @@ export default { align-content: center; align-items: center; .video { - .paLayout(50%,50%,auto,100%,0); + .paLayout(1500%,1500%,auto,100%,0); transform: translate(-50%, -50%); // width: 750px; - display: none; + // display: none; // height: 700px; &.flip { transform: translate(-50%, -50%) scaleX(-1); @@ -838,10 +932,11 @@ export default { .canvas-container { .paLayout(50%,50%,auto,auto,100); transform: translate(-50%, -50%); - // pointer-events: none; - // background-color: rgba(255, 255, 255, 0.1); + pointer-events: none; + background-color: rgba(255, 255, 255, 0.25); } .btn { + visibility: hidden; .paCenterBottom(50%,280px,80px,2); background-color: rgba(255, 255, 255, 0.85); line-height: 40px; @@ -852,15 +947,15 @@ export default { color: #fff; } .progress-bar { - visibility: hidden; + // visibility: hidden; .paCenter(50%,80%,40px,12); margin-top: -20px; - border: 1px solid #fff; + border: 2px solid #fff; border-radius: 25px; padding: 4px; .bar { .prLayout(100%,100%); - border-radius: 12px; + border-radius: 20px; overflow: hidden; .progress { width: 0%; diff --git a/vue.config.js b/vue.config.js index 38f76cb..ae47aa8 100644 --- a/vue.config.js +++ b/vue.config.js @@ -60,9 +60,23 @@ module.exports = { // .loader('babel-loader') // .options({ // presets: [ - // ['@babel/preset-env', { - // modules: false - // }] + // [ + // "@vue/app", + // { + // "useBuiltIns": "entry", + // corejs: 3, + // "targets": { + // "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + // }, + // polyfills: [ + // 'es.promise', + // 'es.symbol' + // ] + // } + // ] + // ], + // plugins: [ + // "@babel/plugin-transform-runtime" // ] // }); // }