Changing state directly from JavaScript?

Jul 04, 2015

Hello Heroes!

Maybe someone out there can help me out! I've been playing with JavaScript and Storyline, you can see an example here: http://bit.ly/1IjNEKs

But, what I can't figure out is how to access an object directly from JavaScript. I would like to change the state of a graphic from JavaScript.

In the example above, if you launch the course with adding ?test=Confused at the end of the URL link, and go to Chapter 3, the character will show the confused state. But essentially, I'm changing a variable first, which leads to a trigger to change the state. If I want ten different states, that's ten more manual triggers. 

What I'd like to do is change the character's state directly. Any thoughts?

40 Replies
Lisa Jones

I'd say the ability to target an object is even more important with the removal of jQuery. We need some way to get access to certain objects. I get where "ID" would be problematic, but it could be as easy as allowing us to add a "class" to an object (and as long as that doesn't match up 1:1 with a class declared in the CSS it's ignored by any of the Articulate-generated code) so that we can search for the class name we create, then script to that class.

Math Notermans

Actually in SL360 its now quite easy to access any object onscreen by using the 'accessibility' names. You either can set the name on an element and target that... or go for the default names Storyline uses.

Code for accessing any page-element in SL360  would be something like this...

var femaleImg = $("[data-acc-text='female@3x.png']");
gsap.to(femaleImg, {duration:2,x:"-=25"});

This code selects an image with jQuery on my SL-slide which has a filename of female@3x.png and moves that then with Greensocks gsap Tweenmax 3.

At the moment working on some approaches on getting things done in SL with Javascript. Will show more of that later on...



Math Notermans

In fact if you keep a close eye on your browser inspector when changing state on a SL-button you will see that the SVG gets edited. So in principle you should be able to call that change with Javascript. I already tried to access it with Gsap, managed to change basic shapes in Storyline with that...but didnot figure out ( yet ) why i cant call a state-change in the SVG...

Math Notermans

Just figured out how to trigger states from Javascript. First of all you have to realize that Storyline use SVG to create inline SVG images from any element you import. When inspecting the output you will notice that when you create a new state ( for hover or whatever ) SL actually creates a new image for that state. With some completely absurd names like '6mCzuc95iTc_80_RFFBC7C_DX820_DY820_CX410_CY318.png' ...based upon your original name..and then some... 

with
setAttribute('xlink:href',2ndStateImg); 
you then can activate a state..in fact you are not activating a state but doing exactly the same Storyline does, you are replacing a source image.

I have this working in a sample. However as is, this is still hard to use, due to the way Storyline publishes images with those tough names. Im working on a setup that at start gets all names of the images in your Storyline and then its easy to work with.

Will share that when i got it working...

Math Notermans

Although by using the above to change an image, you can somewhat simulate state-changes, its too much trouble as is. You have to detect what images are published in SL's mobile folder... for that you need some php or other server side script. Then you can use the detected file-names to simulate state-changes and replace any given image's src. The biggest issue remains that in complex SL-files you will be clueless what filename belongs to which element in Storyline
So reusing state-images that way is too complicated.

However its easy enough to build some state-behaviour from scratch.
Import images you want to use and write code for any behaviour you need.

Will be creating a sample to show some basics for that..

Cheyenne McKeegan

Any progress on this?   I could really benefit from it.  I have a main menu that needs to change button states based on answers to questions on other pages and it'd be much better to use an

'If <answer> then <change all of these buttons> '

Than having to do a trigger for each one which has gotten very slow and produced some flashing artifacts.  

Cheyenne McKeegan

Hmm, can those images be used as buttons and also have a hover state?  

First thing I tried was this:  

The button starts out on normal. If the user answers correctly, it changes to the green and incorrectly to the red.  I tried to manage hover states using the hover trigger and changing the state to either darkstate, darkgood, or darkbad.  However, on moving the mouse off of the button, the button would sometimes completely disappear as if the forced "Restore previous state when the user hovers out" was getting confused.  

My second implementation put each button on a separate layer with their respective triggers, but still had the same disappearing issues.

My third implementation split all of those into 3 separate buttons which I then hid or unhid, however the logic behind that using triggers causes things to be checked every time the timeline starts and since I have 10 of these buttons, that has been resulting in a slow down of the page load time but did fix the disappearing buttons.  

 

Math Notermans

First steps done. So in the course attached images on screen are hidden and shown by Javascript.

( Sample on Review )

Main trick behind is is using the 'accessibility-names'. When you check the title you notice the image-buttons are named 'state hatch bad' etc, as you can see in this image.

accessibility names 

For ease of use in coding Javascript i always rename the layer to its accessibility name. Thus making it easy to find and remember naming. The 'space' in the naming makes it easy to select all elements...by using a selector like this...
$("[data-acc-text*='state']"
or a specific subselection of the elements...
$("[data-acc-text*='state dark']"
or even a specific element $("[data-acc-text*='state dark good']"

The sample as added uses a Webwindow with specific Javascript libraries to ensure all works. I always use JQuery and GSAP Tweenmax. As is GSAP is not free, when you want to use GSAP animation on a course or site, you need a licence. Its totally worth it for sure.

https://greensock.com/gsap/

This for sure not yet is a solution for how to script 'states' with images. Its only a first step. Next step will be replacing an images source. Then its quite a bit closer to the way Storyline handles its states...That will be next step i show.

Math Notermans

Diving a bit deeper into the 'states' of Storyline gave me some more insights and i can control a state now by Javascript. At least when its purely an image...if you use Storyline filters on images...that has to be emulated by script then too.

Check out this sample.

States showing/hiding with Javascript

Its an element with 2 states. The top 2 buttons 'Set State1 SL' and 'Set State2 SL' do just that...standard Storyline actions that enable a state.

After some digging into Storyline i noticed that for states the DIV is just toggled. So set to visible or hidden. With Javascript i can trigger visible DIVS, but when one is hidden i cannot. Thus the button getElements. Clicking that button makes both DIVS visible and then the buttons set State JS work...toggling visibility on the 2 states.

Gonna finetune that with Sharon's sample...