Reputation: 480
I want to build a UI with a joystick, To implement the joystick, I used the JoyStick js library: https://github.com/bobboteck/JoyStick My code works in Firefox and Chrome on Windows 10, but on Android the joystick doesn't appear with the following error messages:
(index):1889 crbug/1173575, non-JS module files deprecated.
(anonymous) @ (index):1889
chromewebdata/:1 Not allowed to load local resource: content://0@media/external/file/10769
My code: controller.html
<!DOCTYPE html>
<html>
<head>
<title>drone controller</title>
<meta charset="utf-8">
<script src="joy.js"></script>
</head>
<body>
<!-- Example of FIXED or ABSOLUTE position -->
<div id="container" style="width:200px;height:200px;margin:50px;position:fixed;bottom:30px;left:500px;">
</div>
<div style="position:fixed;bottom:125px;left:750px;">
Posizione X:<input id="joy3PosizioneX" type="text"><br>
Posizione Y:<input id="joy3PosizioneY" type="text"><br>
Direzione:<input id="joy3Direzione" type="text"><br>
X :<input id="joy3X" type="text"><br>
Y :<input id="joy3Y" type="text">
</div>
<script>
var joy3 = new JoyStick('container');
// var joy3Param = { "title": "joystick3" };
// var Joy3 = new JoyStick('joy3Div', joy3Param);
var joy3IinputPosX = document.getElementById("joy3PosizioneX");
var joy3InputPosY = document.getElementById("joy3PosizioneY");
var joy3Direzione = document.getElementById("joy3Direzione");
var joy3X = document.getElementById("joy3X");
var joy3Y = document.getElementById("joy3Y");
setInterval(function(){ joy3IinputPosX.value=joy3.GetPosX(); }, 50);
setInterval(function(){ joy3InputPosY.value=joy3.GetPosY(); }, 50);
setInterval(function(){ joy3Direzione.value=joy3.GetDir(); }, 50);
setInterval(function(){ joy3X.value=joy3.GetX(); }, 50);
setInterval(function(){ joy3Y.value=joy3.GetY(); }, 50);
</script>
</body>
</html>
joy.js unmodified from github
var JoyStick = (function(container, parameters)
{
parameters = parameters || {};
var title = (typeof parameters.title === "undefined" ? "joystick" : parameters.title),
width = (typeof parameters.width === "undefined" ? 0 : parameters.width),
height = (typeof parameters.height === "undefined" ? 0 : parameters.height),
internalFillColor = (typeof parameters.internalFillColor === "undefined" ? "#00AA00" : parameters.internalFillColor),
internalLineWidth = (typeof parameters.internalLineWidth === "undefined" ? 2 : parameters.internalLineWidth),
internalStrokeColor = (typeof parameters.internalStrokeColor === "undefined" ? "#003300" : parameters.internalStrokeColor),
externalLineWidth = (typeof parameters.externalLineWidth === "undefined" ? 2 : parameters.externalLineWidth),
externalStrokeColor = (typeof parameters.externalStrokeColor === "undefined" ? "#008000" : parameters.externalStrokeColor),
autoReturnToCenter = (typeof parameters.autoReturnToCenter === "undefined" ? true : parameters.autoReturnToCenter);
// Create Canvas element and add it in the Container object
var objContainer = document.getElementById(container);
var canvas = document.createElement("canvas");
canvas.id = title;
if(width === 0) { width = objContainer.clientWidth; }
if(height === 0) { height = objContainer.clientHeight; }
canvas.width = width;
canvas.height = height;
objContainer.appendChild(canvas);
var context=canvas.getContext("2d");
var pressed = 0; // Bool - 1=Yes - 0=No
var circumference = 2 * Math.PI;
var internalRadius = (canvas.width-((canvas.width/2)+10))/2;
var maxMoveStick = internalRadius + 5;
var externalRadius = internalRadius + 30;
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var directionHorizontalLimitPos = canvas.width / 10;
var directionHorizontalLimitNeg = directionHorizontalLimitPos * -1;
var directionVerticalLimitPos = canvas.height / 10;
var directionVerticalLimitNeg = directionVerticalLimitPos * -1;
// Used to save current position of stick
var movedX=centerX;
var movedY=centerY;
// Check if the device support the touch or not
if("ontouchstart" in document.documentElement)
{
canvas.addEventListener("touchstart", onTouchStart, false);
canvas.addEventListener("touchmove", onTouchMove, false);
canvas.addEventListener("touchend", onTouchEnd, false);
}
else
{
canvas.addEventListener("mousedown", onMouseDown, false);
canvas.addEventListener("mousemove", onMouseMove, false);
canvas.addEventListener("mouseup", onMouseUp, false);
}
// Draw the object
drawExternal();
drawInternal();
/******************************************************
* Private methods
*****************************************************/
/**
* @desc Draw the external circle used as reference position
*/
function drawExternal()
{
context.beginPath();
context.arc(centerX, centerY, externalRadius, 0, circumference, false);
context.lineWidth = externalLineWidth;
context.strokeStyle = externalStrokeColor;
context.stroke();
}
/**
* @desc Draw the internal stick in the current position the user have moved it
*/
function drawInternal()
{
context.beginPath();
if(movedX<internalRadius) { movedX=maxMoveStick; }
if((movedX+internalRadius) > canvas.width) { movedX = canvas.width-(maxMoveStick); }
if(movedY<internalRadius) { movedY=maxMoveStick; }
if((movedY+internalRadius) > canvas.height) { movedY = canvas.height-(maxMoveStick); }
context.arc(movedX, movedY, internalRadius, 0, circumference, false);
// create radial gradient
var grd = context.createRadialGradient(centerX, centerY, 5, centerX, centerY, 200);
// Light color
grd.addColorStop(0, internalFillColor);
// Dark color
grd.addColorStop(1, internalStrokeColor);
context.fillStyle = grd;
context.fill();
context.lineWidth = internalLineWidth;
context.strokeStyle = internalStrokeColor;
context.stroke();
}
/**
* @desc Events for manage touch
*/
function onTouchStart(event)
{
pressed = 1;
}
function onTouchMove(event)
{
// Prevent the browser from doing its default thing (scroll, zoom)
event.preventDefault();
if(pressed === 1 && event.targetTouches[0].target === canvas)
{
movedX = event.targetTouches[0].pageX;
movedY = event.targetTouches[0].pageY;
// Manage offset
if(canvas.offsetParent.tagName.toUpperCase() === "BODY")
{
movedX -= canvas.offsetLeft;
movedY -= canvas.offsetTop;
}
else
{
movedX -= canvas.offsetParent.offsetLeft;
movedY -= canvas.offsetParent.offsetTop;
}
// Delete canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// Redraw object
drawExternal();
drawInternal();
}
}
function onTouchEnd(event)
{
pressed = 0;
// If required reset position store variable
if(autoReturnToCenter)
{
movedX = centerX;
movedY = centerY;
}
// Delete canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// Redraw object
drawExternal();
drawInternal();
//canvas.unbind('touchmove');
}
/**
* @desc Events for manage mouse
*/
function onMouseDown(event)
{
pressed = 1;
}
function onMouseMove(event)
{
if(pressed === 1)
{
movedX = event.pageX;
movedY = event.pageY;
// Manage offset
if(canvas.offsetParent.tagName.toUpperCase() === "BODY")
{
movedX -= canvas.offsetLeft;
movedY -= canvas.offsetTop;
}
else
{
movedX -= canvas.offsetParent.offsetLeft;
movedY -= canvas.offsetParent.offsetTop;
}
// Delete canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// Redraw object
drawExternal();
drawInternal();
}
}
function onMouseUp(event)
{
pressed = 0;
// If required reset position store variable
if(autoReturnToCenter)
{
movedX = centerX;
movedY = centerY;
}
// Delete canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// Redraw object
drawExternal();
drawInternal();
//canvas.unbind('mousemove');
}
/******************************************************
* Public methods
*****************************************************/
/**
* @desc The width of canvas
* @return Number of pixel width
*/
this.GetWidth = function ()
{
return canvas.width;
};
/**
* @desc The height of canvas
* @return Number of pixel height
*/
this.GetHeight = function ()
{
return canvas.height;
};
/**
* @desc The X position of the cursor relative to the canvas that contains it and to its dimensions
* @return Number that indicate relative position
*/
this.GetPosX = function ()
{
return movedX;
};
/**
* @desc The Y position of the cursor relative to the canvas that contains it and to its dimensions
* @return Number that indicate relative position
*/
this.GetPosY = function ()
{
return movedY;
};
/**
* @desc Normalizzed value of X move of stick
* @return Integer from -100 to +100
*/
this.GetX = function ()
{
return (100*((movedX - centerX)/maxMoveStick)).toFixed();
};
/**
* @desc Normalizzed value of Y move of stick
* @return Integer from -100 to +100
*/
this.GetY = function ()
{
return ((100*((movedY - centerY)/maxMoveStick))*-1).toFixed();
};
/**
* @desc Get the direction of the cursor as a string that indicates the cardinal points where this is oriented
* @return String of cardinal point N, NE, E, SE, S, SW, W, NW and C when it is placed in the center
*/
this.GetDir = function()
{
var result = "";
var orizontal = movedX - centerX;
var vertical = movedY - centerY;
if(vertical >= directionVerticalLimitNeg && vertical <= directionVerticalLimitPos)
{
result = "C";
}
if(vertical < directionVerticalLimitNeg)
{
result = "N";
}
if(vertical > directionVerticalLimitPos)
{
result = "S";
}
if(orizontal < directionHorizontalLimitNeg)
{
if(result === "C")
{
result = "W";
}
else
{
result += "W";
}
}
if(orizontal > directionHorizontalLimitPos)
{
if(result === "C")
{
result = "E";
}
else
{
result += "E";
}
}
return result;
};
});
Thanks for your help!
Upvotes: 1
Views: 1523
Reputation: 691
I take it you have copied the files to the phone's local storage, and are trying to open them from there in Chrome?
I suspect it not working is intentional. Access to local files can be quite restricted in web browsers in general (since it doesn't really work together with the origin-based security model), and access to local storage on Android is an equally complicated subject.
If you're planning to serve this on the web, and just want to test whether it works in Chrome on Android, the path of least resistance will probably be to just serve it over HTTP. How to do that is probably outside the scope of the question, but for example (as described near the end of this page) Python's http.server
module can be used as a simple command-line web server for testing purposes, assuming you have a computer and a phone in the same local network (or use adb
port forwarding).
Edit: I've just tested your files using the above method (with python3 -m http.server
), and it does show the green joystick on Chrome 92 on Android.
Alternatively, if your end goal is to package this into an Android app, there are specific APIs (such as the WebViewAssetLoader) that allow you to serve the local HTTP and JS assets in a way that will not run into problems like this.
Upvotes: 3
Reputation: 11
This gamepad API is relatively new and still now experimental. To my knowledge, only latest verson of Crome for android supports it. Update your crome browser on android and try. This should work.
Upvotes: 0