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
I haven't looked at your file, but at a glance it should be:
var player = GetPlayer();
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.
OK, I'm getting there.
I renamed the Progress variable and created a new one as a text variable....The code is returning the code of the Progress variable rather than the value.
Digging...
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.
It might not be "ignoring" slide 1, it might be counting starting at 0, which is/was a common way that coding languages deal with handling numbers.
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 :)
This post was removed by the author
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.
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
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?
By the way, the various states in Nicola's file are not images, but Storyline shapes. That should greatly reduce the size of this object.
This post was removed by the author
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)
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
I like it! It is nice clean and simple (apart from the 100 states and triggers you created.
Thanks for sharing.
Thanks Phil :)
Yeah, there wasn't a way around that issue that I could see - At least you only have to do it once (or just import mine)...
I have done it a few times on sliders and animated graphs you always miss a trigger and spend time troubleshooting.
Your will work perfectly thanks!
Hey Nicola,
Thanks for the updates. It is reassuring to find that the concept works for large Articulate file sizes and you have tested it on Moodle.
Moodle is quite a slow LMS,
And yes, I was veering to cutting back on the number of states. For me, 33 -35 is proving to be a sweet spot.
This discussion is closed. You can start a new discussion or contact Articulate Support.