diff --git a/index.html b/index.html
index f6d9909..a6527c6 100644
--- a/index.html
+++ b/index.html
@@ -199,7 +199,7 @@ if scale < 1:
-
+
diff --git a/script.js b/script.js
index 56be202..c6aef35 100644
--- a/script.js
+++ b/script.js
@@ -24,13 +24,13 @@ class Joystick {
this.ctx.beginPath();
this.ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
- this.ctx.fillStyle = '#5554';
+ this.ctx.fillStyle = rootStyles.getPropertyValue('--primary-dark-blue');
this.ctx.fill();
this.ctx.beginPath();
this.ctx.arc(this.nubX, this.nubY, this.radius / 3, 0, Math.PI * 2);
- this.ctx.fillStyle = '#445bcaff';
+ this.ctx.fillStyle = rootStyles.getPropertyValue('--accent-blue');
this.ctx.fill();
this.ctx.restore();
@@ -61,6 +61,11 @@ class Joystick {
}
}
+ reset() {
+ this.nubX = this.x;
+ this.nubY = this.y;
+ }
+
getX() {
return (this.nubX - this.x) / this.radius;
}
@@ -464,7 +469,7 @@ controlModeToggle.addEventListener('click', () => {
// Switch to slider mode
sliderControls.style.display = 'block';
keyboardControls.style.display = 'none';
- controlModeToggle.textContent = 'Switch to Keyboard Controls (WASD + QE)';
+ controlModeToggle.textContent = 'Switch to Keyboard/Joystick Controls';
// Reset manual input state
Object.keys(keyState).forEach(key => keyState[key] = false);
@@ -637,8 +642,15 @@ applyCustomBtn.addEventListener('click', () => {
function convertTouchToCanvas(inCoords) {
const rect = canvas.getBoundingClientRect();
- const x = inCoords.x - rect.left - canvas.width / 2;
- const y = inCoords.y - rect.top - canvas.height / 2;
+
+ // Calculate the scale factor between display size and canvas internal size
+ const scaleX = canvas.width / rect.width;
+ const scaleY = canvas.height / rect.height;
+
+ // Convert client coordinates to canvas coordinates, accounting for scaling
+ const x = (inCoords.x - rect.left) * scaleX - canvas.width / 2;
+ const y = (inCoords.y - rect.top) * scaleY - canvas.height / 2;
+
return { x, y };
}
@@ -659,6 +671,74 @@ canvas.addEventListener('mouseup', (event) => {
rightJoystick.deactivate();
});
+// Touch event listeners for mobile/tablet support
+canvas.addEventListener('touchstart', (event) => {
+ event.preventDefault(); // Prevent scrolling and default touch behavior
+
+ for (let i = 0; i < event.touches.length; i++) {
+ const touch = event.touches[i];
+ const canvasCoords = convertTouchToCanvas({ x: touch.clientX, y: touch.clientY });
+ // alert(`X: ${canvasCoords.x}, Y: ${canvasCoords.y}`);
+ leftJoystick.checkShouldActivate(canvasCoords.x, canvasCoords.y);
+ rightJoystick.checkShouldActivate(canvasCoords.x, canvasCoords.y);
+ }
+});
+
+canvas.addEventListener('touchmove', (event) => {
+ event.preventDefault(); // Prevent scrolling while using joysticks
+
+ for (let i = 0; i < event.touches.length; i++) {
+ const touch = event.touches[i];
+ const canvasCoords = convertTouchToCanvas({ x: touch.clientX, y: touch.clientY });
+ leftJoystick.processTouch(canvasCoords.x, canvasCoords.y);
+ rightJoystick.processTouch(canvasCoords.x, canvasCoords.y);
+ }
+});
+
+canvas.addEventListener('touchend', (event) => {
+ event.preventDefault();
+
+ // If no touches remain, deactivate both joysticks
+ if (event.touches.length === 0) {
+ leftJoystick.deactivate();
+ rightJoystick.deactivate();
+ } else {
+ // Check if the remaining touches are still in range of the joysticks
+ let leftStillActive = false;
+ let rightStillActive = false;
+
+ for (let i = 0; i < event.touches.length; i++) {
+ const touch = event.touches[i];
+ const canvasCoords = convertTouchToCanvas({ x: touch.clientX, y: touch.clientY });
+
+ if (leftJoystick.touchInRange(canvasCoords.x, canvasCoords.y)) {
+ leftStillActive = true;
+ }
+ if (rightJoystick.touchInRange(canvasCoords.x, canvasCoords.y)) {
+ rightStillActive = true;
+ }
+ }
+
+ if (!leftStillActive) {
+ leftJoystick.deactivate();
+ leftJoystick.reset();
+ }
+ if (!rightStillActive) {
+ rightJoystick.deactivate();
+ rightJoystick.reset();
+ }
+ }
+});
+
+canvas.addEventListener('touchcancel', (event) => {
+ // Handle touch cancellation (e.g., when system interrupts)
+ leftJoystick.deactivate();
+ leftJoystick.reset();
+ rightJoystick.deactivate();
+ rightJoystick.reset();
+});
+
+
/*
* END LISTENER CODE
* BEGIN DYNAMIC DOM FUNCTIONS
@@ -934,9 +1014,6 @@ function animate() {
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
- leftJoystick.draw();
- rightJoystick.draw();
-
// Update speeds based on control mode
if (isManualInputMode) {
const maxSpeed = parseFloat(keyboardMaxSpeed.value);
@@ -986,6 +1063,9 @@ function animate() {
drawGrid(ctx, canvas.width * 2, gridSquareSize, xGridOffset, yGridOffset);
drawRobot(ctx, robot, robot.gyroHeading);
+ leftJoystick.draw();
+ rightJoystick.draw();
+
// Do it all over again
ctx.restore();
requestAnimationFrame(animate);