<template>
	<div class="hand-track">
		<video
			id="gum-local"
			class="video"
			:class="{ flip: pcDevice }"
			autoplay
			playsinline
			webkit-playsinline
			x5-playsinline
			muted
			ref="myVideo"
		></video>

		<!-- 获取权限 -->
		<button
			id="showVideo"
			class="btn"
			ref="showVideoBtn"
			@click="initVideo($event)"
		>
			点击开始探索
		</button>

		<!-- info -->
		<div class="info-dialog" ref="info">
			<div class="progress" ref="progress">
				当前进度: {{ progressText }}..
			</div>
			<div class="status">
				<span>{{ handStatus }}</span> :当前手势
			</div>
		</div>

		<!-- progress -->
		<div class="progress-bar" ref="progressBar">
			<div class="bar">
				<div class="progress" :style="'width:' + progress + '%'"></div>
			</div>
		</div>

		<!-- canvas -->
		<div class="canvas-container" ref="container"></div>

		<!-- hand -->
		<div
			class="hand-dialog"
			ref="handDialog"
			v-if="handStep > 0 && handStep < 3"
		>
			<p>请在镜头前尝试做出以下手势</p>
			<div class="hand" :class="'hand-' + handStep" ref="hand"></div>
		</div>

		<!-- unsuit-dialog -->
		<div class="des-dialog" ref="unsuit"></div>
	</div>
</template>
<script>
// @ is an alias to /src
import gsap from "gsap";
import Stats from "stats";
import {
	IHandTrackingApi,
	IEngine,
	Load,
	EventEnum,
} from "@handtracking.io/yoha";
import * as THREE from "three";

