import { Joystick } from 'react-joystick-component'; import React, { useState} from 'react'; //import { w3cwebsocket as W3CWebSocket } from "websocket"; function App() { //declare variables that can be used and updated in html const [x_html, setX_html] = useState(0); const [y_html, setY_html] = useState(0); const [ip, setIp] = useState("10.0.0.66"); //=============================== //=========== config ============ //=============================== const decimalPlaces = 3; const joystickSize = 250; //affects scaling of coordinates and size of joystick on website const throttle = 300; //throtthe interval the joystick sends data while moving (ms) const toleranceSnapToZeroPer = 20;//percentage of moveable range the joystick can be moved from the axix and value stays at 0 //------------------------------------------------- //------- Scale coordinate, apply tolerance ------- //------------------------------------------------- //function that: // - scales the coodinate to a range of -1 to 1 // - snaps 0 zero for a given tolerance in percent // - rounds value do given decimal places // - TODO: add threshold it snaps to 1 / -1 (100%) toleranceEnd const ScaleCoordinateTolerance = (input) => { //calc tolerance threshold and available range const tolerance = joystickSize/2 * toleranceSnapToZeroPer/100; const range = joystickSize/2 - tolerance; let result = 0; //console.log("value:",input,"tolerance:",tolerance," range:",range); //input positive and above 'snap to zero' threshold if ( input > 0 && input > tolerance ){ result = ((input-tolerance)/range).toFixed(decimalPlaces); } //input negative and blow 'snap to zero' threshold else if ( input < 0 && input < -tolerance ){ result = ((input+tolerance)/range).toFixed(decimalPlaces); } //inside threshold around zero else { result = 0; } //return result //console.log("result:", result, "\n"); return result; } //---------------------------------------- //----------- Scale coordinate ----------- //---------------------------------------- //simply scale coordinate from joystick to a value of -1 to 1 without applying any tolerances const ScaleCoordinate = (input) => { return ( input / (joystickSize/2) ).toFixed(decimalPlaces); } //------------------------------------------- //------- Senda data via POST request ------- //------------------------------------------- //function that sends an object as json to the esp32 with a http post request const httpSendObject = async (object_data) => { //debug log console.log("Sending:", object_data); let json = JSON.stringify(object_data); //console.log("json string:", json); //remove quotes around numbers: //so cJSON parses the values as actua[l numbers than strings const regex2 = /"(-?[0-9]+\.{0,1}[0-9]*)"/g json = json.replace(regex2, '$1') //console.log("json removed quotes:", json); //--- API url / ip --- //await fetch("http://10.0.1.69/api/joystick", { //await fetch("http://10.0.1.72/api/joystick", { await fetch("api/joystick", { method: "POST", //apparently browser sends OPTIONS request before actual POST request, this OPTIONS request was not handled by esp32 //also the custom set Access-Control-Allow-Origin header in esp32 url header was not read because of that //changed content type to text/plain to workaround this //https://stackoverflow.com/questions/1256593/why-am-i-getting-an-options-request-instead-of-a-get-request headers: { //"Content-Type": "application/json", "Content-Type": "text/plain", }, body: json, }) //.then((response) => console.log(response)); }; //--------------------------------------- //--- function when joystick is moved --- //--------------------------------------- //function that is run for each move event //evaluate coordinates and send to esp32 const handleMove = (e) => { //console.log("data from joystick-element X:" + e.x + " Y:" + e.y + " distance:" + e.distance); //--- convert coordinates --- //Note: tolerance (snap to zero) now handled by controller -> send raw coordinates //const x = ScaleCoordinateTolerance(e.x); //const y = ScaleCoordinateTolerance(e.y); const x = ScaleCoordinate(e.x); const y = ScaleCoordinate(e.y); //create object with necessary data const joystick_data={ x: x, y: y } //send object with joystick data as json to controller httpSendObject(joystick_data); //update variables for html setX_html(joystick_data.x); setY_html(joystick_data.y); }; //------------------------------------------ //--- function when joystick is released --- //------------------------------------------ const handleStop = (e) => { //create object with all values 0 const joystick_data={ x: 0, y: 0, } //update variables for html setX_html(0); setY_html(0); //send object with joystick data as json to controller httpSendObject(joystick_data); }; //============================= //======== return html ======== //============================= return ( <>