演示地址:http://tools.pt.wsing.cn/VirtualRocker/
源码下载地址:https://download.csdn.net/download/lyp1215/87583275
触摸屏手动摇杆,根据移动距离触发跟踪事件得到参数:
参数 | 说明 |
VirtualRockerID | 手柄ID |
evType | 状态:开始、移动、停止 |
deltaX | X轴偏移量 |
deltaY | Y轴偏移量 |
方法:
名称 | 描述 | 参数 |
Init2Axis | 初始一个2轴的控制UI | |
Init3Axis | 初始一个3轴的控制UI | |
AddVirtualRocker | 添加一个摇杆 | diameter 手柄直径 x 手柄在页面显示位置 X 坐标 y 手柄在页面显示位置 Y 坐标 crossDirection 十字方向 xAxisNum 手柄移动的X坐标对应板卡轴编号 yAxisNum 手柄移动的Y坐标对应板卡轴编号 |
AddButton_Circle | 添加圆形按钮 | title 按钮文字 diameter 按钮直径 x 按钮在页面显示位置 X 坐标 y 按钮在页面显示位置 Y 坐标 |
AddButton_Radius | 添加圆角按钮 | title 按钮文字 diameter 按钮直径 x 按钮在页面显示位置 X 坐标 y 按钮在页面显示位置 Y 坐标 click_Callback 点击回调事件 |
摇杆主要代码:
/*
参数说明:
diameter 手柄直径
x 手柄在页面显示位置 X 坐标
y 手柄在页面显示位置 Y 坐标
crossDirection 十字方向
xAxisNum 手柄移动的X坐标对应板卡轴编号
yAxisNum 手柄移动的Y坐标对应板卡轴编号
*/
function AddVirtualRocker(diameter, x, y, crossDirection, xAxisNum, yAxisNum) {
//添加摇杆
crossDirection = crossDirection || false;
var current_CrossDirection = "";
var radius = diameter / 2;
var virtualRockerDiameter = radius;
var virtualRockerRadius = virtualRockerDiameter / 2;
var $VirtualRockerBox = $("<div data-kq='control' data-type='VirtualRocker' class='VirtualRockerBox' style='width:" + diameter + "px;height:" + diameter + "px;border-radius:" + diameter + "px;left:" + x + "px; top:" + y + "px;'></div>");
var $VirtualRocker = $("<div class='VirtualRocker' style='width:" + virtualRockerDiameter + "px;height:" + virtualRockerDiameter + "px;left:" + virtualRockerRadius + "px; top:" + virtualRockerRadius + "px;'></div>");
$("body").append($VirtualRockerBox);
$VirtualRockerBox.append($VirtualRocker);
if (crossDirection) {
var $VirtualRockerLineX = $("<div class='VirtualRockerLineX' style='left:0px; top:" + radius + "px;'></div>");
var $VirtualRockerLineY = $("<div class='VirtualRockerLineY' style='left:" + radius + "px; top:0px;'></div>");
$VirtualRockerBox.append($VirtualRockerLineX);
$VirtualRockerBox.append($VirtualRockerLineY);
}
var virtualRockerMove = false;
var startX, startY, moveEndX, moveEndY;
var virtualRockerStartX, virtualRockerStartY;
var hammer1 = "";
var hammer2 = "";
var vid = ++_virtualRockerID;
var panId = 0;
var hammerVirtualRocker = new Hammer($VirtualRocker[0]);
hammerVirtualRocker.get('pan').set({ direction: Hammer.DIRECTION_ALL });
hammerVirtualRocker.on('panstart panmove panend pancancel', function (ev) {
if (vid == 1) {
hammer1 += (++panId) + ".VirtualRockerID:" + vid + " evType:" + ev.type + " deltaX:" + ev.deltaX + " deltaY:" + ev.deltaY + "<br>";
$("#divTips2").html(hammer1);
}
else if (vid == 2) {
hammer2 += (++panId) + ".VirtualRockerID:" + vid + " evType:" + ev.type + " deltaX:" + ev.deltaX + " deltaY:" + ev.deltaY + "<br>";
$("#divTips2").html(hammer2);
}
if (ev.type == "panstart") {
panStart(ev);
}
else if (ev.type == "panmove") {
panMove(ev);
}
else if (ev.type == "panend" || ev.type == "pancancel") {
panEnd(ev);
}
});
function panStart(e) {
/ /开始移动
startX = e.deltaX;
startY = e.deltaY;
virtualRockerStartX = $VirtualRocker.position().left;
virtualRockerStartY = $VirtualRocker.position().top;
virtualRockerMove = true;
};
function panMove(e) {
if (!virtualRockerMove) return;
moveEndX = e.deltaX;
moveEndY = e.deltaY;
var moveX = moveEndX - startX, moveY = moveEndY - startY;
moveX += virtualRockerStartX;
moveY += virtualRockerStartY;
//超出宽度
if (moveX <= -virtualRockerRadius) moveX = -virtualRockerRadius;
if ((moveX + virtualRockerDiameter) > (diameter + virtualRockerRadius)) moveX = (diameter - virtualRockerRadius);
if (moveY <= -virtualRockerRadius) moveY = -virtualRockerRadius;
if ((moveY + virtualRockerDiameter) > (diameter + virtualRockerRadius)) moveY = (diameter - virtualRockerRadius);
//遥感内圈圆点
var virtualRockerX = moveX + virtualRockerRadius, virtualRockerY = moveY + virtualRockerRadius;
//移动的距离大于半径时
var moveRadius = Math.sqrt(Math.pow(Math.abs((virtualRockerX) - radius), 2) + Math.pow(Math.abs((virtualRockerY) - radius), 2));
if (moveRadius > radius) {
var isLeft = virtualRockerX - radius < 0;
var isTop = virtualRockerY - radius < 0;
var p = GetPoint(radius, radius, virtualRockerX, virtualRockerY, radius, radius, radius);
if (isLeft) p = p[1];
else p = p[0];
moveX = p.x - virtualRockerRadius;
moveY = p.y - virtualRockerRadius;
}
var isLeft = (moveX + virtualRockerRadius) - radius < 0;
var isRight = (moveX + virtualRockerRadius) - radius > 0;
var isTop = (moveY + virtualRockerRadius) - radius < 0;
var isBottom = (moveY + virtualRockerRadius) - radius > 0;
if (crossDirection) {
//十字方向
if (current_CrossDirection == "") {
if (parseInt(Math.abs(moveX - radius + virtualRockerRadius)) > parseInt(Math.abs(moveY - radius + virtualRockerRadius))) {
//X
moveY = virtualRockerRadius;
if (current_CrossDirection == "") current_CrossDirection = "X";
}
else {
//Y
moveX = virtualRockerRadius;
if (current_CrossDirection == "") current_CrossDirection = "Y";
}
}
else {
if (current_CrossDirection == "X") {
moveY = virtualRockerRadius;
}
else if (current_CrossDirection == "Y") {
moveX = virtualRockerRadius;
}
}
}
var posX = parseInt(moveX - radius + virtualRockerRadius);
var posY = -parseInt(moveY - radius + virtualRockerRadius);
//
var text = _isOpenGas ? "已连接" : "未连接";
text += " ";
text += isLeft ? "左" : isRight ? "右" : "";
text += isTop ? "上" : isBottom ? "下" : "";
text += " ";
text += " X(" + xAxisNum + "):" + posX;
text += " Y(" + yAxisNum + "):" + posY;
$("#divTips").text(text);
//
if (_isOpenGas && (xAxisNum != 0 || yAxisNum != 0)) {
//摇杆
JsInterface.VirtualRocker(xAxisNum, yAxisNum, posX, posY, function (flag, msg) {
if (!flag) {
$("#divTips").text(msg);
}
});
}
$VirtualRocker.css({ left: moveX + "px", top: moveY + "px" });
ShowVirtualRockerInfo(moveX, moveY);
};
function panEnd(e) {
//停止移动
virtualRockerMove = false;
current_CrossDirection = "";
if (_isOpenGas) {
//停止运动
JsInterface.Stop(function (flag, msg) {
if (!flag) {
Wsfly.Tips.Info(msg);
}
});
}
$VirtualRocker.css({ left: virtualRockerRadius + "px", top: virtualRockerRadius + "px" });
HideVirtualRockerInfo();
};
function ShowVirtualRockerInfo(moveX, moveY) {
//显示摇杆信息
var isLeft = (moveX + virtualRockerRadius) - radius < 0;
var isRight = (moveX + virtualRockerRadius) - radius > 0;
var isTop = (moveY + virtualRockerRadius) - radius < 0;
var isBottom = (moveY + virtualRockerRadius) - radius > 0;
var text = isLeft ? "左" : isRight ? "右" : "";
text += isTop ? "上" : isBottom ? "下" : "";
text += "X:" + parseInt(Math.abs(moveX - radius + virtualRockerRadius));
text += " Y:" + parseInt(Math.abs(moveY - radius + virtualRockerRadius));
$("#divVirtualRockerInfo").text(text);
}
function HideVirtualRockerInfo() {
$("#divVirtualRockerInfo").text("");
}
/**
* 求圆和直线之间的交点
* 直线方程:y = kx + b
* 圆的方程:(x - m)² + (x - n)² = r²
* x1, y1 = 线坐标1, x2, y2 = 线坐标2, m, n = 圆坐标, r = 半径
*/
function GetPoint(x1, y1, x2, y2, m, n, r) {
let kbArr = binaryEquationGetKB(x1, y1, x2, y2)
let k = kbArr[0]
let b = kbArr[1]
let aX = 1 + k * k
let bX = 2 * k * (b - n) - 2 * m
let cX = m * m + (b - n) * (b - n) - r * r
let insertPoints = []
let xArr = quadEquationGetX(aX, bX, cX)
xArr.forEach(function (x) {
let y = k * x + b
insertPoints.push({ x: x, y: y })
})
return insertPoints
}
/**
* 求二元一次方程的系数
* y1 = k * x1 + b => k = (y1 - b) / x1
* y2 = k * x2 + b => y2 = ((y1 - b) / x1) * x2 + b
*/
function binaryEquationGetKB(x1, y1, x2, y2) {
let k = (y1 - y2) / (x1 - x2)
let b = (x1 * y2 - x2 * y1) / (x1 - x2)
return [k, b]
}
/**
* 一元二次方程求根
* ax² + bx + c = 0
*/
function quadEquationGetX(a, b, c) {
let xArr = []
let result = Math.pow(b, 2) - 4 * a * c
if (result > 0) {
xArr.push((-b + Math.sqrt(result)) / (2 * a))
xArr.push((-b - Math.sqrt(result)) / (2 * a))
} else if (result == 0) {
xArr.push(-b / (2 * a))
}
return xArr
}
};