Building A Calculator – Part 3 – Numbers on the Display

In the last two posts, I presented a basic calculator and also a quick rundown on creating the framework – or really just the graphical elements of the calculator itself. In case you missed those, you may want to catch up – with the following links.

Part 1 – The Calculator

Part 2 – The Framework

In this post, I want to work through the code used to put the number buttons (0-9) on the display as well as the decimal as that is a part of the numbers.

Challenges
When I first got started on this project, I thought I would use the concatenate technique to populate the numbers to the display. Initially, this seemed to work OK as I played with whole numbers 1 through 9. The tricky part is that every number button press needs to update the same variable until a function button is pressed. Concatenation seemed a good fit for this. I ran into issues when it came time to add the zero or a decimal point though. What was odd is that with the zero – it was fine if the zero were part of a number such as 207 but would sometimes struggle with numbers like 0.007 where there were leading zeroes or 2000 where there were trailing zeroes. In some cases, Captivate merely stripped the zeroes and in other cases, they did not appear until the button was pressed a second time or until a number other than zero was press. So – for example, in typing 2005 – pressing zero the first time would result in just showing the 2, but pressing zero a second time both zeroes would appear. It was similar for the decimal point – for some reason it did not appear until pressing a number afterwards. So the behavior was not what I wanted it to be.

A second challenge was dealing with floating point math. Those pesky results when you start dealing with decimals in particular and suddenly an answer of 7 is displayed as 7.00000000000001 or some other crazy value. More on this when we cover the equals button.

Below, I present my solution which only performs a single calculation at a time. I was satisfied with that for the time being and will try to figure out how to make it so that you can do multiple sequential calculations somewhere in the future.

Displays
There are actually three displays which are represented by three different variables.
The variables are

  • d1 – for the first number in the calculation
  • d2 – for the second number in the calculation
  • ans – for the result after the equals key is pressed

These variables are keyed into the smartshapes used for the displays as $$d1$$, $$d2$$, and $$ans$$. This way, the displays will update dynamically as the buttons are pressed.

Numbers 1 through 9
Each of these numbers has a similar code with a difference simply being the number being added to the variable. In this code you will find two more variables at work.

  • btnCount – This tracks how many times a number button or decimal has been pressed
  • screen – this flag is to help with differentiating between the first or second number in the calculation. We are simply on screen 1 or screen 2.

The btnCount variable was added to help limit the number of digits to that which would fit on the display. I thought it would give it a cleaner look.

The code for each number button 1 through 9 has essentially four parts – two for screen 1 and two for screen 2. Let’s examine the code for our number 1 button. Below are the first two parts that correspond to screen 1.

if ((window.screen==1) && (window.btnCount==0)) {
d1=””;
d1=d1+=”1″;
++btnCount;
}

else if (window.screen==1) {
d1=d1+=”1″;
++btnCount;
}

In the first part above we are checking for two conditions.

  1. If we are on screen 1
  2. If no buttons have been pressed yet (by default the screen reads 0)

If these are both true – we clear the display (d1=””;) This gets rid of the initial zero on the display. Otherwise pressing the number 1 would show on the display as  01 instead of just  1.
Next, we add the number 1 to the d1 display (d1=d1+=”1″;) Notice that I put the 1 in quotes. This ended up being an important part of my solution. I needed to make sure that everything added to the displays was a string rather than a number. That does seem counter-intuitive but it was the key to making the zero and decimal work the way I wanted. Using the += we take the current value of d1 and append the number onto the end of it.
Finally, we increment the btnCount variable

The second part is an else if statement for when the first statement returns false. Here we are simply looking to see that we are on screen 1. You’ll notice that we are not clearing the display in this part. If btnCount does not equal zero – it means there are other numbers on the display and we don’t want to clear them. So we add the 1 to the end and increment our btnCount variable.

Next we can look at the two parts for screen two.

if ((window.screen==2) && (window.btnCount==0)) {
d2=””;
d2=d2+=”1″;
++btnCount;
}

else if (window.screen==2) {
d2=d2+=”1″;
++btnCount;
}

You will notice they are exactly the same as the first two parts with the exception that we are now updating screen number two. So these would be in effect when it is time to update the second display. When a function button is pressed, we leave the first display value in place and then update the second using the same logic.

