Making your projects interactive and interesting with a little bit of code

Introduction:

Instructional designers, instructors and trainers who want their eLearning to go beyond presentation might consider acquiring a new skill:  basic coding.  Learning a little code will help you track learners, adapt to their performance, change the direction of the activity, visualize learner’s performance and so much more.  You don’t need to become a computer scientist or even a computer programmer.  You need to learn a few skills that are on the same level of complexity as the Excel spreadsheet formula language.  You need to learn about variables, functions, and conditional statements.  This project will help you learn those skills.

The objective of this lesson is to create a working traffic light. When the learner clicks a button the traffic light will change. This project makes use of variables, functions, and conditional logic.  You will be able to apply these basic principles to your own projects.  We chose traffic lights because you will easily recognize when you have got it right.  We also introduce the power of SVG graphics in this tutorial.  You will learn more about them. 

Before we begin, a note about the step-by-step instructions:  First, I use the words ‘code’ and ‘script’ interchangeably.  Secondly, when we get to writing code, I’ll display the line of code and provide a detailed explanation of what it does. That is as important as the line of code.

So, let’s get started. If you would rather watch me create this project first and then attempt it, go to this link:

LodeStar 9 — Elements Of Interactivity – YouTube

 Download the most recent version of LodeStar

The instructions in this DIY tutorial work on LodeStar 9 build 7b or greater. This build was released on April 10th, 2021.

You can download the latest release from https://lodestarlearning.com/.

Select the ActivityMaker template:

ActivityMaker is a great place to start.  It has everything we need.    

  1. Select the ActivityMaker template.  (The first template).
  2. Click on ‘Create Project’ and title your project.  Call it Traffic Light Demo.

Create the first two pages

  1. Once the project opens, click on the HTML Editor and create a title page.  Give the page a page ID of ‘Intro’.  Page Id’s are important when we use branching logic.  Each page has a unique identifier that the program code understands.  The Page ID also gives the page a human-friendly name.
  2. Click on the + button at the bottom to add a new page to the project.
  3. Page forward to page two.  Notice that page two is the same page type as page one.  That works for this project.  Give page two the Page ID of “Traffic lights”.

 

Bitmap Graphics and Vector Graphics

We will be using bitmaps and vectors. Let’s learn about them. Bitmap or raster images are created with a collection of bits or pixels. They are spreadsheets of color values and they can’t be scaled up without loss.  Vector graphics are shapes with properties like fill color, stroke width and placement that are modified by mathematical formulas. They can be scaled up without loss of clarity.  It is very difficult programmatically to address a part of a bitmap image (a tree for example) and change its properties.  On the other hand, some types of vector graphics are composed of elements that can be targeted in much the same way as an HTML element (a part of a web page). We’ll see what that means in the traffic light demo.

 

Create the SVG

SVG is an acronym for Scalable Vector Graphic. It is a type of vector graphic that is supported by most modern browsers.  SVG includes the language to define shapes such as paths and outlines consisting of straight lines and curves, bitmap images, and text. Computer commands use this information to draw the objects to the screen at any scale.  An SVG path element looks sharp whether displayed on a smartphone or a Jumbotron.  SVG Elements (parts of the drawing) can be grouped, and styled.. SVG drawings can be interactive and be changed dynamically with, you guessed it, computer code.  A green circle, for example, can be turned yellow by a piece code known as a function or command.  We’ll learn all about them.  Our first task is to bring in a bitmap graphic of a traffic light and combine that with our SVG.  A bitmap graphic is a jpeg or a png file.  A regular image.  You can find hundreds of traffic lights on the web. Here is what we are looking for:  traffic light png – Google Search  Try to find one that is open licensed.  Save that to your local drive.

After you have found your image, do the following:

  1. Click on the SVG button on the HTML Editor.  That brings us to the SVG editor.
  2. Select the image tool (see screenshot) and click anywhere on the canvas to place the image.
  3. Select the traffic lights that you downloaded.

 

Combine Vector Graphics with the Bitmap

After we imported our traffic light bitmap, we’ll draw circles to cover up the lamps.

  1. Select the ellipse (circle) tool and draw a perfect circle by holding down the shift key and dragging.    Color the circle gray by using the palette at the bottom of the screen.
  •  Clone or rubberstamp the selected circle to cover up the yellow and red lamps.

 

 

Make a note of the ID of each circle

SVG elements such as rectangles, circles, and paths have an automatically generated unique id.  It is like a serial number or a social security number.  We can use this id to target the svg element and change its properties.  Here is how to view the ID.  For now just take note of where it is.

  1. Select one of the circles. 
  2. Look for the id on the toolbar of the SVG editor.
  3. Note that each of the ids of the circles is similar with, perhaps, only one digit difference.

