Untitled

 avatar
unknown
plain_text
2 years ago
31 kB
14
Indexable
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

// Change based on WiFi name and password
const char* ssid = "INSERT WIFI SSID";
const char* password = "INSERT WIFI PASSWORD";

// This sets the web server to be accessible @port 80.
ESP8266WebServer server(80);

// Used for debugging.
bool statusLed = HIGH;

String cameraLeftPan = "0";
String cameraRightPan = "0";
String gantryLeftPan = "0";
String gantryRightPan = "0";

// Since http requests pass string value, the receiving variables are also set as String.
// To use the values as integer, you can use Atoi or Atof to convert the string/ character array to integer
// or float, respectively.
String targetMode = "0";
String targetTravDist = "0";
String targetTravDir = "0";
String targetTravDur = "0";
String targetRotDeg = "0";
String targetRotDir = "0";
String targetRotDur = "0";

void setup() {
  // The baud rate for nodeMCU v3 is 9600
  Serial.begin(9600);

  // Used for debugging only. Sets the pin for the built-in LED as output.
  pinMode(LED_BUILTIN, OUTPUT);

  // Connects to the WiFi 
//  Serial.println();
//  Serial.println();
//  Serial.print("Connecting to ");
//  Serial.println(ssid); 
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
//    Serial.print(".");
  }
  // After establishing connection to the WiFi, web server will be started.
  // Once it started, you can check the serial monitor and check the IP address
  // that the microcontroller is using.
//  Serial.println("");
//  Serial.println("WiFi connected"); 
  server.begin();
//  Serial.println("Server started");
//  Serial.print("Use this URL to connect: ");
//  Serial.print("http://");
//  Serial.print(WiFi.localIP());
//  Serial.println("/"); 

  // The lines below will define what the microcontroller will do when you try to access a certain endpoint.
  // For example, when you access http://<IP ADDRESS>/ledOn, it will run the triggerLedOn function in this
  // Arduino code/ .ino file.
  server.on("/", sendIndexHTML);
  server.on("/ledOn", triggerLedOn);
  server.on("/ledOff", triggerLedOff);
  server.on("/form", HTTP_POST, submitForm);
  server.on("/reset", triggerReset);
  server.on("/serialPrint", printInSerialValues);
  server.on("/camera", cameraPan);
  server.on("/gantry", gantryPan);
  server.onNotFound(sendNotFound);

  // After configuring the endpoints that you will make available, server.begin was called again to apply
  // those changes.
  server.begin();
//  Serial.println("HTTP server started");
}

void loop() {
  // this will just loop so that the web server will continue to accept clients
  server.handleClient();

  // used for debugging only. This checks the value for statusLed variable and drive the LED based on the status.
  if(statusLed){
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    digitalWrite(LED_BUILTIN, LOW);
  }
}

// This function will serve the main/ only HTML page. It can be made accessible by accessing <IP>
void sendIndexHTML() {
//  Serial.println("Web server index was accessed");
  server.send(200, "text/html", sendHTML()); 
}

// This function helps define the states of the variable used to either pan the camera to the left or right
void cameraPan(){
  if (server.hasArg("left")) {
    if (server.arg("left") == "on") {
      cameraLeftPan = "1";
    } else if (server.arg("left") == "off") {
      cameraLeftPan = "0";
    }
  } else if (server.hasArg("right")) {
    if (server.arg("right") == "on") {
      cameraRightPan = "1";
    } else if (server.arg("right") == "off") {
      cameraRightPan = "0";
    }
  }
//   Serial.println("Camera");
//   Serial.print("  Left: ");
//   Serial.println(cameraLeftPan);
//   Serial.print("  Right: ");
//   Serial.println(cameraRightPan);
  serialSendValues(cameraLeftPan,cameraRightPan,"0","0","0","0","0","0","0","0","0");
  server.send(200, "text/html", ""); 
}

