DoujinStars
João Dias
João Dias

patreon


Creating an AutoTools Web Screen. Example: Colors

This is how I always create web screens myself. May not be the best way, but it's the way it works for me :)

For reference, here's the Colors web screen so you can look at its source. Also, here's a demo video so you can see how it works.

Step 1: create folder for my webscreen in a Dropbox folder on my PC and copy the AutoTools javascript and ccs files to the folder


Step 2: Create an html file in Sublime Text there (usually called page.html) and create the base page. Sublime makes it easy. I just type in "<h" then press enter and it'll do the rest :)


Step 3: Add this to the header:

<script src="autotools.js"></script>
<link rel="stylesheet" type="text/css" href="autotoolsstyle.css" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
   <style type="text/css">  
  html,body{
  margin: 0px;
height: 100vh;
overflow: hidden;
   font-family: 'Roboto', sans-serif;
  }
   </style>

This includes the javascript and css files mentioned before in the page so I can use them and then also sets the viewport. This viewport configures the page so that it doesn't scroll and can't be zoomed, making it behave more like a mobile app.

The  html,body{}  style there removes the margin, sets the height to 100% percent of the screen (vh stands for view height), and sets the font to Roboto which is what is normally used on Android.

Final Step: create the screen itself :) This is the part that is different for every screen. Here we go...


<meta name="autotoolswebscreen" type="variablejs" id="colors" label="Transition Colors" description="List of colors separated by commas. Can use any html compatible color format." isColor="true" />
<meta name="autotoolswebscreen" type="variablejs" id="times" label="Transition Times" description="List of times (in ms) it takes for each transition to finish. You can use less times than colors." defaultValue="3000" />
<meta name="autotoolswebscreen" type="variablejs" id="repeat" label="Loop" subtype="boolean" description="Enable to make transitions start over when all the colors have been shown" defaultValue="false" />

These 3 lines tell AutoTools that it should accept 3 inputs. The first is a color, the second one a normal string (text) and the third one a boolean (true or false). AutoTools knows how to read these and create inputs when you're configuring the web screen. These will then be used later in the code so you can change the screen according to what the users configured.


  <body>
<div id="color"></div>
  </body>

The body of the web page is very simple in this case. I simply need an element that I can change the background color of.

Next we start the script part of the page: the part where you actually do stuff with the input...

When reading the text below please bear in mind that I mostly used arrow functions for my functions.


var getColorClass = index => `color${index}`

This is a helper function to create a unique string for each color from the input. Will be used below. It receives an index (a number) and returns a string that is simply the word "color" followed by that number. 



var sleep = time => new Promise(resolve => setTimeout(resolve, time));

Another helper function. Receives the time I want to sleep and returns a Promise that resolves after that time. I'm not going to explain Promises right now, cause that would be a whole other article :) Just keep in mind that when you call this function, the code will stop at that line for the needed time and then advance. Kinda like the Wait action in Tasker.



AutoTools.setDefaultValues({
"colors": "black,yellow,green,blue,pink,white,red",
"times": "1000",
"repeat": true
});

I usually do this at the start of my Web Screen scripts. It sets all the values to some default values so that the screen works even if the user didn't provide any input. :) In this case it's setting  colors to  black,yellow,green,blue,pink,white,red , times to 1000 and repeat to true. So if the user doesn't provide an input these are the values that are going to be used. After these lines of code you can freely access the colors variable for example, knowing that it'll always have a value.



var inputObjects = AutoTools.fieldsToObject("colors","times");

Here I'm creating an object that was created based on the user input. It takes all the input fields and creates a javascript array with them for easy access. For example, after this line I can access inputObjects[0] (accessing the first position of the array) and that will contain an object with "colors" and "times" fields, which I can access directly. 

Check here for more info on this function




const firstColor = inputObjects[0].colors;
const firstTimeToSleep = inputObjects[0].times;

