拖动时候用到的三个事件:mousedown
、mousemove
、mouseup
在移动端都不起任何作用。毕竟移动端是没有鼠标的,查资料后发现,在移动端与之相对应的分别是:touchstart
、touchmove
、touchend
事件。还有一点要注意的是在PC端获取当前鼠标的坐标是:event.clientX
和event.clientY
,在移动端获取坐标位置则是:event.touches[0].clientX
和event.touches[0].clientY
。
制作一个摇杆按钮
<template>
<div style="position: relative;">
<!-- 事实传输数据 -->
<!-- <websocket :x="sendleft" :y="sendtop" ref="ws" /> -->
<div
class="toucharea"
@touchstart="onTouchStart"
@touchmove="onTouchMove"
@touchcancel="onTouchEnd"
@touchend="onTouchEnd"
@mousedown="onTouchStartPC"
@mousemove="onTouchMovePC"
@mouseup="onTouchEndPC"
>
<div
style="border-radius: 50%;"
:style="{width:touchRadius*2+'px',height:touchRadius*2+'px'}"
></div>
</div>
<div
class="ball"
:style="{left:left+'px',top:top+'px'}"
:class="(inDraging === false && transition)?'animation':''"
>
<slot name="ball">
<div style="width: 60px;height: 60px;border-radius: 50%;"></div>
</slot>
</div>
<!-- :class="{animation:inDraging===false&&transition}" -->
<div
class="stick"
:class="(inDraging === false && transition)?'animation':''"
:style="{height: stickHeight+'px',transform:'translateX(-50%)'}"
>
<div
:style="{transform:'rotate('+(angle/(3.14159/180)-90)+'deg)'}"
style="transform-origin: 50% 0%;width: 100%;height: 100%;"
>
<slot name="stick"></slot>
</div>
</div>
<div class="bottom">
<slot name="bottom"></slot>
</div>
</div>
</template>
<script>
// import websocket from "./websocket.vue";
import { writeApi, readApi } from "../request/api.js";
import mqtt from "mqtt/dist/mqtt";
// import AppVue from "@/App.vue";
var startLeft, startTop;
var timer;
var getDistance = function(x1, y1, x2, y2) {
var _x = Math.abs(x1 - x2); //返回绝对值
var _y = Math.abs(y1 - y2);
// console.log("x坐标是", _x);
// console.log("y坐标是", _y);
return Math.sqrt(_x * _x + _y * _y); //返回平方根,到圆心的距离
};
export default {
data() {
return {
// sendleft: 156,
// sendtop: 152,
sendleft: 0,
sendtop: 0,
left: 0,
top: 0,
stickHeight: 0,
angle: 0,
inDraging: false,
reqTimer: null,
//心跳检测装置
heartCheck: {
thimeout: 2000,
timeoutObj: null,
reset: function() {
//接收成功一次推送,就将心跳检测的计时器为2秒
clearTimeout(this.timeoutObj);
this.start();
},
start: function() {
this.timeoutObj = setTimeout(() => {
var message = {
type: "t10010",
servive: "发送维持连接消息!"
};
console.log("发送维持连接消息");
ws.send(JSON.stringify(message)); //启动心跳
}, this.thimeout);
}
},
bootConnect: {
shipId: "",
tcp: ""
},
//
client: "",
options: {
port: 8083, //端口号
connectTimeout: 4000,
// clientId:
// "mqtt_lih" +
// Math.random()
// .toString(16)
// .substr(2, 8),
// clientId:
// "mqtt_lih" +
// Math.random()
// .toString(16)
// .substr(2, 8),
clientId: "mqtt_lih",
username: JSON.parse(localStorage.getItem("userMsg")).username || "",
password: JSON.parse(localStorage.getItem("userMsg")).password || "",
clean: true
}
};
},
props: {
//触摸识别区域的半径
touchRadius: {
type: Number,
default: 100
},
//杆头的移动范围半径,也就是杆体的长度
ballMoveRadius: {
type: Number,
default: 50
},
transition: {
type: Boolean,
default: false
}
},
created() {
// let _this = this;
// var baseApi = localStorage.getItem("baseApi") || "";
// this.client = mqtt.connect(
// "ws://" + baseApi + ":" + "1883" + "/mqtt",
// _this.options
// );
// this.client = mqtt.connect(
// "ws://" + "192.168.221.62" + ":" + "1883" + "/mqtt",
// _this.options
// );
},
mounted() {
document.addEventListener("mouseup", this.onTouchEndPC);
this.loop();
//启用定时器
let _this = this;
this.reqTimer = setInterval(() => {
if (
this.$store.state.bootMsg.CurrentMode == 1
// this.$store.state.bootMsg.Status == 2 ||
// this.$store.state.bootMsg.Status == 4
) {
console.log("不发送");
} else {
_this.sendMsg();
console.log("发送的是" + this.sendleft + "和" + this.sendtop);
}
}, 500);
},
methods: {
sendMsg() {
// alert(1);
// AppVue.aNewFunction();
// this.$root.aNewFunction();
let keyWord =
"0 67 4 124 " +
"0 " +
this.sendleft.toString() +
" 1 " +
this.sendtop.toString() +
" " +
Math.floor((this.sendleft + this.sendtop + 1) / 256).toString() +
" " +
((this.sendleft + this.sendtop + 1) % 256).toString() +
" 13 10";
this.bootConnect = JSON.parse(localStorage.getItem("bootConnect"));
// //MainType: 18,
// // shipId: "110", //船id
// // tcp: "fg.yunenjoy.cn:50113",
// writeApi({
// ...this.bootConnect,
// command: keyWord
// }).then(res => {
// console.log(res);
// });
// this.client.publish.topic
// this.mqttConnect.doPublish(
// JSON.stringify({ ...this.bootConnect, command: keyWord })
// );
this.doPublish(JSON.stringify({ ...this.bootConnect, command: keyWord }));
},
//MQTT发送数据
doPublish(payload) {
let obj = {
timestamp: 111,
type: "manualControl",
framecnt: 1,
data: {
throttle: this.sendtop,
rudder: this.sendleft
}
};
this.mqttConnect.doPublish(JSON.stringify(obj));
// this.mqttConnect.doPublish(payload);
// this.client.publish(
// "ship/push/" +
// JSON.parse(localStorage.getItem("userInfo")).lastOperationShip.seq ||
// "",
// payload,
// { qos: 0 },
// error => {
// if (error) {
// console.log("Publish error", error);
// }
// }
// );
},
sssfn() {
alert(1);
},
onTouchStart(e) {
var curTouch = e.touches[0];
startLeft = curTouch.clientX - this.left;
startTop = curTouch.clientY - this.top;
this.inDraging = true;
},
onTouchStartPC(e) {
console.log("-------onTouchStartPC---------");
// alert(this.left);
console.log(e);
startLeft = e.clientX - (this.left || 0);
startTop = e.clientY - (this.top || 0);
this.inDraging = true;
},
onTouchMovePC(e) {
// console.log("-------onTouchMovePC---------");
// console.log(e);
if (this.inDraging) {
var tleft = e.clientX - startLeft;
var ttop = e.clientY - startTop;
var distance = getDistance(tleft, ttop, 0, 0);
if (distance >= this.ballMoveRadius) {
// alert("大于半径");
distance = this.ballMoveRadius;
}
var angle = Math.atan2(ttop - 0, tleft - 0);
this.left = Math.cos(angle) * distance;
this.top = Math.sin(angle) * distance;
console.log();
this.stickHeight = distance;
this.angle = angle;
//需要发送的距离
// /100 -> /65
// this.sendleft = Math.floor(150 + (this.left / 65) * 38);
// this.sendtop = Math.floor(152 - (this.top / 65) * 46);
this.sendleft = (this.left / 65) * 100;
this.sendtop = -(this.top / 65) * 100;
}
console.log("---------e.clientX-------" + e.clientX + "---------------");
console.log("---------startLeft-------" + startLeft + "---------------");
console.log("---------left-------" + this.left + "---------------");
// this.$refs.ws.sendPostion();
},
onTouchEndPC(e) {
// console.log("-------onTouchEndPC---------");
// console.log(e);
this.stickHeight = this.left = this.top = 0;
this.inDraging = false;
//复原便宜坐标
this.sendleft = 0;
this.sendtop = 0;
},
onTouchMove(e) {
// console.log(e);
var curTouch = e.touches[0];
var tleft = curTouch.clientX - startLeft;
var ttop = curTouch.clientY - startTop;
var distance = getDistance(tleft, ttop, 0, 0);
if (distance >= this.ballMoveRadius) {
// alert("大于半径");
distance = this.ballMoveRadius;
}
var angle = Math.atan2(ttop - 0, tleft - 0);
this.left = Math.cos(angle) * distance;
this.top = Math.sin(angle) * distance;
this.stickHeight = distance;
this.angle = angle;
//需要发送的距离
// /100 -> /65
// this.sendleft = Math.floor(150 + (this.left / 65) * 38);
// this.sendtop = Math.floor(152 - (this.top / 65) * 46);
this.sendleft = (this.left / 65) * 100;
this.sendtop = -(this.top / 65) * 100;
// this.$refs.ws.sendPostion();
},
onTouchEnd(e) {
this.stickHeight = this.left = this.top = 0;
this.inDraging = false;
//复原便宜坐标
this.sendleft = 0;
this.sendtop = 0;
// this.$emit("onJoyStickCancel");
},
loop() {
requestAnimationFrame(this.loop);
if (this.inDraging) {
// console.log(
// "角度:" +
// this.angle +
// ",x偏移" +
// this.left +
// ",y偏移" +
// this.top +
// ",power:" +
// this.stickHeight / this.ballMoveRadius
// );
// this.$emit("onJoyStickUpdate", {
// angle: this.angle,
// direction: { x: this.left, y: this.top },
// power: this.stickHeight / this.ballMoveRadius
// });
}
},
readBoot() {
this.bootConnect = JSON.parse(localStorage.getItem("bootConnect"));
readApi({
//MianType: 18,
// tcp: "fg.yunenjoy.cn:50113",
// shipId: "110"
...this.bootConnect
});
}
},
// components: { websocket },
beforeDestroy() {
document.removeEventListener("mouseup");
clearInterval(this.reqTimer);
this.reqTimer = null;
this.bootConnect = JSON.parse(localStorage.getItem("bootConnect"));
//退出手动模式指令
// writeApi({
// //MainType: 18,
// // shipId: "110", //船id
// // tcp: "fg.yunenjoy.cn:50113",
// ...this.bootConnect,
// command: "0 67 3 124 194 13 10"
// }).then(res => {
// console.log(res);
// });
},
destroyed() {
clearInterval(this.reqTimer);
this.reqTimer = null;
}
};
</script>
<style lang="less" scoped>
.toucharea {
user-select: none;
position: absolute;
z-index: 4;
transform: translate(-50%, -50%);
border-radius: 50%;
}
.ball {
position: absolute;
z-index: 3;
transform: translate(-50%, -50%);
}
.stick {
position: absolute;
z-index: 2;
}
.ball.animation {
transition: left 0.1s ease-out, top 0.1s ease-out;
}
.stick.animation {
transition: all 0.2s ease-out;
}
.bottom {
position: absolute;
z-index: 1;
transform: translate(-50%, -50%);
}
</style>
源码:https://github.com/ezshine/ezjoystick
csdn友连:https://blog.csdn.net/ezshine/article/details/124312109
Comments | NOTHING