The Number Zero
The number zero had to be treated a little bit differently but ultimately it was simpler – only two parts needed – one for each of our two screens.

if ((window.screen==1) && (window.btnCount>=1)) {
d1=d1+=”0″;
++btnCnt;
}

if ((window.screen==2) && (window.btnCount>=1)) {
d2=d2+=”0″;
++btnCount;
}

In both cases, we are checking which screen we are on and whether or not a button has been pressed. Remember, the default screen displays a zero so we only need to update the display if another button has already been pressed.

The Decimal
I struggled with the decimal for a while because it never wanted to show up until after a number was pressed and I wanted it to appear right away. So 5.7 would remain as 5 on the display until I pressed the 7. The same strategy as the numbers is used with the decimal and the issue goes away.

if (window.screen==1) {
d1=d1+=”.”;
cp.disable(“decBtn”);
++btnCount;
}

if (window.screen==2) {
d2=d2+=”.”;
cp.disable(“decBtn”);
++btnCount;
}

With the decimal, we don’t need to check for any other buttons being pressed because if the decimal is the first button that is pressed, we want the leading zero to remain so there is no need to clear it. If the decimal is not the first button pressed we just add it anyway. What is different is that you see we are disabling the decimal button after it is pressed so that someone does not enter multiple decimals for a given number – that would not make any sense.

Stay tuned for Part 4! We will take a look at some more code for other buttons.

The post Building A Calculator – Part 3 – Numbers on the Display appeared first on eLearning.

Adding a range slider to Captivate

Hey all,

I presented this at the 2018 Adobe Conference and thought I would share it here.

I used jQuery UI to add a slider to a course. When learners operate the slider it updates a Captivate variable.

You can view it here: https://gforce.courseportfolios.com/?course=26

And here is the code I used:

$('head').append($('<link rel="stylesheet" type="text/css" />').attr('href', '//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css'));
$.getScript("//code.jquery.com/ui/1.12.1/jquery-ui.js");

setTimeout(function() {
varhandStates= [“Normal”, “one”, “two”, “three”, “four”]
varcustomSlider=$(“#sliderArea”).append(“<div id=’customSlider’style=’z-index: 1000;’></div>”);
$(“#customSlider”).slider({
min:0,
max:4,
range:”min”,
value:0,
slide:function(event, ui) {
window.cpAPIInterface.setVariableValue(“sliderValue”, ui.value)
cp.changeState(“hand”, handStates[ui.value]);
}
});
}, 500)

The post Adding a range slider to Captivate appeared first on eLearning.

Captivate 2019 incorporating A-Frame VR, JavaScript, 360 Video

Here’s a sample Captivate file with the following features;

  • JavaScript
  • 360 Video with A-Frame VR incorporated
  • A-Frame VR scenes with JavaScript “talking” to Captivate variables
  • Captivate 10 360 Video

We’re currently creating a series of “how-to” videos demonstrating how we created this Captivate file.

Subscribe to our YouTube Channel to get updates when our “how-to” videos will be released!

Link to working sample

The post Captivate 2019 incorporating A-Frame VR, JavaScript, 360 Video appeared first on eLearning.

YouTube-style timer in Captivate

Does anyone have a working solution for displaying the movie duration using system variables and JavaScript? E.g. 01:15 / 03:30

  • I know that the movie duration is available in the TOC, but I don’t want the latter to be visible all the time
  • I have been able to calculate the total time of the project using the cpInfoFrameCount system variable
  • But I’m stuck with the current time. The cpInfoCurrentFrame system variable is what I need, but I can’t convert it to the mm:ss format:
    • I can display cpInfoCurrentFrame in a caption and it increments as the movie progresses. So far so good.
    • If I use a Captivate while loop for the conversion to mm:ss, the “Execute JavaScript” action is only executed once e.g. (while cpInfoCurrentFrame < cpInfoFrameCount)
    • I can’t add a JavaScript while loop for some reason as an action: it is removed when I save the action.
    • The “Expression” action is not powerful enough.

Any ideas?

The post YouTube-style timer in Captivate appeared first on eLearning.

Creating repositionable custom nav buttons?

Hi all!

