UNPKG

pixelstream-cn

Version:

基于虚幻引擎的像素流平台

346 lines (305 loc) 12.2 kB
'use strict'; import TouchEventHandler from './TouchEventHandler'; export default class player { constructor(tools,keyboard,mode,mouseSimulate) { if(mouseSimulate!=null){ this.touchEventHandler = new TouchEventHandler(mouseSimulate); } this.keyboardDowns={}; this.mouseDowns={}; this.keyboard=null; this.tools=tools; this.mode=mode; this.setKeyboard(keyboard); this.isFocus=false; // 是焦点? 焦点状态下才可以输入键盘信息 } setKeyboard(keyboard){ this.keyboard = keyboard; } init(element) { let videoDiv = document.createElement("div"); videoDiv.style.position="absolute"; videoDiv.style.outline="none"; this.videoElement = document.createElement("video"); // this.videoElement.controls=true; this.videoElement.style.width="100%"; this.videoElement.style.height="100%"; this.videoElement.playsInline = true; this.videoElement.autoplay=true; this.videoElement.muted=true; videoDiv.append(this.videoElement); let mouseDiv = document.createElement("div"); mouseDiv.style.height="100%"; mouseDiv.style.width="100%"; mouseDiv.style.position="absolute"; // mouseDiv.style.zIndex=9999; if(this.mode=='stretch'){ videoDiv.style.height="100%"; videoDiv.style.width="100%"; this.videoElement.style.objectFit="fill"; }else{ videoDiv.style.width="100%"; } element.append(videoDiv); if(this.tools){ let toolElement = document.createElement("div"); toolElement.style.height="20px"; toolElement.style.position="absolute"; toolElement.style.zIndex=9999; toolElement.style.top="20px"; toolElement.style.left="20px"; toolElement.style.background="#000"; toolElement.style.color="#fff"; toolElement.style.lineHeight="12px"; toolElement.style.fontSize="12px"; toolElement.style.padding="4px"; toolElement.style.cursor="pointer"; toolElement.style.boxSizing="border-box"; toolElement.innerHTML="锁定鼠标"; toolElement.addEventListener("click",()=>{ videoDiv.requestPointerLock(); }); element.append(toolElement); } this.mouseElement = videoDiv; if(this.touchEventHandler){ this.touchEventHandler.setTargetElement(this.mouseElement); } this.initPlayer(); } audio(stream){ console.log("audio"); this.audioElem = document.createElement("Audio"); this.audioElem.srcObject = stream; } playAudio(){ try { this.audioElem.play(); console.log("playAudio"); } catch (error) { console.log("playAudio fail"); setTimeout(this.playAudio,500); } } play(stream) { this.isPlaying = false; this.videoElement.srcObject = stream; this.videoElement.load(); let _this = this; this.videoElement.addEventListener('loadedmetadata', (e) => { _this.playAudio(); // _this.setPlayerSize(_this.videoElement.videoWidth, _this.videoElement.videoHeight); }); } // setPlayerSize(videoWidth, videoHeight) { // console.log("setPlayerSize",videoWidth, videoHeight); // let radio = this.mouseElement.offsetWidth/videoWidth; // console.log("radio",radio); // } initPlayer() { this.fingers = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]; this.fingerIds = {}; let _this = this // this.mouseElement.onfocus = ()=>{ // console.log("onfocus"); // this.isFocus=true; // } // this.mouseElement.onblur = ()=>{ // console.log("onblur"); // this.isFocus=false; // } // this.mouseElement.setAttribute('tabindex', '0'); this.mouseElement.onmousedown = (e) => { _this.mouseElement.focus(); let coord = _this.normalizeAndQuantizeUnsigned(e.offsetX, e.offsetY); _this.mouseDownHandel(e.button,coord); _this.mouseDowns[e.button]=e; e.preventDefault(); } this.mouseElement.onmouseup = (e) => { let coord = _this.normalizeAndQuantizeUnsigned(e.offsetX, e.offsetY); _this.mouseUpHandel(e.button,coord); delete _this.mouseDowns[e.button]; // e.preventDefault(); }; this.mouseElement.onmousemove = (e) => { _this.isFocus=true; // offsetX 为正 为负 offsetY 为正 为负 let coord = _this.normalizeAndQuantizeUnsigned(e.offsetX, e.offsetY); let delta = _this.normalizeAndQuantizeSigned(e.movementX, e.movementY); _this.mouseMoveHandel(coord,delta); e.preventDefault(); } this.mouseElement.onmouseenter = function (e) { _this.mouseEnterHandel(e); // _this.mouseElement.pressMouseButtons(e); e.preventDefault(); }; this.mouseElement.onmouseleave = (e)=>{ _this.isFocus=false; for(let key in _this.mouseDowns){ _this.mouseElement.onmouseup(_this.mouseDowns[key]); delete _this.mouseDowns[key]; } for(let key in _this.keyboardDowns){ _this.keyboardUpHandel(_this.keyboardDowns[key]); delete _this.keyboardDowns[key]; } _this.mouseLeaveHandel(e); _this.mouseElement.releaseMouseButtons(e); e.preventDefault(); }; this.mouseElement.pressMouseButtons = (e) => { let coord = _this.normalizeAndQuantizeUnsigned(e.offsetX, e.offsetY); _this.mousePressHandel(e.buttons,coord); } this.mouseElement.releaseMouseButtons = (e) => { let coord = _this.normalizeAndQuantizeUnsigned(e.offsetX, e.offsetY); _this.mouseReleaseHandel(e.buttons,coord); } this.videoElement.ontouchstart = (e)=>{ console.log("ontouchstart",e) _this.isFocus=true; if(_this.touchEventHandler){ _this.touchEventHandler.handleTouchStart(e); }else{ for (let t = 0; t < e.changedTouches.length; t++) { _this.rememberTouch(e.changedTouches[t]); } _this.touchStartHandel(_this.getTouchData(e.changedTouches),); } e.preventDefault(); } this.videoElement.ontouchend = function(e) { console.log("ontouchend") _this.isFocus=true; if(_this.touchEventHandler){ _this.touchEventHandler.handleTouchEnd(e); }else{ _this.touchEndHandel(_this.getTouchData(e.changedTouches)); // Re-cycle unique identifiers previously assigned to each touch. for (let t = 0; t < e.changedTouches.length; t++) { _this.forgetTouch(e.changedTouches[t]); } } e.preventDefault(); }; this.videoElement.ontouchmove = function(e) { console.log("ontouchmove") if(_this.touchEventHandler){ _this.touchEventHandler.handleTouchMove(e); }else{ _this.touchMoveHandel(_this.getTouchData(e.touches)); } e.preventDefault(); }; this.mouseElement.addEventListener('contextmenu', (e) => { let coord = _this.normalizeAndQuantizeUnsigned(e.offsetX, e.offsetY); _this.mouseUpHandel(e.button,coord); e.preventDefault(); }) document.onkeydown = function(e) { if(_this.isFocus){ if(!_this.keyboard || _this.keyboard.findIndex(item=>{return item.toLowerCase()==e.key.toLowerCase()})>=0){ _this.keyboardDowns[e.key]=e; _this.keyboardDownHandel(e); e.preventDefault(); //preventDefault 用来阻断后续事件 如keypress } } } document.onkeyup = function(e) { if(_this.isFocus){ if(!_this.keyboard || _this.keyboard.findIndex(item=>{return item.toLowerCase()==e.key.toLowerCase()})>=0){ if(_this.keyboardDowns[e.key]){ delete _this.keyboardDowns[e.key]; } _this.keyboardUpHandel(e); e.preventDefault(); } } } document.onkeypress = function(e) { if(_this.isFocus){ if(!_this.keyboard || _this.keyboard.findIndex(item=>{return item.toLowerCase()==e.key.toLowerCase()})>=0){ _this.keyboardPressHandel(e); e.preventDefault(); } } } if ('onmousewheel' in this.mouseElement) { this.mouseElement.onmousewheel = (e) => { _this.mouseElement.focus(); let coord = _this.normalizeAndQuantizeUnsigned(e.offsetX, e.offsetY); _this.mouseWheelHandel(e.wheelDelta, coord); e.preventDefault(); } } else { this.mouseElement.addEventListener( 'DOMMouseScroll', (e) => { _this.mouseElement.focus(); let coord = _this.normalizeAndQuantizeUnsigned(e.offsetX, e.offsetY); _this.mouseWheelHandel(e.detail * -120, coord); e.preventDefault(); }, false ) } } getTouchData(touches) { let data = []; for (let t = 0; t < touches.length; t++) { let touch = touches[t]; let x = touch.clientX - this.getOffsetLeft(touch.target); let y = touch.clientY - this.getOffsetTop(touch.target); let coord = this.normalizeAndQuantizeUnsigned(x, y); data.push({ coord:coord, finger:this.fingerIds[touch.identifier], force:touch.force, }); } return data; } getOffsetLeft(target){ if(target.offsetParent){ return target.offsetLeft+this.getOffsetLeft(target.offsetParent); } return target.offsetLeft; } getOffsetTop(target){ if(target.offsetParent){ return target.offsetTop+this.getOffsetTop(target.offsetParent); } return target.offsetTop; } rememberTouch(touch) { let finger = this.fingers.pop(); this.fingerIds[touch.identifier] = finger; } forgetTouch(touch) { this.fingers.push(this.fingerIds[touch.identifier]); delete this.fingerIds[touch.identifier]; } normalizeAndQuantizeUnsigned(x, y) { let widthRatio = x / this.mouseElement.clientWidth; //0-1之间占比 let heightRatio = y / this.mouseElement.clientHeight; //0-1之间占比 let normalizedX = widthRatio; let normalizedY = heightRatio; return { inRange: true, x: normalizedX * 65536, y: normalizedY * 65536, } } normalizeAndQuantizeSigned(x, y) { let widthRatio = x / (this.mouseElement.clientWidth / 2); //0-1之间占比 let heightRatio = y / (this.mouseElement.clientHeight / 2); //0-1之间占比 let normalizedX = widthRatio; let normalizedY = heightRatio; return { x: normalizedX * 32767, y: normalizedY * 32767, } } }