Joystick.js
function Joystick(id) {
let canvas = document.getElementById(id);
let nei = new Image();
let wai = new Image();
let waiSize = canvas.height;
let neiSize = waiSize * 0.6;
let centerX = waiSize / 2;
let centerY = waiSize / 2;
let touchX = canvas.offsetLeft,
touchY = canvas.offsetTop;
let jc = canvas.getContext("2d");
let jx = 0,
jy = 0;
let timeId;
nei.onload = () =>
jc.drawImage(
nei,
centerX - neiSize / 2,
centerY - neiSize / 2,
neiSize,
neiSize
);
wai.onload = () =>
jc.drawImage(
wai,
centerX - waiSize / 2,
centerY - waiSize / 2,
waiSize,
waiSize
);
function move() {
jc.clearRect(
centerX - waiSize / 2,
centerY - waiSize / 2,
waiSize,
waiSize
);
jc.drawImage(
wai,
centerX - waiSize / 2,
centerY - waiSize / 2,
waiSize,
waiSize
);
jc.drawImage(
nei,
centerX - neiSize / 2 + jx,
centerY - neiSize / 2 + jy,
neiSize,
neiSize
);
requestAnimationFrame(move);
}
nei.src = require("../assets/imgs/probe/nei.png");
wai.src = require("../assets/imgs/probe/wai.png");
move();
let effectiveFinger = -1;
function callback() {
loop();
sCallback(jx, jy);
}
function loop() {
if (timeId) {
requestAnimationFrame(callback);
}
}
function ontouchstart(event) {
for (let i = 0; i < event.touches.length; i = i + 1) {
if (
Math.sqrt(
Math.pow(event.touches[i].clientX - centerX - touchX, 2) +
Math.pow(event.touches[i].clientY - centerY - touchY, 2)
) <=
waiSize / 2 - neiSize / 2
) {
effectiveFinger = i;
console.log("finger No." + i + " is effectiveFinger now.");
if (timeId) timeId = null;
timeId = true;
loop();
}
}
}
function ontouchend(event) {
if (timeId) timeId = null;
if (event.touches[effectiveFinger] == null) {
if (event.touches[0] == null) {
jx = 0;
jy = 0;
}
effectiveFinger -= 1;
}
}
function ontouchmove(event) {
if (effectiveFinger !== -1)
if (
Math.sqrt(
Math.pow(
event.touches[effectiveFinger].clientX - centerX - touchX,
2
) +
Math.pow(
event.touches[effectiveFinger].clientY - centerY - touchY,
2
)
) <=
waiSize / 2 - neiSize / 2
) {
jx = event.touches[effectiveFinger].clientX - centerX - touchX;
jy = event.touches[effectiveFinger].clientY - centerY - touchY;
} else {
let x = event.touches[effectiveFinger].clientX - touchX,
y = event.touches[effectiveFinger].clientY - touchY,
r = waiSize / 2 - neiSize / 2;
let ans = GetPoint(centerX, centerY, r, centerX, centerY, x, y);
if (
Math.sqrt((ans[0] - x) * (ans[0] - x) + (ans[1] - y) * (ans[1] - y)) <
Math.sqrt((ans[2] - x) * (ans[2] - x) + (ans[3] - y) * (ans[3] - y))
) {
jx = ans[0] - centerX;
jy = ans[1] - centerY;
} else {
jx = ans[2] - centerX;
jy = ans[3] - centerY;
}
}
}
canvas.addEventListener("touchstart", ontouchstart);
canvas.addEventListener("touchmove", ontouchmove);
canvas.addEventListener("touchend", ontouchend);
requestAnimationFrame(move);
function GetPoint(cx, cy, r, stx, sty, edx, edy) {
let k = (edy - sty) / (edx - stx);
let b = edy - k * edx;
let x1, y1, x2, y2;
let c = cx * cx + (b - cy) * (b - cy) - r * r;
let a = 1 + k * k;
let b1 = 2 * cx - 2 * k * (b - cy);
let tmp = Math.sqrt(b1 * b1 - 4 * a * c);
x1 = (b1 + tmp) / (2 * a);
y1 = k * x1 + b;
x2 = (b1 - tmp) / (2 * a);
y2 = k * x2 + b;
return [x1, y1, x2, y2];
}
}
function getDirection(pos) {
var rad = Math.atan2(pos.y, pos.x);
if ((rad >= -Math.PI / 8 && rad < 0) || (rad >= 0 && rad < Math.PI / 8)) {
} else if (rad >= Math.PI / 8 && rad < (3 * Math.PI) / 8) {
} else if (rad >= (3 * Math.PI) / 8 && rad < (5 * Math.PI) / 8) {
} else if (rad >= (5 * Math.PI) / 8 && rad < (7 * Math.PI) / 8) {
} else if (
(rad >= (7 * Math.PI) / 8 && rad < Math.PI) ||
(rad >= -Math.PI && rad < (-7 * Math.PI) / 8)
) {
} else if (rad >= (-7 * Math.PI) / 8 && rad < (-5 * Math.PI) / 8) {
} else if (rad >= (-5 * Math.PI) / 8 && rad < (-3 * Math.PI) / 8) {
} else {
}
}
var sCallback;
Joystick.prototype._addCallback = function (fn) {
sCallback = fn;
};
export default Joystick;
demo.vue
<template>
<div class="joystick-content">
<canvas id="joystick"
width="150"
height="150"></canvas>
</div>
</template>
<script>
import Joystick from "../plugins/Joystick.js";
export default{
mounted(){
this.joystick = new Joystick("joystick");
this.joystick._addCallback(this.joyCb);
},
methods: {
joyCb(x, y) {
y = y * -1;
console.log(x, y, "joyCD");
this.getDirection({ x, y })
},
getDirection(pos) {
var rad = Math.atan2(pos.y, pos.x);
if ((rad >= -Math.PI / 8 && rad < 0) || (rad >= 0 && rad < Math.PI / 8)) {
console.log("右");
} else if (rad >= Math.PI / 8 && rad < (3 * Math.PI) / 8) {
console.log("右上");
} else if (rad >= (3 * Math.PI) / 8 && rad < (5 * Math.PI) / 8) {
console.log("上");
} else if (rad >= (5 * Math.PI) / 8 && rad < (7 * Math.PI) / 8) {
console.log("左上");
} else if (
(rad >= (7 * Math.PI) / 8 && rad < Math.PI) ||
(rad >= -Math.PI && rad < (-7 * Math.PI) / 8)
) {
console.log("左");
} else if (rad >= (-7 * Math.PI) / 8 && rad < (-5 * Math.PI) / 8) {
console.log("左下");
} else if (rad >= (-5 * Math.PI) / 8 && rad < (-3 * Math.PI) / 8) {
console.log("上");
} else {
console.log("右下");
}
const data = {
x: (pos.x / 30.0).toFixed(2),
y: (pos.x / 30.0).toFixed(2),
};
},
}
}
</script>