Javascript-based progress bar

Jul 20, 2018

 

Hi all :)

I'm trying to set up a progress bar for my courses, and am trying to make it as simple to manage as possible.

I have the javascript code below in a timeline start trigger in the master slide for the file.  I have SL variables as follows: 

this_slide - sets the slide number on each slide (manual at the moment)

no_slides - the total number of slides in this course that I want to be counted by the progress bar (manual, set by altering the variable's default value)

Progress - The number that should be returned by the Javascript; represents the percent completed, rounded to the nearest whole number

BarState - this is currently set to change to the Progress value when it changes; I thought I'd be using this to set the eventual state of the progress bar (which is a 100 state image - well, currently 50 states I think).  This bit isn't fixed yet, just wanted to get the JS playing ball.

Basically, it doesn't seem to return the variable to SL and I'm not sure why.  The variables remain at 0.  The Progress function works with manually assigned variables as I've tested it in the Chrome console.

If anyone has any clue why it's not working, I'd be very grateful for some help :D I'm attaching the .story file I'm testing it in.

var player = (GetPlayer);

var totalSlides = player.GetVar("no_slides");

var currentSlide = player.GetVar("this_slide");

var Progress = function getProgress() {
var currentProgress = (currentSlide / totalSlides * 100);
var roundedProgress = Math.round(currentProgress);
return roundedProgress;
}

player.SetVar("Progress",Progress);

16 Replies
Nicola Fern

Bums. You know when you spend ages working on something that isn't your thing? That! Thanks :)

So it still isn't working, but now I'm getting 'NaN' returned, which I think means Not a Number? This is something I was getting before while I was working out how to go about this.

Any ideas?

Updated file attached.

Nicola Fern

It's nearly working now, just need to tweak something as it's ignoring slide 1 so the numbers are all off by a slide.

I was missing calling the Progress variable in the js as a function, so the variable setting line for the player needed to be: 

player.SetVar("Progress", Progress());

I'll post the full example when I've got it the way it should be.

Nicola Fern

It was to do with when the JS was firing - I had it set to run on timeline start on the master, and also had the number set on the slide on timeline start. I changed the JS to fire when the variable changed and it works marvellously.  Just need to finish all my progress bar states and triggers and I'm in business :)

Malathi Kandadai

Hi Nicola, 

Thanks for sharing this example. I used extended your example to make a  visual bar with that holds the percentage value as text. 

The .story file is attached. 

I still need to test it on a large scale 100 screen+ application with multiple scenes. 

Eager to hear your progress. 

 

 

 

Nicola Fern

Hi all

I've got a working template now that I've started integrating into my previous courses.  I was off last week but managed to finish it yesterday.  The basic .story file is attached, along with some notes on customising it.

The text on the master slide can be deleted - it just provided proof it was working OK and storing the variables correctly.

This is the complete, working version of the Javascript - the variables are explained in the original post: 

var player = GetPlayer();

var totalSlides = player.GetVar("no_slides");

var currentSlide = player.GetVar("this_slide");

var Progress = function getProgress(state) {
var currentProgress = (currentSlide / totalSlides * 100);
var roundedProgress = Math.round(currentProgress);
return roundedProgress;
}

player.SetVar("Progress", Progress());

Nic

Malathi Kandadai

Thanks Nicola. This really clarifies.

I was thrashing about trying to see whether a method that avoided 100 state images existed. But after looking at your file, I am reassured that there is no other way. 

My concern was whether loading 100 state images in the master slide will slow down package load.  

Have you already tested your learning package delivery via an LMS? 

 

 

 

 

Malathi Kandadai

Thanks, Michael. But even so when I click Edit states to modify colour or weight of the progress bar Storyline hangs. (Screenshot attached) 

Is this happening for anyone else? 

In her code Nicola is referencing a parameter state. How is this being currently used? Can it be used to reference the progress bar state with a given number? 

var Progress = function getProgress(state) 

Nicola Fern

HI

Yes, multistate images or objects can cause issues when editing them.  I have a high spec workstation and it does slow down even that, but it's far from unusable for me.  I tested the output on our moodle server and I found it has no percieved impact on the speed of the courses. Our courses tend to be in the 70-90MB region anyway due to the amount of audio and imagery we use.

You could decide you don't want the progress bar to be so accurate if you wanted - you could then split it into say 5 or 20 percent increments and work that way - you'd need to modify the maths in the code though.

The Progress var declared contains a function (the bit in the curly brackets) - the function defines currentProgress to find the percentage completed, and then roundedProgress, which rounds that sum to the nearest whole number and then returns that as the value of Progress.  The (state) in brackets doesn't mean anything outside of the JS code.

var Progress = function getProgress(state) {
var currentProgress = (currentSlide / totalSlides * 100);
var roundedProgress = Math.round(currentProgress);
return roundedProgress;
}

The issue is then that internally SL doesn't see the states as numbers, it sees them as text labels. There is no state 50, there's a state with a label of '50'.  If it worked numerically like that then you could have one trigger that says when variable changes, adjust this state to match.  It would be much cleaner.  Also I found it massively frustrating that you can't reorder the states once created - which is why state 1 is in the middle! I initially had that as state 1 but then realised a bit late that I needed 1 to be blank - I was NOT about to redo the ones I'd done at that point!

Hope this helps...I'm new to the whole Javascript thing so if anyone has any better ideas, I'm all ears!

Nic

 

 

This discussion is closed. You can start a new discussion or contact Articulate Support.