Table of Contents
Changing Color Dynamically
Examples
Change Color When Event is Approaching
{c1bp} <= ({dtp}+(1/24)) and 'FF0000' or 'FFFFFF'
Gradually Transition Color As Battery Drains, From Green to Yellow to Red
{bl} > 66 and string.format('%.2x%s',(100-{bl})*255/33,'FF00') or {bl} > 16 and string.format('%s%.2x%s','FF',({bl}-16)*255/50,'00') or 'FF0000'
Introduction
Changing colors dynamically could be useful for making information stand out when it is most important, or to use color in familiar ways to represent information.
When creating code that sets the color of an object, it's important to understand how that code looks and what it means. Color code is a 6 digit hexadecimal number that represents the amount of red, green and blue in that color. The first two digits are the amount of red, the middle two digits are the amount of green and the last two digits are the amount of blue. Each pair of digits has a minimum value of 00 (none of that color at all), and a maximum value of FF. Hexadecimal FF is equivalent to 255 in decimal. The code '000000' gives you the color black, and 'FFFFFF' gives you the color white.
Hexadecimal is a number system that uses base 16, instead of the base 10 that our decimal number system uses. This means the numbers 0-15 can be represented by a single digit, to represent those numbers past 9, alphabet characters are used (i.e. 10 in decimal is A in hexadecimal, 11 is B, 12 is C, 13 is D, 14 is E, and 15 is F).
In Watchmaker, you can insert code into the color field by selecting the color field of an object, then tapping the 6 digit color code directly under the check mark. This will open up the standard variable list you see when editing other fields. From here you can use any variable you want to create conditions that will result in different colors, or even create a color that depends on a variable.
Explanation of Examples
Change Color When Event is Approaching
{c1bp} <= ({dtp}+(1/24)) and 'FF0000' or 'FFFFFF'
This code is intended to set the color of an object to red when the next event on the agenda is less than 1 hour away, and it will set the color to white if there is more than an hour to the next event.
{c1bp} is a variable in Watchmaker that gives you the beginning time of the next event on the agenda as a percentage of a 24 hour day. We are testing to see if this number is less than the current time plus one hour ({dtp}+(1/24)). If that comparison is true, the code will return the part after the word “and” ('FF0000'); if the comparison is false, the code will return the part after the word “or” ('FFFFFF'). 'FF0000' gives us a nice bright red, 'FFFFFF' gives us a white.
You could expand this example by creating multiple conditions, an easy expansion would be something like
{c1bp} <= ({dtp}+(1/24)) and 'FF0000' or {c1bp} <= ({dtp}+(2/24)) and 'FFFF00' or '00FF00'
This variation would make your object green if the next event is more than 2 hours away, yellow if it is 1-2 hours away, and red if it is less than 1 hour away.
Gradually Transition Color As Battery Drains, From Green to Yellow to Red
{bl} > 66 and string.format('%.2x%s',(100-{bl})*255/33,'FF00') or {bl} > 16 and string.format('%s%.2x%s','FF',({bl}-16)*255/50,'00') or 'FF0000'
Here again we are using a condition to set the color value of an object, this time the condition is {bl} > 66, and the value we get is a function of the battery level: string.format('%.2x%s',(100-{bl})*255/33,'FF00'). I will explain what that means, but the idea is the amount of red increases as the battery lowers from 100 to 66, effectively transitioning the color from a bright green to a bright yellow.
The string.format function is how you build a string in LUA. I am using it here to convert the decimal number generated by the formula (100-{bl})*255/33 into a hexadecimal number that is part of a 6 digit string that is the color code I want displayed. The part in the parenthesis after “string.format” are the function arguments, each argument is separated by a comma. So the first argument is '%.2x%s', second is (100-{bl})*255/33 and third is 'FF00'.
Let's talk about that first argument, you always need something like this when you use string.format. It always needs the single quotes (' '), and in those quotes is a code that tells LUA what our string will look like. In this case, %.2x tells it the first thing in our string will be a 2 digit hexadecimal number, and %s tells us it will be followed by a string (some letters or numbers). The formatting here is also important, note that there is no space between %.2x and %s, this tells LUA that there shouldn't be a space between the hexadecimal number and the string.
The second argument is a linear formula that uses the battery level as its variable. It correlates to the %.2x in the first argument. The formula itself is: (100-{bl})*255/33. I'm using this formula to set the red value of the color, I want it to be 0 when the battery is at 100, and 255 when the battery is at 67. Since this code only runs when the battery is greater than 66, the formula 100-{bl} will give us a number between 0 and 33. I then multiply by 255 and divide by 33 to change that range to 0-255. Simply putting %.2x in the first argument does the hard work of converting the result into hexadecimal.
The third argument is a string that is simply the rest of the color code, in this case I want maximum green and no blue.
The result is that the color changes from bright green to bright yellow with each battery decrease.
There is similar code in the second condition to transition from yellow to red when the battery level is between 16 and 66:
{bl} > 16 and string.format('%s%.2x%s','FF',({bl}-16)*255/50,'00')
In the above you should note there are now four arguments in the string.format function. The three codes each correspond to arguments 2-4 in order. The formula has changed a little because I am using a bigger range, I've decided that I want the gradual transition from yellow to red to start at battery level = 66, and end at battery level = 16.
And finally, if the battery is below 16 the color will be bright red:
or 'FF0000'
I put this code into a circle that is shaded using the segment shader option, with the code {bl}*3.6 for “degrees” and opacity 75 (to dull the bright colors a little). Then I put a black circle of the same size underneath, and a smaller black circle on top.
For help with selecting colors, visit Color Hex Color Codes