I’m working on a software simulation project in Captivate 2019 (latest release) and I have a floating menu that sits on top of the sim to provide instructions as well as forward/back/exit buttons. My challenge is that I have a sim where there’s no good place for the group of objects to sit for the whole simulation. Is there a way to use JavaScript/HTML5 to make this something the user can move around the screen, or am I stuck duplicating the object/hiding the old one/etc?

I can find examples on how to set it up in HTML5 (https://www.w3schools.com/howto/howto_js_draggable.asp) but I’m just not Captivate-savvy enough to figure it out how to access the CSS/JavaScript. =)

It’s not a showstopper but it would be nice to be able to do it…

Thank you!

The post Creating repositionable custom nav buttons? appeared first on eLearning.

Adding Timer(Time-Limit) to Captivate Quiz using JavaScript.

Play

Although Captivate provides Widget to implement timer in Quiz(Test), following simple procedure, using JavaScript, could give you lot more freedom to program and control the Quiz. I regularly use this in the online Test of my Students.
Let me explain with example, steps required for the same.
In a Captivate project, Add following user variables:
Step 1:
User Variables:
cp_min, cp_sec, cp_time_out, time_left:
Create /add questions slides of your choice. I have added simple 5 slides in this Captivate project to explain this procedure.
Step 2:
As shown below, Insert similar Slide, just before 1st Quiz Slide.

Step 3:

“On Exit” Action of this Slide, add JavaScript as scripted below:

Explanation of the above Script: To explain it better, let me divide script in different parts :
Line 1 to 4: setting JavaScript variables and passing it’s value to Captivate. Here you can set time-limit of your choice. For Demo purpose, I have set just 2 minutes as Time-limit.
Line 7 to 23: it is the function which would be called every second by line number 24.
Inside the function: Line number 8 to 13: simple manipulation of seconds , minutes.
Line 15 to 18: checking if the time is Over. And if thime is over Resullt slide is called.

Timer(second_Passed() function) will continually check for Time elapsed. The moment time is up, JavaScript will force program execution to jump from the current question slide to the Result slide.
Note: The candidate who is giving that exam is not necessarily Failed, but marks would be counted for whatsoever correct answers he/she has given in the time-limit, and Result is displayed accordingly.

Step 4:

To inform Student, about this(sudden end of Exam due to time-out), Time-Out message need to be displayed.

In the Result Slide, following Advanced Actions is added to display “Timed-Out” Box, if time was over.

Result:

I hope this will be useful to many who want to add simple time-limit in the Quiz(online exam).

Note: Although everything is shown and working example in also hosted, I have purposely kept one ‘cache’ without explanation. And those who will do it, will come to know about that cache. Try solving that at least for some time… otherwise I will explain that Defiantly. But I strongly believe that first you must try practically.

Request to Expert: Defiantly, You may be knowing the ‘Cache’ and its solution, but please don’t explain and give solution in the immediate post. Let other do by them selves.

The post Adding Timer(Time-Limit) to Captivate Quiz using JavaScript. appeared first on eLearning.

Storyline 360 – Best practices of using JavaScript to get Custom Print Result

Though there are vivid authoring tools, Articulate Storyline would be the best possible tool to create custom elearning courses. The best practice to create more engaging e-learning courses is to include JavaScript in Storyline. Recently, we were deployed in a project where our stakeholders need an activity to be implemented such that user should take…

Scrolling Marquee Sign

I was having some fun with creating one of those signs that scrolls messages across the display and thought I would share it with you.

As with all projects – there is usually more than one way to approach them but I hope this will simply provide some inspiration for some of your own projects.
Tackle it however you choose. Here is my rendition…

My little message board is made up of several states, a couple variables, and some buttons.

Image States
Of course, I had to create enough image states to represent all the updates in the display. My example has a display with a digital readout and total  of 33 states. Basically it was nothing more than doing a one-off of each of the letters so it did not take too long to create them. I did spend a little time trying to get what I thought was a decent glow on the letters for aesthetic purposes only.

Variables
I have two variables. One to track whether the display is on or off and one for helping to adjust the speed of the scrolling.

Buttons
I have four buttons. Two speed buttons – one to increase speed and one to decrease along with two buttons for turning the display on and off.

Function
Once started, the message will continue to scroll over and over until stopped. I wrestled a bit with immediately “powering off” the display and letting it finish the message and simply not repeat again. I decided to just stop it cold in order to reduce confusion over whether the button worked or not. The speed buttons will increase or decrease the speed of the scrolling by a hundredth of a second for each click of the respective arrow.

JavaScript
I decided to run with JavaScript on this, although I did make a version using advanced actions as well. I stayed with the JavaScript on this one because I felt it offered better control over the speed. The ‘Delay Next Action’ option is too clunky for me when timing is more critical. I will admit, though, that it was quicker in this case to simply create an advanced action with a ‘While’ condition to go to the next state.

On the green power button, the JavaScript itself is a simple repeating of a setTimeout function called scroll that changes the state of the display. The final setTimeout calls the first one as long as the variable for power is flagged. Here is an example of what they look like so you can see the pattern. I am sure there is a better way to script this but I can only work with what I know for the moment. We are also setting the go variable to 1, calling the scroll function,  and disabling the green button so that the scrolling is not initiated on top of itself.

function scroll() {
cp.changeState(“display”,”w”);
if (window.go==0) {
cp.changeState(“display”,”Normal”);
}
else if(window.go==1) {
setTimeout(scroll2, speed);
}
}

function scroll2() {
cp.changeState(“display”,”we”);
if (window.go==0) {
cp.changeState(“display”,”Normal”);
}
else if(window.go==1) {
setTimeout(scroll3, speed);
}
}

On the red power button we are simply changing the go variable to 0 and re-enabling the green button.

On the speed buttons, the code simply increases or decreases the speed variable by a value of 10. The setTimeout part of the javascript uses a value in milliseconds which means a value of 1000 represents 1 second. I have the default scrolling set for 100. It is worth noting that in order to decrease the speed of the scroll, I am actually increasing the speed variable while decreasing the speed variable in order to make it go faster.

If you have any questions about this please do not hesitate to post them.

I have included a working sample below.

Play

The post Scrolling Marquee Sign appeared first on eLearning.

Accessing Image by ID containing a specific word via an external JS file?

Hi everyone, I’m working in Captivate 2017 on a responsive project. What I’m trying to accomplish is take a piece of code which ‘zooms’ (translates position and scale via GSAP API) images via one function that targets all images by whether or not their id contains the word ‘image’. I’ve created something that ‘zooms’ images using GSAP already, but the difference is I made each image page a .zip file containing an html, css, and js page. This was nice as I could control the css and html of the images, however, loading a .zip file on each slide with an image can take a minute and sometimes images don’t load right away.
I’m wondering if I can do the same effect, however with one external JS file that I’ll load into my index.html file after publish. I’m having a hard time calling/accessing images with an id that contains the word ‘image’ however. I’m not an expert coder by any means and I’ve had a lot of help from forums to get as far as I am, but essentially the code I’m using looks like this:

var targets = document.querySelectorAll(‘[id^=”image”]’);

for (var i = 0; i < targets.length; i++) {

var tl = new TimelineMax({ paused: true, reversed: true });

tl.to(targets[i], 0.6, { x: 100, y: 100 }, 0);

targets[i].anim = tl;

targets[i].addEventListener(“click”, function() {

this.anim.reversed() ? this.anim.play() : this.anim.reverse();

});

}

This method using document.querySelectorAll returns the variable ‘target’ in the console log as a node list with the length of 0 (even when on a slide that has an image on it). So I’ve tried another method:

var targets = $(“img[id*=”image”]”);

for (var i = 0; i < targets.length; i++) {

var tl = new TimelineMax({ paused: true, reversed: true });

tl.to(targets[i], 0.6, { x: 100, y: 100 }, 0);

targets[i].anim = tl;

targets[i].addEventListener(“click”, function() {

this.anim.reversed() ? this.anim.play() : this.anim.reverse();

});

}

I’ve tried this using $(“img …. and $(“div …. as I’m not sure what HTML tag captivate assigns to images? Neither of them seem to pick up my image with the id of “image43”  however. In the console log it returns as “m.fn.init [prevObject: m.fn.init(1), context: document, selector: “img[id*=”image”]”]” with a length of 0.
Anyone have an idea as to how I can call my images based off of their id and if it contains the word image? Or if I could do the same thing by calling whatever class name captivate assigns to images (how would I figure out what that is)? Thanks!

The post Accessing Image by ID containing a specific word via an external JS file? appeared first on eLearning.