export default {
	name: "handTrack",
	components: {},
	data() {
		return {
			progress: 0,
			progressText: "0%", //进度文字
			BORDER_PADDING_FACTOR: 0.02, //边界阀值
			VIDEO_WIDTH_FACTOR: 0.9, //宽度阀值
			videoRealSize: {},
			handStatus: "未检测到手",
			handStep: 1,
			meshAdded: false,
			pcDevice: false, // pc设备
			lineConfig: {
				segments: 10000,
				r: 800,
				t: 0,
			},
		};
	},
	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();
			let ver = str.match(/cpu iphone os (.*?) like mac os/);
			if (!ver) {
				console.log("请在Ios系统中打开");
			} else {
				console.log(
					"你当前的Ios系统版本为：" + ver[1].replace(/_/g, ".")
				);
				return ver[1].replace(/_/g, ".");
			}
		},
		// 检测用户手机是否兼容
		// > 14.3 ios ok
		checkUserDeviceSuitable() {
			if (
				window.deviceInfo.system === "IOS"
				// && window.deviceInfo.app === "WX"
			) {
				let iosV = this.getIOSVersion();
				if (
					!this.versionStringCompare(iosV, "14.3")
					//  && this.versionStringCompare(iosV, "14.0")
				) {
					// 	this.$Utils.showTips({
					// 		message: "请点击右上角 ...</br>在浏览器打开",
					// 		autoClose: false,
					// 	});
					// } else if (!this.versionStringCompare(iosV, "14.0")) {
					this.$Utils.showTips({
						message:
							"😭 很抱歉</br>⚠️ 当前系统版本过低</br>无法体验该Demo",
						autoClose: false,
					});
				}
			}
		},
		// 版本号比较
		versionStringCompare(preVersion = "", lastVersion = "") {
			// 将版本号格式化为相同位数数字字符串
			function toNum(a) {
				var a = a.toString();
				//也可以这样写 var c=a.split(/\./);
				var c = a.split(".");
				// eslint-disable-next-line camelcase
				var num_place = ["", "0", "00", "000", "0000"],
					// eslint-disable-next-line camelcase
					r = num_place.reverse();
				for (var i = 0; i < c.length; i++) {
					var len = c[i].length;
					c[i] = r[len] + c[i];
				}
				var res = c.join("");
				return res;
			}

			var _a = toNum(preVersion),
				_b = toNum(lastVersion);
			console.log(_a, _b);
			if (_a == _b || _a > _b) return true;
			else return false;
		},
		// 获取设备权限
		getDevicePermission(constraints) {
			if (navigator.mediaDevices.getUserMedia === undefined) {
				navigator.mediaDevices.getUserMedia = function (constraints) {
					var getUserMedia =
						navigator.getUserMedia ||
						navigator.webkitGetUserMedia ||
						navigator.mozGetUserMedia ||
						navigator.msGetUserMedia ||
						navigator.oGetUserMedia;
					if (!getUserMedia) {
						return Promise.reject(
							new Error(
								"getUserMedia is not implemented in this browser"
							)
						);
					}
					return new Promise(function (resolve, reject) {
						getUserMedia.call(
							navigator,
							constraints,
							resolve,
							reject
						);
					});
				};
			}

			return navigator.mediaDevices
				.getUserMedia(constraints)
				.then((stream) => {
					if (stream) {
						if (typeof stream.stop === "function") {
							stream.stop();
						} else {
							let trackList = [
								stream.getAudioTracks(),
								stream.getVideoTracks(),
							];
							for (let i = 0; i < trackList.length; i++) {
								let tracks = trackList[i];
								if (tracks && tracks.length > 0) {
									for (let j = 0; j < tracks.length; j++) {
										let track = tracks[j];
										if (typeof track.stop === "function") {
											track.stop();
										}
									}
								}
							}
						}
						// const tracks = stream.getTracks();
						// tracks.forEach(function (track) {
						// 	track.stop();
						// });

						// stopStreamTracks(stream);
						return true;
					}
					return Promise.reject(new Error("EmptyStreamError"));
				})
				.catch((errMsg) => {
					if (errMsg && "NotAllowedError" === errMsg.name) {
						return false;
					}
					return Promise.reject(errMsg);
				});
		},
		// IOS 用户获取授权
		requestPermission() {
			return (
				this.getDevicePermission({ video: true })
					// .catch(() =>
					// 	this.getDevicePermission({ video: false, audio: true })
					// )
					// .catch(() =>
					// 	this.getDevicePermission({ video: true, audio: true })
					// )
					.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();
			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") {
						source.push(device);
					}
				});
			}
			console.log("devices source:", source);
			if (source.length < 2 && window.deviceInfo.device === "PC") {
				this.pcDevice = true;
			}
			return source[source.length - 1].deviceId;
		},
		// 初始化 video
		async initVideo(e) {
			this.video.play();

			this.getUserMedia(
				{
					deviceId: { exact: this.deviceId },
					facingMode: "environment",
				},
				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
			let streamSize = this.GetStreamDimensions(stream);

			// let handledSize = this.ScaleResolutionToWidth(
			// 	{ width: window.innerWidth, height: window.innerHeight },
			// 	window.innerWidth * this.VIDEO_WIDTH_FACTOR
			// );

			// 设置视频
			this.responseVideoAndCanvas();

			// 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 size:", streamSize);
			// console.log("Got streamHandled size:", handledSize);

			// 将视频流赋予video对象src
			this.video.srcObject = stream;

			this.video.play();

			// 开始识别
			this.startDraw();
		},
		// 处理stream获取错误
		handleError(error) {
			console.error(error);
		},
		// 视频设置
		responseVideoAndCanvas(size) {
			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) {
			return {
				width: stream.getVideoTracks()[0].getSettings().width,
				height: stream.getVideoTracks()[0].getSettings().height,
			};
		},
		// 等比缩放视频 宽
		ScaleResolutionToWidth(resolution, width) {
			const cw = resolution.width;
			const ch = resolution.height;
			const tw = width;

			return {
				width: tw,
				height: ch / (cw / tw),
			};
		},
		// 等比缩放视频 高
		ScaleResolutionToHeight(resolution, height) {
			const cw = resolution.width;
			const ch = resolution.height;
			const th = height;

			return {
				width: cw / (ch / th),
				height: th,
			};
		},
		// 创建手势识别引擎
		async CreateEngine() {
			let API = IHandTrackingApi;
			if (API) {
				console.log("have API");
				return API.CreateEngine();
			}
			API = await Load("./yoha");
			return API.CreateEngine();
		},
		// 开始识别
		async startDraw() {
			// 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");

			// 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();
			// }

			this.engine.SetUpCustomTrackSource(this.video);
			// await this.engine.SetUpCameraTrackSource();

			gsap.to([this.$refs.handDialog, this.$refs.info], {
				autoAlpha: 1,
				delay: 0.5,
			});
			// 识别引擎启动
			this.engineStart();
		},
		// 识别引擎启动
		engineStart() {
			this.engine.Start((e) => {
				let cursorPos;
				if (e.coordinates) {
					cursorPos = this.ExponentialCoordinateAverage(
						this.ComputeCursorPositionFromCoordinates(e.coordinates)
					);
					// console.log(cursorPos);
				}

				// console.log(e.type);

				if (e.type === EventEnum.RESULT) {
					if (e.poses.fist) {
						this.handStatus = "握拳";
						this.hideAll();
						if (this.handStep == 1) {
							this.handStep++;
						}
						// document.getElementById("status").innerText = "握拳";
					} else if (e.poses.pinch) {
						this.handStatus = "捏合";
						if (this.handStep > 2) {
							this.updatePosition(
								cursorPos[0],
								cursorPos[1],
								0.1
							);
							this.Render();
						}
					} else {
						this.handStatus = "张开";
						if (this.handStep > 2) {
							this.updatePosition(
								cursorPos[0],
								cursorPos[1],
								cursorPos[3]
							);
							this.Render();
						}
						if (this.handStep == 2) {
							this.handStep++;
						}
						// document.getElementById("status").innerText = "张开";
					}
				} else if (e.type === EventEnum.LOST) {
					this.handStatus = "未检测到手";

					this.hideAll();
					// document.getElementById("status").innerText = "未检测到手";
				}
			});
		},
		// 计算坐标值平均数
		ExponentialMovingAverage(value, alpha) {
			if (this.curValue_ === undefined || this.curValue_ === null) {
				this.curValue_ = value;
			} else {
				this.curValue_ = this.curValue_ * (1 - alpha) + value * alpha;
			}
			return this.curValue_;
		},
		// 计算出手指四个点
		ExponentialCoordinateAverage(coord, alpha = 0.85) {
			let xAvg_ = this.ExponentialMovingAverage(coord[0], alpha),
				yAvg_ = this.ExponentialMovingAverage(coord[1], alpha),
				zAbg_ = this.ExponentialMovingAverage(coord[2], alpha),
				aAvg_ = this.ExponentialMovingAverage(coord[3], alpha);

			return [xAvg_, yAvg_, zAbg_, aAvg_];
		},
		// 计算几个点的中间值
		ComputeCursorPositionFromCoordinates(coords) {
			// return [
			// 	(coords[3][0] + coords[7][0]) / 2,
			// 	(coords[3][1] + coords[7][1]) / 2,
			// ];
			if (coords[17][0] < coords[2][0]) {
				// console.log('Right')
				return [
					((coords[0][0] + coords[9][0]) / 2) * 1,
					(coords[0][1] + coords[9][1]) / 2,
					coords[3][0] - coords[18][0],
					coords[3][1] - coords[18][1],
				];
			} else {
				// console.log('Left')
				return [
					((coords[0][0] + coords[9][0]) / 2) * 1.1,
					(coords[0][1] + coords[9][1]) / 2,
					coords[3][0] - coords[18][0],
					coords[3][1] - coords[18][1],
				];
			}
		},
		// init THREELayer
		initTHREELayer(size) {
			this.container = this.$refs.container;
			this.camera_ = new THREE.PerspectiveCamera(
				45,
				window.innerWidth / window.innerHeight,
				0.1,
				2000
			);

			const distance =
				this.video.width /
				(2 * Math.tan((this.camera_.fov * Math.PI) / 360));
			this.camera_.up.set(0, -1, 0);
			this.camera_.position.set(
				this.video.width / 2,
				this.video.height / 2,
				-1000
			);
			console.log("distance:", distance);
			this.camera_.lookAt(
				window.innerWidth / 2,
				window.innerHeight / 2,
				0
			);

			// this.camera_ = new THREE.OrthographicCamera(
			// 	0,
			// 	this.video.width,
			// 	0,
			// 	this.video.height,
			// 	0,
			// 	1500
			// );

			this.clock = new THREE.Clock();

			this.scene_ = new THREE.Scene();

			this.renderer_ = new THREE.WebGLRenderer({
				alpha: true,
				powerPreference: "high-performance",
				failIfMajorPerformanceCaveat: false,
				antialias: true,
			});
			// console.log(this.video.width, this.video.height);
			this.renderer_.debug.checkShaderErrors = false;
			this.renderer_.setSize(window.innerWidth, window.innerHeight);
			this.renderer_.setPixelRatio(window.devicePixelRatio);
			this.renderer_.setClearColor(0x000000, 0.0);
			this.renderer_.autoClear = true;
			this.renderer_.domElement.id = "canvas";
			this.container.appendChild(this.renderer_.domElement);
			// this.renderer_.domElement.width = this.video.width;
			// this.renderer_.domElement.height = this.video.height;

			// add stats dom
			this.stats = new Stats();
			this.container.appendChild(this.stats.dom);

			// this.animate();
			// gsap.to(this.renderer_.domElement, { autoAlpha: 1 });
			// this.drawPoint();
			this.addLineBox();
		},
		// 添加测试小球
		addTestBall() {
			//light
			let mainLight = new THREE.HemisphereLight(0xffffff, 0x444444);
			mainLight.position.set(0, 200, 0);
			var light = new THREE.DirectionalLight(0xffffff);
			var light2 = new THREE.DirectionalLight(0xffffff);
			light.position.set(200, 0, 200);
			light2.position.set(-200, 0, 200);
			this.scene_.add(light);
			this.scene_.add(light2);
			this.scene_.add(mainLight);

			this.group3D = new THREE.Object3D();

			gsap.to(this.group3D.rotation, {
				y: Math.PI * 2,
				repeat: -1,
				duration: 5,
				ease: "none",
			});
			//放入些mesh做实验
			var material = new THREE.MeshLambertMaterial({
				color: "#2194ce",
			});
			// var cubeGeometry = new THREE.CubeGeometry(100, 100, 100);
			var geo2 = new THREE.SphereGeometry(40, 40, 40);
			for (var i = 0; i < 50; i++) {
				var spr = new THREE.Mesh(geo2, material);
				spr.position.set(
					Math.random() * 800 - 400,
					Math.random() * 800 - 400,
					Math.random() * 800 - 400
				);
				this.group3D.add(spr);
			}

			this.scene_.add(this.group3D);

			this.ambientLight = new THREE.AmbientLight(0x8a7e7e, 0.5);
			this.scene_.add(this.ambientLight);
		},
		// 添加线条
		addLineBox() {
			const geometry = new THREE.BufferGeometry();
			const material = new THREE.LineBasicMaterial({
				vertexColors: true,
				opacity: 0.5,
			});

			const positions = [];
			const colors = [];
			const r = this.lineConfig.r;

			for (let i = 0; i < this.lineConfig.segments; i++) {
				const x = Math.random() * r - r / 2;
				const y = Math.random() * r - r / 2;
				const z = Math.random() * r - r / 2;

				// positions

				positions.push(x, y, z);

				// colors

				colors.push(x / r + 0.5);
				colors.push(y / r + 0.5);
				colors.push(z / r + 0.5);
			}

			geometry.setAttribute(
				"position",
				new THREE.Float32BufferAttribute(positions, 3)
			);
			geometry.setAttribute(
				"color",
				new THREE.Float32BufferAttribute(colors, 3)
			);
			this.generateMorphTargets(geometry);

			geometry.computeBoundingSphere();

			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;

			for (let i = 0; i < this.lineConfig.segments; i++) {
				const x = Math.random() * r - r / 2;
				const y = Math.random() * r - r / 2;
				const z = Math.random() * r - r / 2;

				data.push(x, y, z);
			}

			const morphTarget = new THREE.Float32BufferAttribute(data, 3);
			morphTarget.name = "target1";

			geometry.morphAttributes.position = [morphTarget];
		},
		// draw pointer
		drawPoint() {
			const geo_ = new THREE.RingGeometry(0, 10, 32);
			const mat_ = new THREE.MeshBasicMaterial({
				color: "red",
				side: THREE.DoubleSide,
			});
			this.mesh_ = new THREE.Mesh(geo_, mat_);
			this.scene_.add(this.mesh_);
			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) {
			if (!this.renderer_) return;
			gsap.to(this.renderer_.domElement, { autoAlpha: 1 });

			if (this.mesh_) {
				this.mesh_.position.x = x * this.video.width;
				this.mesh_.position.y = y * this.video.height;
				this.mesh_.position.z = 0;
			}

			if (this.group3D) {
				this.group3D.position.x = x * this.video.width;
				this.group3D.position.y = y * this.video.height;
				this.group3D.position.z = 0;
			}
			if (this.lineBox) {
				this.lineBox.position.x = x * this.video.width;
				this.lineBox.position.y = y * this.video.height;
				this.lineBox.position.z = 100;
			}

			if (scale) {
				gsap.to(this.lineBox.scale, { x: scale, y: scale, z: scale });
			} else {
				gsap.to(this.lineBox.scale, { x: 0.15, y: 0.15, z: 0.15 });
			}
		},
		// hide all
		hideAll() {
			if (!this.renderer_) return;
			gsap.to(this.renderer_.domElement, { autoAlpha: 0 });
		},
		animate() {
			requestAnimationFrame(this.animate);
			this.Render();
		},
		// THREE canvas render
		Render() {
			if (!this.renderer_) return;
			this.stats.update();
			this.renderer_.render(this.scene_, this.camera_);
			if (this.lineBox) {
				const delta = this.clock.getDelta();
				const time = this.clock.getElapsedTime();

				this.lineBox.rotation.x = time * 0.25;
				this.lineBox.rotation.y = time * 0.5;

				this.lineConfig.t += delta * 0.5;
				this.lineBox.morphTargetInfluences[0] = Math.abs(
					Math.sin(this.lineConfig.t)
				);
			}
		},
	},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.hand-track {
	.prLayout(100%,100%);
	overflow: hidden;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-content: center;
	align-items: center;
	.video {
		.paLayout(1500%,1500%,auto,100%,0);
		transform: translate(-50%, -50%);
		// width: 750px;
		// display: none;
		// height: 700px;
		&.flip {
			transform: translate(-50%, -50%) scaleX(-1);
		}
	}
	.info-dialog {
		visibility: hidden;
		.paRightLayout(0,0, 50%,130px,2);
		background-color: rgba(255, 255, 255, 0.25);
		border-radius: 0 0 0 30px;
		padding: 20px;
		font-size: 28px;
		display: flex;
		flex-direction: column;
		align-content: center;
		align-items: center;
		text-align: center;
		justify-content: center;
		div {
			width: 100%;
			line-height: 40px;
			color: #fff;
			span {
				font-weight: bold;
				color: #f00;
			}
		}
		.progress {
		}
	}
	.hand-dialog {
		visibility: hidden;
		.paLayout(0,0,100%,100%,11);
		background-color: rgba(0, 0, 0, 0.4);
		color: #fff;
		text-align: center;
		line-height: 50px;
		font-size: 30px;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-content: center;
		align-items: center;
		pointer-events: none;
		.hand {
			margin-top: 20px;
			.prLayout(160px*2.5,277px*2.5);
			.bg-norepeat("hand_1","png");
			background-size: contain;
			&.hand-1 {
				.bg-norepeat("hand_1","png");
				background-size: contain;
			}
			&.hand-2 {
				.bg-norepeat("hand_2","png");
				background-size: contain;
			}
		}
	}
	.canvas-container {
		.paLayout(50%,50%,auto,auto,100);
		transform: translate(-50%, -50%);
		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;
		text-align: center;
		border-radius: 8px;
		font-size: 25px;
		background-image: linear-gradient(to top, #a18cd1 0%, #fbc2eb 100%);
		color: #fff;
	}
	.progress-bar {
		// visibility: hidden;
		.paCenter(50%,80%,40px,12);
		margin-top: -20px;
		border: 2px solid #fff;
		border-radius: 25px;
		padding: 4px;
		.bar {
			.prLayout(100%,100%);
			border-radius: 20px;
			overflow: hidden;
			.progress {
				width: 0%;
				height: 100%;
				background-color: #fff;
			}
		}
	}
	.unsuit-dialog {
		visibility: hidden;
		.paCenterBottom(0, 100%,80px,10);
		position: fixed;
		background-color: rgba(255, 255, 255, 0.35);
		color: #fff;
		line-height: 80px;
		text-align: center;
		font-size: 40px;
	}
}
</style>