Create the push button to operate the lights

  1. Create two more circles as pictured below.  Use the fill tool (the bucket) to give the inner circle a gradient.
  2. Select both circles and use the G key to group them into one object.
  3. Click on the ‘Fit to Content’ button to size the canvas to the objects.  Be sure no object is left at the edge.  You may need to move your objects in a little so that they are not cut off.

Add a branch option

Now comes the interesting part.  We will add a branch option to the button we just created (the grouped circles).

  1. Right click on the button and select ‘Select Branch Options’.  These are the branch options that get executed when the object is first selected.  Optionally, the ‘De-select branch options’ get executed when the object is deselected (i.e. clicked on a second time).
  • From the Branch Options dialog, select Execute Commands.  Then select the ‘Edit’ button to enter the script editor.
  • In the script editor, click forcefully on the first line to activate the editor.

Enter your script (code)

What happens when a student or trainee clicks on the button is decided by what you type into the script editor.

In plain language, here is what we are attempting to do:

  • Get long term value of current light  (it is stored between clicks)
  • If current light is not a number, assign 0 to it
  • If current light is less than 3, add 1, else set it to 1
  • Save the value of current light into long term memory
  • Turn all lamps gray
  • Switch to a different path based on value of current light

In other words we want the traffic light to progress from green to yellow to red to green after every click.  To store the last light that was illuminated, we need to define a place in the computer’s memory.  Now let’s get to the code.

  1. Type in each of the following lines and then read an explanation of what it accomplishes.

var currentLight = getValue(“currentLight”);

Expanation:  “currentLight” is a slot in the computer’s memory.  We store the value of the lit traffic light there.  1 = green; 2 = yellow; 3 = red;

getValue is a function.  The purpose of this function is to retrieve the value that is stored in memory.

Functions often have an input and an output.  In this case, the string of characters “currentLight” serve as the input.  The output is the actual value stored in memory.

We assign the output of getValue to a local variable called currentLight.  currentLight is a local variable and “currentLight” (with quotes) is the label of the memory slot that holds a value for longer term storage.

Local variables disappear once the block of code has been executed; the longer term storage labeled “currentLight” persists for the life of the activity.

Variable names are case sensitive, must be one word, and can’t start with a number or symbol.

The keyword ‘var’ tells the computer that currentLight is intended to be a variable.  The = sign is actually an assignment operator.  That means that the output of getValue is assigned to the variable.

Technically, a copy of the value is made and stored in the local variable.

Lastly, the semi-colon at the end of the line terminates the line.  It’s a computer geeky way of punctuating the line so that the computer can make sense of it.

var isNum = isNumber(currentLight);

Explanation:  The isNumber function takes the input of currentLight (i.e. the value that currentLight holds) and returns true if the value is a number and false if it is not.  The first time this code is run, isNumber will return false because currentLight is “undefined”.  We haven’t stored anything yet.  True or false gets assigned to a local variable called ‘isNum’.  Once again, var identifies isNum as a variable.

if(!isNum){

      currentLight = 0;

}

Explanation:  We’ve now seen the use of a function and the use of a variable.  Here is our first conditional statement or, in other words, the ‘if’ statement.    Let’s first look at a simpler if statement and then we’ll return to the trickier one.  Type the following:

if(currentLight < 3){

    currentLight = currentLight + 1;

}

else{

    currentLight = 1;

}

Explanation: The keyword ‘if’ is followed by parentheses.  If the expression inside the parentheses evaluates to true, then the first block is executed.  The first block is defined by the curly braces.  {   }.  If the expression inside the parentheses evaluates to false, then the else block is executed.  The else block is defined by the second set of curly braces.  So, if currentLight holds the value of ‘1’, then 1 is indeed less than 3.  Therefore the expression inside the parentheses evaluates to true.  The code in the first block gets executed, which means that currentLight is assigned the old value currentLight plus 1.  In other words, currentLight is assigned the value of 2.

With those rules in mind, let’s return to the first conditional if statement.  The first time this code executes, currentLight will be undefined. Is ‘undefined’ a number?  No it is not.  Therefore isNum is assigned the value of false.  The expression inside the first if parentheses is !isNum.  The ! symbol makes this a bit tricky.  It inverts the value of isNum.  If isNum is false it now evaluates to ‘true’.  The if statement evaluates to true when currentLight is undefined.  The outcome is that currentLight is initialized with the value of 0.  So the very first time we click, currentLight will equal 0 after the first if statement.  Now let’s move on to the second if statement.  Is 0 less than 3?  Yes.  Yes is synonymous to ‘true’.  Therefore currentLight will be assigned the old value of currentLight plus 1.  The old value of currentLight was 0.  0 + 1 is now 1.  After the second if statement, currentLight holds the value of 1.  So, to repeat, the very first time we click, currentLight ends up with the value of 1. 

setValue(“currentLight”, currentLight);