// This function helps define the states of the variable used to either pan the camera to the left or right
void gantryPan(){
  if (server.hasArg("left")) {
    if (server.arg("left") == "on") {
      gantryLeftPan = "1";
    } else if (server.arg("left") == "off") {
      gantryLeftPan = "0";
    }
  } else if (server.hasArg("right")) {
    if (server.arg("right") == "on") {
      gantryRightPan = "1";
    } else if (server.arg("right") == "off") {
      gantryRightPan = "0";
    }
  }
//   Serial.println("Gantry");
//   Serial.print("  Left: ");
//   Serial.println(gantryLeftPan);
//   Serial.print("  Right: ");
//   Serial.println(gantryRightPan);
  serialSendValues("0","0",gantryLeftPan,gantryRightPan,"0","0","0","0","0","0","0");
  server.send(200, "text/html", ""); 
}

// Used for debugging. This will turn on the LED. It is triggered by accessing <IP>/ledOn
void triggerLedOn() {
  statusLed = LOW;
  server.send(200, "text/html", sendHTML()); 
}

// Used for debugging. This will turn off the LED. It is triggered by accessing <IP>/ledOff
void triggerLedOff() {
  statusLed = HIGH;
  server.send(200, "text/html", sendHTML()); 
}

// If you are trying to access an endpoint not defined in setup, it will print out "Not found"
void sendNotFound(){
  server.send(404, "text/plain", "Not found");
}

// This function will process the data received from the HTML page (FrontEnd) and save them to their
// respective variables. Accessing /form in the web browser will just take you to the HTML of the main page.

// Behind the scenes, when you click the "Submit" button, it will send an HTTP POST request similar to this:
// <IP>/form?mode=pan&travelDis=123&travelDir=forward
void submitForm(){
  if (server.hasArg("mode")) {
    targetMode = server.arg("mode");
    // Serial.println("Updated value for: targetMode");
  }
  if (server.hasArg("travelDis")) {
    targetTravDist = server.arg("travelDis");
    // Serial.println("Updated value for: targetTravDist");
  }
  if (server.hasArg("travelDir")) {
    targetTravDir = server.arg("travelDir");
    // Serial.println("Updated value for: targetTravDir");
  }
  if (server.hasArg("travelDur")) {
    targetTravDur = server.arg("travelDur");
    // Serial.println("Updated value for: targetTravDur");
  }
  if (server.hasArg("rotateDeg")) {
    targetRotDeg = server.arg("rotateDeg");
    // Serial.println("Updated value for: targetRotDeg");
  }
  if (server.hasArg("rotateDir")) {
    targetRotDir = server.arg("rotateDir");
    // Serial.println("Updated value for: targetRotDir");
  }
  if (server.hasArg("rotateDur")) {
    targetRotDur = server.arg("rotateDur");
    // Serial.println("Updated value for: targetRotDur");
  }
  serialSendValues("0","0","0","0",targetMode,targetTravDist,targetTravDir,targetTravDur,targetRotDeg,targetRotDir,targetRotDur);
  server.send(200, "text/html", sendHTML()); 
}


// This function will be used to reset the values currently saved within the microcontroller. 
// After setting to the values below, it will just redirect/ serve the HTML for the main page.
// Values are reset by accessing this endpoint: <IP>/reset
void triggerReset() {
  targetMode = "";
  targetTravDist = "0";
  targetTravDir = "0";
  targetTravDur = "0";
  targetRotDeg = "0";
  targetRotDir = "0";
  targetRotDur = "0";
  server.send(200, "text/html", sendHTML()); 
}

// This function will be used print out the current values of the important variables.
// The values can be seen in the serial monitor.
// It is done by accessing this endpoint: <IP>/serialPrint
void printInSerialValues() {
//   Serial.println(targetMode);
//   Serial.println(targetTravDist);
//   Serial.println(targetTravDir);
//   Serial.println(targetTravDur);
//   Serial.println(targetRotDeg);
//   Serial.println(targetRotDir);
//   Serial.println(targetRotDur);
  server.send(200, "text/html", sendHTML()); 
}

