From fb1d34bcf4467baaf44a0475952d769c3ad89eed Mon Sep 17 00:00:00 2001 From: rucky Date: Tue, 28 Dec 2021 17:44:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=86=E5=A4=87=E6=B7=BB=E5=8A=A0three?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=20=E8=B0=83=E8=AF=95ios=E6=8E=88=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 1 - src/page/index/HandTrack/index.vue | 163 ++++++++++++++++++++++------- 2 files changed, 125 insertions(+), 39 deletions(-) diff --git a/public/index.html b/public/index.html index 228be0d..54180b4 100644 --- a/public/index.html +++ b/public/index.html @@ -75,7 +75,6 @@ -

精彩即将为您呈现...

diff --git a/src/page/index/HandTrack/index.vue b/src/page/index/HandTrack/index.vue index c3da005..809a26b 100644 --- a/src/page/index/HandTrack/index.vue +++ b/src/page/index/HandTrack/index.vue @@ -9,6 +9,7 @@ playsinline webkit-playsinline x5-playsinline + muted ref="myVideo" > @@ -39,6 +40,9 @@ + + +
14 safria ok || > 14.3 ios webview ok + // > 14.3 ios ok checkUserDeviceSuitable() { if ( - window.deviceInfo.system === "IOS" && - window.deviceInfo.app === "WX" + window.deviceInfo.system === "IOS" + // && window.deviceInfo.app === "WX" ) { let iosV = this.getIOSVersion(); if ( - !this.versionStringCompare(iosV, "14.3") && - this.versionStringCompare(iosV, "14.0") + !this.versionStringCompare(iosV, "14.3") + // && this.versionStringCompare(iosV, "14.0") ) { - this.$Utils.showTips({ - message: "请点击右上角 ...
在浏览器打开", - autoClose: false, - }); - } else if (!this.versionStringCompare(iosV, "14.0")) { + // this.$Utils.showTips({ + // message: "请点击右上角 ...
在浏览器打开", + // autoClose: false, + // }); + // } else if (!this.versionStringCompare(iosV, "14.0")) { this.$Utils.showTips({ message: "😭 很抱歉
⚠️ 当前系统版本过低
无法体验该Demo", @@ -162,11 +170,16 @@ export default { }; } - return global.navigator.mediaDevices + return navigator.mediaDevices .getUserMedia(constraints) .then((stream) => { if (stream) { - stopStreamTracks(stream); + const tracks = stream.getTracks(); + tracks.forEach(function (track) { + track.stop(); + }); + + // stopStreamTracks(stream); return true; } return Promise.reject(new Error("EmptyStreamError")); @@ -178,21 +191,26 @@ export default { return Promise.reject(errMsg); }); }, - // 开始获取权限 + // IOS 用户获取授权 requestPermission() { - return this.getDevicePermission({ video: true, audio: true }) - .catch(() => - this.getDevicePermission({ video: false, audio: true }) - ) - .catch(() => - this.getDevicePermission({ video: true, audio: false }) - ) - .catch(() => true); + return ( + this.getDevicePermission({ video: true }) + // .catch(() => + // this.getDevicePermission({ video: false, audio: true }) + // ) + // .catch(() => + // this.getDevicePermission({ video: true, audio: true }) + // ) + .catch(() => true) + ); }, // 获取摄像头设备id async getBackCameraDeviceId() { + await this.requestPermission(); let source = new Array(); + console.log("start get camera devices"); let devices = await navigator.mediaDevices.enumerateDevices(); + console.log("devices array:", devices); if (devices.length > 0) { devices.forEach(function (device) { if (device.kind == "videoinput") { @@ -200,6 +218,7 @@ export default { } }); } + console.log("devices source:", source); return source[source.length - 1].deviceId; }, // 初始化 video @@ -222,8 +241,6 @@ export default { // }, }; - this.video.play(); - try { this.stream = await navigator.mediaDevices.getUserMedia( constraints @@ -243,12 +260,12 @@ export default { const videoTracks = stream.getVideoTracks(); this.stream = stream; // make variable available to browser console let streamSize = this.GetStreamDimensions(stream); - let handledSize = this.ScaleResolutionToHeight( - streamSize, - window.innerHeight - ); + // let handledSize = this.ScaleResolutionToHeight( + // streamSize, + // window.innerHeight + // ); - this.videoRealSize = handledSize; + // this.videoRealSize = handledSize; console.log("Got stream with constraints:", constraints); console.log(`Using video device: ${videoTracks[0].label}`); @@ -256,13 +273,15 @@ export default { console.log("Got stream size:", streamSize); console.log( "Got streamHandled size:", - window.innerHeight, - handledSize + window.innerHeight + // handledSize ); - this.responseVideo(handledSize); + // this.responseVideoAndCanvas(handledSize); this.video.srcObject = stream; + // this.video.play(); + // 开始识别 this.startDraw(); }, @@ -271,9 +290,14 @@ export default { console.error(error); }, // 视频设置 - responseVideo(size) { + responseVideoAndCanvas(size) { this.video.width = size.width; this.video.height = size.height; + + // init canvcas + this.ctx = this.canvas.getContext("2d"); + this.canvas.width = size.width; + this.canvas.height = size.height; }, // 获得stream大小 GetStreamDimensions(stream) { @@ -327,6 +351,7 @@ export default { this.progress = Math.round(progress * 100); this.progressText = `${this.progress}%`; }); + console.log("engine model loaded"); this.progressText = "引擎准备中…"; this.engine.Configure({ @@ -358,16 +383,25 @@ export default { autoAlpha: 1, delay: 0.5, }); - + // 识别引擎启动 + this.engineStart(); + }, + // 识别引擎启动 + engineStart() { this.engine.Start((e) => { + let cursorPos; if (e.coordinates) { - const cursorPos = this.ExponentialCoordinateAverage( + cursorPos = this.ExponentialCoordinateAverage( this.ComputeCursorPositionFromCoordinates(e.coordinates) ); console.log(cursorPos); } + // console.log(e.type); + if (e.type === EventEnum.RESULT) { + this.drawPoint(cursorPos[0], cursorPos[1]); + this.Render(); if (e.poses.fist) { this.handStatus = "握拳"; if (this.handStep == 1) { @@ -376,7 +410,6 @@ export default { // document.getElementById("status").innerText = "握拳"; } else if (e.poses.pinch) { this.handStatus = "捏合"; - // document.getElementById("status").innerText = "捏合"; } else { this.handStatus = "张开"; if (this.handStep == 2) { @@ -445,6 +478,54 @@ export default { ]; } }, + // init THREELayer + initTHREELayer() { + this.camera_ = new THREE.OrthographicCamera( + 0, + this.videoRealSize.width, + 0, + this.videoRealSize.height, + 0, + 1000 + ); + this.renderer_ = new THREE.WebGLRenderer({ + alpha: true, + powerPreference: "high-performance", + failIfMajorPerformanceCaveat: false, + antialias: true, + }); + this.renderer_.domElement = this.canvas; + this.renderer_.debug.checkShaderErrors = false; + this.renderer_.setSize( + this.videoRealSize.width, + this.videoRealSize.height + ); + this.renderer_.setPixelRatio(window.devicePixelRatio); + this.renderer_.setClearColor(0x000000, 0.0); + this.renderer_.autoClear = true; + this.scene_ = new THREE.Scene(); + }, + // draw pointer + drawPoint(x, y) { + if (!this.meshAdded) { + this.geo_ = new THREE.RingGeometry(0, 8, 30); + this.mat_ = new THREE.MeshBasicMaterial({ + color: "red", + side: THREE.DoubleSide, + }); + this.mesh_ = new THREE.Mesh(this.geo_, this.mat_); + this.scene_.add(this.mesh_); + this.meshAdded = true; + } + + this.mesh_.position.x = x * this.videoRealSize.width; + this.mesh_.position.y = y * this.videoRealSize.height; + this.mesh_.position.z = 0; + }, + // THREE canvas render + Render() { + this.renderer_.render(this.scene_, this.camera_); + }, }, }; @@ -459,8 +540,8 @@ export default { align-content: center; align-items: center; .video { - .paLayout(50%,50%,auto,100%,0); - transform: translate(-50%, -50%); + // .paLayout(50%,50%,auto,100%,0); + // transform: translate(-50%, -50%); // transform: scaleX(-1); // width: 750px; display: none; @@ -521,6 +602,12 @@ export default { } } } + .canvas { + .paLayout(50%,50%,auto,100%,100); + transform: translate(-50%, -50%); + pointer-events: none; + background-color: rgba(255, 255, 255, 0.1); + } .btn { .paCenterBottom(50%,280px,80px,2); background-color: rgba(255, 255, 255, 0.85); @@ -534,7 +621,7 @@ export default { .paCenter(50%,80%,40px,12); margin-top: -20px; border: 1px solid #fff; - border-radius: 20px; + border-radius: 25px; padding: 4px; .bar { .prLayout(100%,100%);