Changing state directly from JavaScript?

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?

33 Replies
Math Notermans

After some more digging into Storyline's states-approach i discovered that SL handles states different depending on the amount of images used. As seen in a post above for only 2 images it creates 2 hidden Divs and toggles those. If it would handle it the same for multiple images, my approach above would work and then you could control any amount of states. But it handles multiple images differently. When more then 1 image there is only 1 SVG and the source image for that SVG is replaced by an png/jpg when switching states. Thus having multiple scenarios for states makes it really hard to script that consistently with Javascript.

Thus said i switched the approach, and found a well working solution.

Enter: the sprite and clippath approach...
In this sample below there is only 1 image... a large png, visible at start. When you click any of the state buttons the state is scripted. What happens is that with Javascripted the DIV gets masked with a clippath and then the complete DIV gets moved so it stays more or less in position. Ideally i would use background-position to move the image but it doesnot work ( yet )

stateLike

State like setup

For now this is a nice solution to get a state-like setup that you can script with Javascript.

As always i use JQuery and GSAP, all of this you can do in Vanilla Javascript, but i like the ease of use of GSAP for this.

Elaine Powell

That's awesome. Editing those states could be the answer to so many development problems.

So each state is a toggle? Like NormalState0 & NormalState1 for Normal?

When you can, please share your javascript code for these. I have an idea accessing these states might be a big deal.

I didn't read the whole comment thread. I've got your code.

Thank you so much!

Math Notermans

Hi Elaine, offcourse i will help you all the way. In fact jQuery is only a library that eases up selecting elements, and thus should not complicate things but make it easier :-) GSAP especially TweenLite , a older version of GSAP is used in Storyline itself for all animation. That said i gladly help you step by step. Either here in the forum or by direct mail or however...

Math Notermans

Luckily last month i figured out that Storyline as is uses TweenLite internally for all its animation. All transitions, animation and Motion Path animation you make in Storyline in fact is done behind the scenes with GSAP's TweenLite.

If you check some of my recent posts you will find samples of how to work with TweenLite in a standard Storyline. So i just tested this on my Sprite-state Storyline and as expected it really simplifies it. You can remove the WebObject and JQuery completely and with quite simple vanilla Javascript code trigger a Sprite animation as shown above in Storyline.

Steps to create a Sprite-animation in Storyline

Step 1 : Create your image
I found that easiest is having a long image with all steps/states next to eachother.
Ensure position of your steps in your image is ok. I use Photoshop to create it.
Online there are lot of tools to create a sprite too.
eg: https://www.piskelapp.com/ or https://www.toptal.com/developers/css/sprite-generator/
If you use Photoshop or Illustrator there are luckily also plugins to help create sprites.
https://www.formfcw.com/dev/spritecssgenerator/
I used this script to create a sprite from the PSD added.

sprites001

Resulting in this one sprite in which the images are perfectly positioned.

sprites2

Step 2 : Into Storyline
In Storyline after you imported the image, keeping the image at 100% makes it easier to script the position later on...

100percent

Now you need to be able to select it with Javascript. Easiest way is giving it a custom 'accessibility' name. You dont need to do this perse. You can select a image with its auto-generated acc-name, in this case 'mySprite.png', but i prefer changing that to ensure its unique.

accname

Step 3 : Javascript Fun
As said TweenLite is included and used in Storyline, so now its easy in fact.
Create an 'Execute Javascript' trigger that acts when the timeline starts.
Add the following code..
var StorylineSprite = document.querySelectorAll("[data-acc-text='someSprite']");
TweenLite.set(StorylineSprite, { transformOrigin: "left top", x:"0%" , clipPath:"inset(0% 90% 0% 0%)"});
As you can see in the image below, coding inside Storyline is no fun due to missing colorcoding. I use Sublime Text for all my Javascript. The colorcoding helps great to see errors and ensure your code is fine. I also always name the layer of an element in Storyline to its 'Accessibility Name' That way its easier to quickly see how you named elements. If you did...

jsCode

Depending on the amount of steps you have in your sprite. The 90% offcourse can vary. I have 10 images in my spritesheet to make it easy for myself.

Step 4 : Adding a button and state
Now we can add a button and animate the clippath. As you have to know how the values in the clippath animation influence your 'state-animation' its often easier to change the TweenLite setting a bit to see whats happening.

In the previous step we used TweenLite.set.. 'Set' immediately sets a value. So no time used..when triggered the clippath is set to the position asked for. 'TweenLite.to animates over time... so then you can see how your clippath is changing.

Some code like this will do the trick to see how the clippath moves...
var StorylineSprite = document.querySelectorAll("[data-acc-text='someSprite']");
TweenLite.to(StorylineSprite, 5,{ transformOrigin: "left top", x:"-240%" , clipPath:"inset(0% 80% 0% 10%)"});

First line should be clear now.
Selecting 'someSprite' with a vanilla selector
var StorylineSprite = document.querySelectorAll("[data-acc-text='someSprite']");

Then the TweenLite call
to: tweening to something (set or from are other possiblilities)

When using 'to', we need a duration...thats the 5... dont forget the comma behind it,cause all are arguments to pass to TweenLite.
StorylineSprite, 5,{ ... }

If you found the proper values for the clippath...then switch from 'to' to 'set' and you are done.
Alas is getting the proper x position with the Modern Player somewhat complex. Have some other posts dealing with that... If you have a case/course to work with we can figure that out together...