void serialSendValues(String camLeft, String camRight, String ganLeft, String ganRight, String mode, String traDis, String traDir, String traDur, String rotDeg, String rotDir, String rotDur) {
  if (traDir == "forward") {
    traDir = "1";
  } else if (traDir == "backward") {
    traDir = "2";
  }
  if (rotDir == "cw") {
    rotDir = "1";
  } else if (rotDir == "ccw") {
    rotDir = "2";
  }
  String payload;
  payload = camLeft + "," + camRight + "," + ganLeft + "," + ganRight + "," + mode + "," + traDis + "," + traDir + "," + traDur + "," + rotDeg + "," + rotDir + "," + rotDur;
  Serial.println(payload);
}

// This is a simple String function that returns the HTML page saved as a String
// To update the HTML here, 
//   1. please get the HTML code you want to use.
//   2. using notepad++ or using the latest notepad, replace " with \"
//   3. copy the updated code.
//   4. compress the HTML using this site https://www.textfixer.com/html/compress-html-compression.php.
//   5. copy the compressed HTML.
//   6. replace the very long string in line 182. Follow the syntax/ format below:
//      String html ="<paste the code here. make sure it is enclosed with double quotes>"
String sendHTML(){
  String html ="<!DOCTYPE html><html> <head> <title>Motorized Camera Slider</title> <!-- this imports ajax --> <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js\"></script> <style> :root { --minimum-desktop-width: 900px; --video-height: 600px; } /* this hides certain parts of the page when it loads. this is used to hide buttons and other inputs */ .hide-on-default { visibility: hidden !important; } .container-hide-on-default { visibility: hidden !important; height: 0px } /* this configures the initial size of the video stream */ .video-js { width: var(--minimum-desktop-width); height: var(--video-height); } /* this creates a container or box that will later contain the various buttons and inputs */ .main-content { width: var(--minimum-desktop-width); height: 100%; margin-top: 7px; border-top-style: dotted; border-right-style: solid; border-bottom-style: dotted; border-left-style: solid; border-radius: 15px; border-color: gray; } /* this adds a top margin to the section that will contain the buttons and sliders */ .menu-section { margin-top: 10px; } /* this adds a top and bottom margin to the section that will contain the main controls*/ .control-section { margin-top: 10px; margin-bottom: 10px; width: 800px; display: unset; } /* this serves as the dividers of preset buttons and inputs */ .preset-section { width: 400px; display: inline-block; vertical-align: top; } /* this will configure how the image buttons will look like */ .image-button-container { border-width: thin; border-radius: 10px; } .image-button { height: 50px; width: 50px } /* this will configure how the buttons will look like */ /* the mode buttons and submit button will use the style defined here */ .mode-button { display: inline-block; padding: 15px 25px; margin: 15px; font-size: 24px; cursor: pointer; text-align: center; text-decoration: none; outline: none; color: #525252; background-color: white; border: none; border-style: solid; border-color: #3c5196; border-radius: 15px; box-shadow: 0 9px #999; transition-duration: 0.4s; width: 200px; } /* this defines how the reset button will look like */ .reset-button { display: inline-block; padding: 15px 25px; margin: 15px; font-size: 24px; cursor: pointer; text-align: center; text-decoration: none; outline: none; color: #525252; background-color: white; background: url('https://cdn-icons-png.flaticon.com/512/4674/4674411.png') no-repeat center; background-size: contain; border: none; border-style: solid; border-color: #3c5196; border-radius: 15px; box-shadow: 0 9px #999; transition-duration: 0.4s; width: 70px; } .left-button { background: white url('https://cdn-icons-png.flaticon.com/512/4674/4674401.png') no-repeat center; background-size: contain; } .right-button { background: white url('https://cdn-icons-png.flaticon.com/512/4674/4674414.png') no-repeat center; background-size: contain; } /* this defines how the mode buttons will behave based on action */ /* for example, it will change color when you hover on the button */ .mode-button:hover { background-color: #3c5196; color: white; } .mode-button:active { background-color: #3c5196; box-shadow: 0 5px #525252; transform: translateY(4px); } .mode-button:disabled { box-shadow: 0 5px #525252; transform: translateY(4px); color: #525252; pointer-events: none; } .control-label { width: 90%; font-size: 24px; font-weight: bold; color: #525252; text-align: center; } /* the lines below will define how the sliders will look like */ .range-container { max-width: 700px; margin-top: 10px; margin-bottom: 10px; height: auto; } .range-label { width: 90%; font-size: 16px; font-weight: bold; color: #525252; text-align: left; text-decoration: none; } .range-slider { width: 70%; } .range-textbox { width: 25%; } .minus, .plus{width:20px;height:20px;background:#f2f2f2;border-radius:4px;padding:8px 5px 8px 5px;border:1px solid #ddd; display: inline-block; vertical-align: middle; text-align: center;} /* these @media lines will update certain parts/ objects in the website */ /* it will make the objects appear differently based on the screen size */ @media only screen and (max-width: 1080px) { .video-js, .main-content { width: 100%; } video { width: 100%; height: auto; } } @media only screen and (max-width: 867px) { .mode-button { width: 70%; } .reset-button { width: 70px; } .range-container { width: 95%; } .range-label { text-align: center; } .range-slider { width: 50%; } .range-textbox { width: 25%; margin-left: 30%; margin-right: 30%; } } @media only screen and (max-width: 550px) { .mode-button { width: 95%; } .reset-button { width: 70px; } } </style> </head> <body> <!-- <center> --> <!-- this section defines the video stream. please update the value for the 'src' here based on the IP address and stream you want to display --> <iframe class=\"video-js\" src =\"http://192.168.1.7/mjpeg/1\" > <p>Your browser does not support iframes.</p> </iframe> <!-- this section contains the mode buttons. The other buttons or inputs that will also appear after selecting the mode. --> <div class=\"main-content\"> <center> <div class=\"control-section\"> <div class=\"control-label\">Camera Controls</div> <input type=\"button\" id=\"leftCameraBtn\" class=\"mode-button reset-button left-button\" onpointerdown=\"startCameraLeftPan()\" onpointerup=\"stopCameraLeftPan()\" value=\" \" /> <input type=\"button\" id=\"rightCameraBtn\" class=\"mode-button reset-button right-button\" onpointerdown=\"startCameraRightPan()\" onpointerup=\"stopCameraRightPan()\" value=\" \" /> </div> <div class=\"control-section\"> <div class=\"control-label\">Gantry Controls</div> <input type=\"button\" id=\"leftGantryBtn\" class=\"mode-button reset-button left-button\" onpointerdown=\"startGantryLeftPan()\" onpointerup=\"stopGantryLeftPan()\" value=\" \" /> <input type=\"button\" id=\"rightGantryBtn\" class=\"mode-button reset-button right-button\" onpointerdown=\"startGantryRightPan()\" onpointerup=\"stopGantryRightPan()\" value=\" \" /> </div> <div class=\"control-section\"> <div class=\"control-label\">Presets</div> <!-- <div class=\"preset-section\"> --> <div id=\"modeBtnsSection\"> <input type=\"button\" class=\"mode-button\" value=\"Pan\" id=\"modePan\"/> <input type=\"button\" class=\"mode-button\" value=\"Rotate\" id=\"modeRotate\"/> <input type=\"button\" class=\"mode-button\" value=\"Pan & Rotate\" id=\"modePanRotate\"/> </div> <div class=\"preset-section\"> <form action=\"/form\" class=\"menu-section\" method=\"post\"> <input type=\"hidden\" id=\"mode\" name=\"mode\" value=\"\"/> <!-- this section configures the slider and number box that will define the distance to travel --> <div id=\"travDistCtr\" class=\"container-hide-on-default\"> <div class=\"range-label\">Travel Distance (in mm):</div> <span class=\"minus\" id=\"travelDisMinus\">-</span> <input type=\"range\" id=\"travelDisSlider\" class=\"hide-on-default\" value=\"25\" min=\"0\" max=\"550\" step=\"25\" onchange=\"updateTravDis()\"/> <span class=\"plus\" id=\"travelDisPlus\">+</span> <input type=\"number\" id=\"travelDis\" class=\"hide-on-default\" name=\"travelDis\" value=\"25\" min=\"0\" max=\"550\" step=\"25\" oninput=\"updateTravDisSlider()\"/> </div> <!-- this section configures the image button showing the direction --> <div id=\"travDirCtr\" class=\"container-hide-on-default\"> <div class=\"range-label\">Travel Direction (forward or backward):</div> <button type=\"button\" class=\"image-button-container\" onclick=\"updateTravDir()\"> <img id=\"travelDirImg\" class=\"hide-on-default\" src=\"https://cdn-icons-png.flaticon.com/512/4674/4674414.png\"> </button> <input type=\"hidden\" id=\"travelDir\" name=\"travelDir\" value=\"forward\"/> </div> <!-- this section configures the slider and number box that will define how long it would take to reach the endpoint--> <div id=\"travDurCtr\" class=\"container-hide-on-default\"> <div class=\"range-label\">Travel Duration (in seconds):</div> <span class=\"minus\" id=\"travelDurMinus\">-</span> <input type=\"range\" id=\"travelDurSlider\" class=\"hide-on-default\" value=\"10\" min=\"0\" max=\"1500\" step=\"10\" onchange=\"updateTravDur()\"/> <span class=\"plus\" id=\"travelDurPlus\">+</span> <input type=\"number\" id=\"travelDur\" class=\"hide-on-default\" name=\"travelDur\" value=\"10\" min=\"0\" max=\"1500\" step=\"10\" oninput=\"updateTravDurSlider()\"/> </div> <!-- this section configures the slider and number box that will define how many degrees it will rotate. --> <div id=\"rotDegCtr\" class=\"container-hide-on-default\"> <div class=\"range-label\">Rotate (in degrees):</div> <span class=\"minus\" id=\"rotateDegMinus\">-</span> <input type=\"range\" id=\"rotateDegSlider\" class=\"hide-on-default\" value=\"10\" min=\"0\" max=\"360\" step=\"10\" onchange=\"updateRotDeg()\"/> <span class=\"plus\" id=\"rotateDegPlus\">+</span> <input type=\"number\" id=\"rotateDeg\" class=\"hide-on-default\" name=\"rotateDeg\" value=\"10\" min=\"0\" max=\"360\" step=\"10\" oninput=\"updateRotDegSlider()\"/> </div> <!-- this section configures the image button showing the direction --> <div id=\"rotDirCtr\" class=\"container-hide-on-default\"> <div class=\"range-label\">Rotation Direction (CW or CCW):</div> <button type=\"button\" class=\"image-button-container\" onclick=\"updateRotDir()\"> <img id=\"rotateDirImg\" class=\"hide-on-default\" src=\"https://cdn-icons-png.flaticon.com/512/4674/4674415.png\"> </button> <input type=\"hidden\" id=\"rotateDir\" name=\"rotateDir\" value=\"cw\"/> </div> <!-- this section configures the slider and number box that will define how long it would take to rotate. --> <div id=\"rotDurCtr\" class=\"container-hide-on-default\"> <div class=\"range-label\">Rotate Duration (in seconds):</div> <span class=\"minus\" id=\"rotateDurMinus\">-</span> <input type=\"range\" id=\"rotateDurSlider\" class=\"hide-on-default\" value=\"10\" min=\"0\" max=\"1500\" step=\"10\" onchange=\"updateRotDur()\"/> <span class=\"plus\" id=\"rotateDurPlus\">+</span> <input type=\"number\" id=\"rotateDur\" class=\"hide-on-default\" name=\"rotateDur\" value=\"10\" min=\"0\" max=\"1500\" step=\"10\" oninput=\"updateRotDurSlider()\"/> </div> <input type=\"submit\" id=\"submitBtn\" class=\"hide-on-default\" value=\"Submit\"/> <a href=\"./reset\"> <input type=\"button\" id=\"resetBtn\" class=\"hide-on-default\" value=\" \" src=\"https://cdn-icons-png.flaticon.com/512/4674/4674411.png\"/> </a> </form> </div> </div> </center> </div> <!-- this section contains the scripts that will be used. It will contain onclick actions, onupdate actions, etc. --> <script> /* these are the variables for the mode buttons */ const btnPan = document.getElementById('modePan'); const btnRotate = document.getElementById('modeRotate'); const btnPanRotate = document.getElementById('modePanRotate'); /* this variable will point to the specific section in the page that contains the mode buttons */ const modeBtnsSection = document.getElementById('modeBtnsSection'); /* these are the variables that will be used to hide and unhide the inputs */ const travDistCtr = document.getElementById('travDistCtr'); const travDirCtr = document.getElementById('travDirCtr'); const travDurCtr = document.getElementById('travDurCtr'); const rotDegCtr = document.getElementById('rotDegCtr'); const rotDirCtr = document.getElementById('rotDirCtr'); const rotDurCtr = document.getElementById('rotDurCtr'); /* these are the variables used to update the submit and reset buttons. It also includes the hidden object that saves the desired mode. */ const inputMode = document.getElementById('mode'); const submitBtn = document.getElementById('submitBtn'); const resetBtn = document.getElementById('resetBtn'); /* the lines below gets the exact input elements or objects like the slider for the distance to travel */ const inputTravDistSlider = document.getElementById('travelDisSlider'); const inputTravDistText = document.getElementById('travelDis'); const inputTravDistMinus = document.getElementById('travelDisMinus'); const inputTravDistPlus = document.getElementById('travelDisPlus'); const inputTravDirImg = document.getElementById('travelDirImg'); const inputTravDir = document.getElementById('travelDir'); const inputTravDurSlider = document.getElementById('travelDurSlider'); const inputTravDurText = document.getElementById('travelDur'); const inputTravDurMinus = document.getElementById('travelDurMinus'); const inputTravDurPlus = document.getElementById('travelDurPlus'); const inputRotDegSlider = document.getElementById('rotateDegSlider'); const inputRotDegText = document.getElementById('rotateDeg'); const inputRotDegMinus = document.getElementById('rotateDegMinus'); const inputRotDegPlus = document.getElementById('rotateDegPlus'); const inputRotDirImg = document.getElementById('rotateDirImg'); const inputRotDir = document.getElementById('rotateDir'); const inputRotDurSlider = document.getElementById('rotateDurSlider'); const inputRotDurText = document.getElementById('rotateDur'); const inputRotDurMinus = document.getElementById('rotateDurMinus'); const inputRotDurPlus = document.getElementById('rotateDurPlus'); function startCameraLeftPan() { $.ajax({ /* the target endpoint to send HTTP POST to */ url: \"./camera\", /* the data to send */ data: {'left' : 'on'}, type: \"POST\", success: function(data){ console.log('HTTP POST request sent') }, error: function(){ console.log('startCameraLeftPan failed') } }); } function stopCameraLeftPan() { $.ajax({ /* the target endpoint to send HTTP POST to */ url: \"./camera\", /* the data to send */ data: {'left' : 'off'}, type: \"POST\", success: function(data){ console.log('HTTP POST request sent') }, error: function(){ console.log('stopCameraLeftPan failed') } }); } function startCameraRightPan() { $.ajax({ /* the target endpoint to send HTTP POST to */ url: \"./camera\", /* the data to send */ data: {'right' : 'on'}, type: \"POST\", success: function(data){ console.log('HTTP POST request sent') }, error: function(){ console.log('startCameraRightPan failed') } }); } function stopCameraRightPan() { $.ajax({ /* the target endpoint to send HTTP POST to */ url: \"./camera\", /* the data to send */ data: {'right' : 'off'}, type: \"POST\", success: function(data){ console.log('HTTP POST request sent') }, error: function(){ console.log('stopCameraRightPan failed') } }); } function startGantryLeftPan() { $.ajax({ /* the target endpoint to send HTTP POST to */ url: \"./gantry\", /* the data to send */ data: {'left' : 'on'}, type: \"POST\", success: function(data){ console.log('HTTP POST request sent') }, error: function(){ console.log('startGantryLeftPan failed') } }); } function stopGantryLeftPan() { $.ajax({ /* the target endpoint to send HTTP POST to */ url: \"./gantry\", /* the data to send */ data: {'left' : 'off'}, type: \"POST\", success: function(data){ console.log('HTTP POST request sent') }, error: function(){ console.log('stopGantryLeftPan failed') } }); } function startGantryRightPan() { $.ajax({ /* the target endpoint to send HTTP POST to */ url: \"./gantry\", /* the data to send */ data: {'right' : 'on'}, type: \"POST\", success: function(data){ console.log('HTTP POST request sent') }, error: function(){ console.log('startGantryRightPan failed') } }); } function stopGantryRightPan() { $.ajax({ /* the target endpoint to send HTTP POST to */ url: \"./gantry\", /* the data to send */ data: {'right' : 'off'}, type: \"POST\", success: function(data){ console.log('HTTP POST request sent') }, error: function(){ console.log('stopGantryRightPan failed') } }); } /* this updates the inputs for the travel distance based on the value of another */ function updateTravDis() { inputTravDistText.value = inputTravDistSlider.value; } function updateTravDisSlider() { inputTravDistSlider.value = inputTravDistText.value; } inputTravDistMinus.addEventListener('click', function onClick() { var val = Number(inputTravDistSlider.value); val -= Number(25); if ( val < 0 ) { val = Number(0); } inputTravDistSlider.value = val; inputTravDistText.value = val; }); inputTravDistPlus.addEventListener('click', function onClick() { var val = Number(inputTravDistSlider.value); val += Number(25); inputTravDistSlider.value = val; inputTravDistText.value = val; }); /* this updates the image to be displayed to show the desired direction */ function updateTravDir() { var src, val; if (inputTravDir.value == \"forward\") { val = \"backward\"; src = \"https://cdn-icons-png.flaticon.com/512/4674/4674401.png\"; } else if (inputTravDir.value == \"backward\") { val = \"forward\"; src = \"https://cdn-icons-png.flaticon.com/512/4674/4674414.png\"; } inputTravDir.value = val; inputTravDirImg.src = src; } /* this updates the inputs for the travel duration based on the value of another */ function updateTravDur() { inputTravDurText.value = inputTravDurSlider.value; } function updateTravDurSlider() { inputTravDurSlider.value = inputTravDurText.value; } inputTravDurMinus.addEventListener('click', function onClick() { var val = Number(inputTravDurSlider.value); val -= Number(5); if ( val < 0 ) { val = Number(0); } inputTravDurSlider.value = val; inputTravDurText.value = val; }); inputTravDurPlus.addEventListener('click', function onClick() { var val = Number(inputTravDurSlider.value); val += Number(5); inputTravDurSlider.value = val; inputTravDurText.value = val; }); /* this updates the inputs for the degrees to rotate based on the value of another */ function updateRotDeg() { inputRotDegText.value = inputRotDegSlider.value; } function updateRotDegSlider() { inputRotDegSlider.value = inputRotDegText.value; } inputRotDegMinus.addEventListener('click', function onClick() { var val = Number(inputRotDegSlider.value); val -= Number(10); if ( val < 0 ) { val = Number(0); } inputRotDegSlider.value = val; inputRotDegText.value = val; }); inputRotDegPlus.addEventListener('click', function onClick() { var val = Number(inputRotDegSlider.value); val += Number(10); inputRotDegSlider.value = val; inputRotDegText.value = val; }); /* this updates the image to be displayed to show the desired direction of rotation */ function updateRotDir() { var src, val; if (inputRotDir.value == \"cw\") { val = \"ccw\"; src = \"https://cdn-icons-png.flaticon.com/512/4674/4674413.png\"; } else if (inputRotDir.value == \"ccw\") { val = \"cw\"; src = \"https://cdn-icons-png.flaticon.com/512/4674/4674415.png\"; } inputRotDir.value = val; inputRotDirImg.src = src; } /* this updates the inputs for the rotate duration based on the value of another */ function updateRotDur() { inputRotDurText.value = inputRotDurSlider.value; } function updateRotDurSlider() { inputRotDurSlider.value = inputRotDurText.value; } inputRotDurMinus.addEventListener('click', function onClick() { var val = Number(inputRotDurSlider.value); val -= Number(5); if ( val < 0 ) { val = Number(0); } inputRotDurSlider.value = val; inputRotDurText.value = val; }); inputRotDurPlus.addEventListener('click', function onClick() { var val = Number(inputRotDurSlider.value); val += Number(5); inputRotDurSlider.value = val; inputRotDurText.value = val; }); /* the lines below displays what buttons or inputs are visible based on the selected mode */ btnPan.addEventListener('click', function onClick() { btnPan.style.backgroundColor = '#3c5196'; btnPan.style.color = 'white'; btnPan.setAttribute('disabled', ''); btnRotate.setAttribute('disabled', ''); btnPanRotate.setAttribute('disabled', ''); inputMode.value = \"pan\"; submitBtn.className = \"mode-button\"; resetBtn.className = \"reset-button\"; modeBtnsSection.className = \"preset-section\"; travDistCtr.className = \"range-container\"; inputTravDistSlider.className = \"range-slider\"; inputTravDistText.className = \"range-textbox\"; travDirCtr.className = \"range-container\"; inputTravDirImg.className = \"image-button\"; travDurCtr.className = \"range-container\"; inputTravDurSlider.className = \"range-slider\"; inputTravDurText.className = \"range-textbox\"; }); btnRotate.addEventListener('click', function onClick() { btnRotate.style.backgroundColor = '#3c5196'; btnRotate.style.color = 'white'; btnPan.setAttribute('disabled', ''); btnRotate.setAttribute('disabled', ''); btnPanRotate.setAttribute('disabled', ''); inputMode.value = \"rotate\"; submitBtn.className = \"mode-button\"; resetBtn.className = \"reset-button\"; modeBtnsSection.className = \"preset-section\"; rotDegCtr.className = \"range-container\"; inputRotDegSlider.className = \"range-slider\"; inputRotDegText.className = \"range-textbox\"; rotDirCtr.className = \"range-container\"; inputRotDirImg.className = \"image-button\"; rotDurCtr.className = \"range-container\"; inputRotDurSlider.className = \"range-slider\"; inputRotDurText.className = \"range-textbox\"; }); btnPanRotate.addEventListener('click', function onClick() { btnPanRotate.style.backgroundColor = '#3c5196'; btnPanRotate.style.color = 'white'; btnPan.setAttribute('disabled', ''); btnRotate.setAttribute('disabled', ''); btnPanRotate.setAttribute('disabled', ''); inputMode.value = \"panrotate\"; submitBtn.className = \"mode-button\"; resetBtn.className = \"reset-button\"; modeBtnsSection.className = \"preset-section\"; travDistCtr.className = \"range-container\"; inputTravDistSlider.className = \"range-slider\"; inputTravDistText.className = \"range-textbox\"; travDirCtr.className = \"range-container\"; inputTravDirImg.className = \"image-button\"; travDurCtr.className = \"range-container\"; inputTravDurSlider.className = \"range-slider\"; inputTravDurText.className = \"range-textbox\"; rotDegCtr.className = \"range-container\"; inputRotDegSlider.className = \"range-slider\"; inputRotDegText.className = \"range-textbox\"; rotDirCtr.className = \"range-container\"; inputRotDirImg.className = \"image-button\"; rotDurCtr.className = \"range-container\"; inputRotDurSlider.className = \"range-slider\"; inputRotDurText.className = \"range-textbox\"; }); </script> <!-- </center> --> </body></html>";
  return html;
}
Editor is loading...