基于点击位置的手机控制器(只支持点击事件)
main.js
const creatWS = (to)=>{
if (!store.state.websocket) {
let code = to.query.code
if (code) {
store.state.websocket = new WebSocket('ws://212.64.24.247:3010/')
store.state.websocket.onopen = ()=>{
store.state.websocket.send(JSON.stringify({login:true,groupId:code}))
}
store.state.websocket.onmessage = (e) => {
const json = JSON.parse(JSON.parse(e.data).data)||{}
if (json.code != code ) {
return
}
if (to.path == '/phone') {
return
}
let appClientRect = document.querySelector('#app').getBoundingClientRect()
const pointDom = document.elementFromPoint(appClientRect.width * json.mess[0], appClientRect.height * json.mess[1])
if (pointDom.click) {
pointDom.click()
}
if(pointDom instanceof SVGElement && pointDom.getEventListeners('click')){
pointDom.getEventListeners('click')[0].listener(this)
}
}
}
}
}
router.beforeEach((to, from, next) => {
creatWS(to)
if (!store.state.control) {
store.state.control = Number(to.query.control)
}
next()
});
phone.vue
<template>
<div class="g-contain">
<div
ref="mask"
class="mask"
@click.stop="handelClick"
v-if="!!Number($route.query.control)"
></div>
<iframe
class="iframe"
:src="`${screens[$store.state.activeScreen].path}?code=${$route.query.code}&control=${$route.query.control}`"
frameborder="0"
></iframe>
<!-- <div class="screen-list-wrap" v-drag v-if="!!Number($route.query.control)">
<ul class="screen-list" v-if="close">
<li
v-for="(item, index) in screens"
:key="index"
@click="changeSCreen(index)"
:class="{
active: item.path == screens[$store.state.activeScreen].path,
}"
>
{{ item.name }}
</li>
</ul>
<div class="toggle-btn" @click="close = !close">
{{ close ? "关" : "开" }}
</div>
</div> -->
</div>
</template>
<script>
function debounce(func, wait) {
let timer;
return function () {
let args = arguments; // arguments中存着e
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
export default {
name: "index",
data() {
return {
close: true,
screens: [
{
name: "西湖国际",
path: "/#/ztindex",
},
],
};
},
mounted() {
document.title = "齐圣科技数字化案例中心";
},
destroyed() {},
components: {},
methods: {
send(mess) {
let code = this.$route.query.code;
if (code) {
this.$store.state.websocket.send(JSON.stringify({code:code,mess:mess}));
}
},
handelClick: debounce(function (e) {
const scrollleft =
document.documentElement.scrollLeft || document.body.scrollLeft;
const scrolltop =
document.documentElement.scrollTop || document.body.scrollTop;
const point =
[(scrollleft + e.clientX) /
this.$refs.mask.getBoundingClientRect().width,
(scrolltop + e.clientY) /
this.$refs.mask.getBoundingClientRect().height];
this.send(point);
}, 400),
changeSCreen(index) {
this.send(`changeScreen,${index}`);
},
},
directives: {
drag: {
inserted(el) {
let positionParams = {
x: 20,
y: 20,
startX: 0,
startY: 0,
endX: 0,
endY: 0,
};
el.addEventListener("touchstart", function (e) {
positionParams.startX = e.touches[0].pageX;
positionParams.startY = e.touches[0].pageY;
});
el.addEventListener("touchend", function (e) {
positionParams.x = positionParams.endX;
positionParams.y = positionParams.endY;
positionParams.startX = 0;
positionParams.startY = 0;
});
el.addEventListener("touchmove", function (e) {
if (e.touches.length > 0) {
let offsetX = e.touches[0].pageX - positionParams.startX;
let offsetY = e.touches[0].pageY - positionParams.startY;
let x = positionParams.x - offsetX;
let y = positionParams.y - offsetY;
if (x + el.offsetWidth > document.documentElement.offsetWidth) {
x = document.documentElement.offsetWidth - el.offsetWidth;
}
if (y + el.offsetHeight > document.documentElement.offsetHeight) {
y = document.documentElement.offsetHeight - el.offsetHeight;
}
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
el.style.right = x + "px";
el.style.bottom = y + "px";
positionParams.endX = x;
positionParams.endY = y;
e.preventDefault();
}
});
},
},
},
};
</script>
<style lang="scss" scoped>
@import "../assets/css/mixin";
.g-contain {
position: relative;
width: 100%;
height: 100%;
.iframe,
.mask {
width: 100%;
height: 100%;
}
.mask {
position: absolute;
top: 0;
left: 0;
}
.screen-list {
width: 2rem;
position: absolute;
left: 50%;
bottom:1.5rem;
transform: translateX(-50%);
li {
padding: 0.2rem;
background: #fff;
line-height: 1;
border-radius: 0.05rem;
cursor: pointer;
margin-bottom: 0.2rem;
color: #333;
display: block;
text-align: center;
font-size: 0.2rem;
&.active {
background: #28aa00;
color: #fff;
}
}
}
.screen-list-wrap {
width: 1.5rem;
position: absolute;
z-index: 999;
right: 20px;
bottom: 20px;
.toggle-btn {
width: 1.5rem;
height: 1.5rem;
font-size: 0.5rem;
line-height: 1.5rem;
text-align: center;
border-radius: 50%;
background-color: #fff;
}
}
}
</style>
story/index.js
websocket: null,
activeScreen: 0,
control: 0,
index.html
<script>
(function () {
'use strict';
Element.prototype._addEventListener = Element.prototype.addEventListener;
Element.prototype._removeEventListener = Element.prototype.removeEventListener;
Element.prototype.addEventListener = function (type, listener, useCapture = false, notes) {
this._addEventListener(type, listener, useCapture);
if (!this.eventListenerList) this.eventListenerList = {};
if (!this.eventListenerList[type]) this.eventListenerList[type] = [];
this.eventListenerList[type].push({ type, listener, useCapture, notes });
};
Element.prototype.removeEventListener = function (type, listener, useCapture = false) {
this._removeEventListener(type, listener, useCapture);
if (!this.eventListenerList) this.eventListenerList = {};
if (!this.eventListenerList[type]) this.eventListenerList[type] = [];
for (let i = 0; i < this.eventListenerList[type].length; i++) {
if (this.eventListenerList[type][i].listener === listener && this.eventListenerList[type][i].useCapture === useCapture) {
this.eventListenerList[type].splice(i, 1);
break;
}
}
if (this.eventListenerList[type].length == 0) delete this.eventListenerList[type];
};
Element.prototype.getEventListeners = function (type) {
if (!this.eventListenerList) this.eventListenerList = {};
if (type === undefined) return this.eventListenerList;
return this.eventListenerList[type];
};
})();
</script>