Getting the first color and time to sleep from the object, so I can use them easily below.



inputObjects.shift();

Since I'm going to be using the first values of the arrays directly, I'm going to remove the first item from the array here. I won't be needing this anymore outside of the  firstColor and  firstTimeToSleep variables I created above.




AutoTools.addStyle(`
#color{
width: 100vw;
height: 100vh;
background-color: ${firstColor};
   transition: background-color ${firstTimeToSleep}ms linear;
}
`)

Now I add the style for the first color and time. Since this style depends on user input I couldn't add it at the start of the file along with the other styles, because that can't use user input. I can easily add some css styles dynamically with the AutoTools.addStyle() function.

This is setting the style for the div with the id color that was added to the html page above. It's making sure it occupies the entire screen, setting the background color to the first color on the list and setting the transition time of the background color to the time the user selected in the input. This will make sure that the first color of the screen will be the first color the user selected, and the time it takes to transition to the second color will also be according to user input



for (var i = 0; i < inputObjects.length; i++) {
var input = inputObjects[i];
AutoTools.addStyle(`
#color.${getColorClass(i)} {
 background-color: ${input.colors};
}
`)
}

Now I go through all items in the inputObjects array and add a custom style for each one. I do this by creating a style for a specific css class whose name is gotten by the  getColorClass() function I mentioned earlier. So, for example, if I had gotten red,green,yellow from the user to use as colors:

- the red item with already be gone because of the  inputObjects.shift() performed above

- for the green item I wold create a style like

#color.color0 {
 background-color: green;
}

This means that when the color div on the page has the class set to color0, it'll have a green background color

- for the yellow item I would create a style like

  #color.color1 {
    background-color: yellow;
  }




const colorElement = document.querySelector("#color");

Simply getting a reference to the color div element on the page so I can change it from javascript




var cycleColors = async () => {
var timeToSleep = firstTimeToSleep;
var index = 0;
for(var input of inputObjects){
colorElement.className = getColorClass(index++);
await sleep(timeToSleep);
if(input.times){
timeToSleep = input.times;
}
colorElement.style.transition = `background-color ${timeToSleep}ms linear`;
}
if(repeat){
setTimeout(cycleColors,0);
}
};

This is the main function of the whole thing. This will cycle the colors the user has provided in the screen's input.



var timeToSleep = firstTimeToSleep;
var index = 0;

Just providing some initial values for the loop below.




for(var input of inputObjects){
colorElement.className = getColorClass(index++);
await sleep(timeToSleep);
if(input.times){
timeToSleep = input.times;
}
colorElement.style.transition = `background-color ${timeToSleep}ms linear`;
}

For each input in the inputObjects array, I'll set the class name of the colors div element to the correct color class, so that the background color changes to the appropriate color.

Then I sleep (wait) for the time to sleep that the user has configured in the input

Then, if the input has more times , it updates the timeToSleep variable so that it can be used in the next iteration of the loop.

Then I set the transition time of the element according to the timeToSleep variable.






if(repeat){
setTimeout(cycleColors,0);
}

If the user has selected to repeat the cycle, call the function again. The reason for using  setTimeout is explained next.




setTimeout(cycleColors,0)

This is the final line of the code. It calls the cycleColors function explained above. It uses  setTimeout  instead of calling cycleColors() directly because otherwise the browser would block and not correctly update the colors. By using  setTimeout  we are forcing the browser to perform the function asynchronously (in the background) and so it doesn't block and everything works. It's a weird javascript quirk :)


Ok, I'm sure that a lot of important info is missing, so please do let me know in the comments if you need any more info about any part of the code!


Hope you enjoyed this small walk-through. Let me know what you think! :)

Comments

Let me know if you have any questions!

João Dias

You put a lot of effort into this! Thank you! Going through it all.. but I think it's going to take me some time!

Robert Burton

Awesome

Mat

You can finish it now ;)

João Dias

Reading starts now

Mat


More Creators