Explanation: setValue is a function that does the opposite of getValue.  setValue stores the value of currentLight in a memory slot labelled “currentLight”.  The slot in memory does not need to match the name of the variable.  The label, however, used in getValue must match the label used in setValue;

changeColor(“ls1617676199534_2”, “#CCCCCC”);

changeColor(“ls1617676199534_3”, “#CCCCCC”);

changeColor(“ls1617676199534_4”, “#CCCCCC”);

Explanation:  changeColor is a function.  It takes two inputs and does something with them.  Another word for input is argument.  That’s a really geeky term.  Who’s arguing?  Nevertheless, inputs are called arguments.  The first argument or input is ID of the element whose color property we are changing.  By that I mean the circle.  You cannot use my values.  You need to follow an earlier step and use the IDs of your circles.  They will be different.  You can ‘Save and Close’ and return to this code after you copied the circle ID’s to a notepad. The second argument is the color value.  Now, here is another geeky thing.  It is common to express computer colors with hexadecimal values.  # means hexadecimal.  The first pair of CC is equivalent to the decimal value of 210.  The three pairs of CC create the color gray.  We could substitute “#CCCCCC” with the word “gray”.  It is a slightly different shade of gray.  I prefer #CCCCCC, but admit that “gray” is simpler.

Finally, type the following:

switch(currentLight){

    case 1:

changeColor(“ls1617676199534_2”, “#00FF00”); 

break;

    

    case 2:

        changeColor(“ls1617676199534_3”, “#FFFF00”);  

        break;

    case 3:

         changeColor(“ls1617676199534_4”, “#FF0000”); 

        break;

}

Explanation: The ‘switch’ statement is another type of conditional like the ‘if’ statement.  It’s like a train track switch.  Train #1 goes down the case 1: track.  Train #2 goes down the case 2: track, and so forth.  What is train 1?  That is what currentLight evaluates to.  If currentLight holds the value of 1, we go down the first track and execute changeColor(“ls1617676199534_2”, “#00FF00”), which means that we turn the first lamp green.  We could replace  “#00FF00” with “green”.  If currentLight holds the value of 2, then we change the second circle to yellow.  If currentLight holds 3, then we change the third circle to red.  Our code only permits 1, 2 or 3.  That is because our second if statement, resets currentLight to 1 when currentLight reaches 3.

The hexadecimal values represent three pairs.  The first pair is Red.  The second pair is Green.  The third pair is Blue.  FF0000 means full red and no green and no blue, which produces the red color.  #00FF00 means no red, full green, and no blue, which produces the green color.  FFFF00 means full red, and full green and no blue, which produces yellow.  In computer color, equal amounts of red and green light produce yellow light.

So here is the code in its entirety.  If you simply cut and paste, the code wouldn’t work because the SVG element IDs would be incorrect.

var currentLight = getValue(“currentLight”);

var isNum = isNumber(currentLight);

if(isNum){

   currentLight = currentLight;

}

      else{

            currentLight = 0;

}

if(currentLight < 3){

    currentLight++;

}else{

    currentLight = 1;

}

setValue(“currentLight”, currentLight)

changeColor(“”, “#CCCCCC”);

changeColor(“”, “#CCCCCC”);

changeColor(“”, “#CCCCCC”);

switch(currentLight){

    case 1:

        changeColor(“”, “#00FF00”); 

        break;

    case 2:

        changeColor(“”, “#FFFF00”);  

        break;

    case 3:

         changeColor(“”, “#FF0000”); 

        break;

}

Test your code

  1. Click on the ‘Test’ button.  The test won’t reveal logic errors but it will highlight basic issues like forgetting a semi-colon or misspelling the name of a function.   The real test comes when you preview the project in a browser.

Save and Preview

  1. Click on the ‘Save and Close’ button (to the right of ‘Test’) to save your script and exit the editor and return to the Branch Options dialog.
  2. Click on the ‘Save’ button to exit the Branch Options dialog.
  3. Click on the ‘Save to Page’ to save and exit the SVG Editor.
  4. Click “Preview in Browser” to see your project work.  Go to page two and click on the button to change the traffic light.  If this worked for you, leave a comment. If not, edit your traffic lights. Back in the LodeStar, click on the traffic light on the page, then when the image dialog opens, select ‘Edit’.

 

Conclusion

You did it.  You learned how to use a variable to store a value.  You learned the definition of a function and how to use one.  (You can find more LodeStar functions by clicking on the ‘Help’ button in the script editor. )  You also learned two types of conditional statements:  the “if” and the “switch”.  With the use of variables, functions, and conditional statements, the sky is the limit in terms of what you can do.  We’ll soon publish a more thorough article on LodeStar functions and what they can do.  In the meantime, the next best step is to create your own simple project.  Don’t rush into applying this to a ‘real’ project.  Play a little first.  Soon you will be able to achieve a higher degree of interactivity, store learner information, create branching conditions based on the information, and much much more.