GSAP 3.5.1 ( latest version ) is now included in Storyline 360

A few months ago i discovered Storyline uses the GSAP Tweening library for all its animation features. Any animation you make in Storyline somehow is triggered by GSAP under the hood of Storyline. Then i noticed that Articulate still was using TweenLite a very old and limited version of GSAP... back from 2014 :-)

Well today i discovered Storyline updated the GSAP libraries and from this day on you can animate your objects with GSAP javascript code.

For example:
Give any object in your Storyline the 'accessibility name' of "myName"
Then add a trigger to call this Javascript:

var myElement = document.querySelectorAll("[data-acc-text='myName']");, {duration: 2,scaleX:2,autoAlpha:0.5, x: "+=500"});
Your Element will move and fade and scale over the x-axis.

Really great news Articulate acted and updated GSAP.
I will check whats possible with the built-in GSAP code and what not and show that here...

46 Replies
Math Notermans

Thx Owen, for quite a while i used jQuery for selecting elements. When Articulate removed jQuery i didnot like that...but now they added the newest GSAP into Storyline im happy :-) Deleting all jQuery related things from code and using pure Vanilla JS now.

As Storyline default adds some 'accessibility-name' you can use those from scratch as selector.
My 'generic functions' i now added with a 'symbolic link' to the Articulate Programme folders thus no need for any Webobjects anymore and i can easily add any new or updated functions to my 'generic functions' that then work without hassle.

Articulate 10

I used the gsap hitTest but it's not working. I'm sure I'm doing something wrong. I first set the targetElement and hammerElement positions when the timeline begins:

var targetElement = document.querySelectorAll("[data-acc-text='targetBox']")

var hammerElement = document.querySelectorAll("[data-acc-text='hammer01']")

gsap.set(targetElement, {x:500, y:200});
gsap.set(hammerElement, {x:500, y:800});

and then I call this when user hits up key:

var hammerElement = document.querySelectorAll("[data-acc-text='hammer01']")

var targetElement = document.querySelectorAll("[data-acc-text='targetBox']"), .25,{y:"-=200", onUpdate:checkHit});

function checkHit() {
if (Draggable.hitTest(hammerElement, targetElement)){
gsap.set(targetElement, {x:500, y:100});


The hammerElement moves as it should but the function isn't working.

Math Notermans

One thing you have to keep in mind for sure is, the way javascript selectors workin Storyline. querySelectorAll selects ALL elements with a given attribute. When i have some time i make a sample of it.

Another thing to keep in mind is, that it is hard to directly set a state with Javascript. You would need to set a variable...and add a Storyline trigger to change the state whenever that var changes.

Lee Mulvogue

Hi Math, I've been a heavy GSAP user in Flash / Animate CC for years and just found this, wondering if you've figured out a way to resolve target elements from variables?

eg. say I have 10 buttons and I want to drive the animations via a looped array, "normally" you could target these by root["button"+i], but this results in "target undefined not found"

Example code; when targeted directly it works (all are named correctly), but can't figure out how to dynamically generate the target names in JS in Storyline?  Guessing the root=this declaration isn't right in the Storyline environment, but I can't find any references.

var root = this;
var swatchX = 0;
var swatchY = 0;
var swatchFromX = 0;
var swatchFromY = 120;

var swatch0_mc = document.querySelectorAll("[data-acc-text='swatch0_mc']");
var swatch1_mc = document.querySelectorAll("[data-acc-text='swatch1_mc']");
var swatch2_mc = document.querySelectorAll("[data-acc-text='swatch2_mc']");
var swatch3_mc = document.querySelectorAll("[data-acc-text='swatch3_mc']");
var swatch4_mc = document.querySelectorAll("[data-acc-text='swatch4_mc']");

for (i=0; i<5; i++){
i < 4 ? swatchX = 5 + i*120 : swatchX = 5 + (i-4)*120;
i < 4 ? swatchY = 530 : swatchY = 465;
gsap.fromTo(root["swatch"+i+"_mc"], {duration: 0.3, x: swatchFromX, y: swatchFromY}, {x: 5, y: swatchY});
gsap.fromTo(root["swatch"+i+"_mc"], {duration: 0.3, x: 5}, {x: swatchX, delay: 0.3});
Math Notermans

With a sample i would have fixed this in less then a minute... Like this its guessing.. or rebuilding something alike...

A few things i do notice...
querySelectorAll : this gives ALL elements with the given attribute
maybe that should be querySelector ( i can't tell without seeing a real Storyline ) or you need to loop the result or access a single one from the Nodelist it returns.

The loop that animates the element(s) can be like this:

var accStr = "swatch"+i+"_mc";
 var element2Animate = document.querySelectorAll("[data-acc-text='"+accStr+"']");
gsap.fromTo(element2Animate, {duration: 0.3, x: swatchFromX, y: swatchFromY}, {x: 5, y: swatchY});

A few remarks.. you might use GSAPs timeline it has quite some extra's that make life easier. And its included in Storyline's version.

Also you can use vw and vh as relative values for position in Gsap in Storyline. That especially solves the x-position issues with the Classic and Modern player.

If you share a file i gladly check it...

Good luck... as a fellow long-time Gsap user...

Lee Mulvogue

Thanks Math, I've now gotten it to work with the above method, selecting the element dynamically in each iteration of the loop rather than attempting to dynamically reference pre-assigned element vars; see the attached for examples of working code and commented failing code.

Would still be good to figure out how to dynamically refence inside the gsap call, but not sure if that's possible in Storyline.  Looks like it's very hard, if not impossible, to reference/target elements and sub-elements; quite definitely can't replace Animate CC with Storyline!

Math Notermans

Well all is possible. One very particular thing to know is that the 'data-acc-text' attribute works similar to a classList. So using spaces in the data-acc-text attribute will make it work like a list with multiple classes. So i changed your elements to 'swatch 1' .. etc, etc. Although i loved Actionscript in Flash and worked for years with it i removed the _mc part... Reminded me a bit too much of the good old Flash days ;-) So i can now select all swatches with a single selector

var allSwatches = document.querySelectorAll("[data-acc-text*='swatch']");

or select any specific swatch at will....

document.querySelector("[data-acc-text='swatch 03']");

Now i can just loop all swatches at will.

var swatchStr = "swatch";
var allSwatches = document.querySelectorAll("[data-acc-text*='"+swatchStr+"']");
console.log("allSwatches length: "+allSwatches.length);
var swatchAtt = allSwatches[0].getAttribute('data-acc-text');
console.log("swatchAtt: "+swatchAtt);

for (i=0; i<allSwatches.length; i++){
i < 4 ? swatchX = allSwatches.length + i*120 : swatchX = allSwatches.length + (i-4)*120;
i < 4 ? swatchY = 530 : swatchY = 465;
gsap.fromTo(allSwatches[i], {duration: 0.3, x: swatchFromX, y: swatchFromY}, {x: 5, y: swatchY});
gsap.fromTo(allSwatches[i], {duration: 0.3, x: 5}, {x: swatchX, delay: 0.3});

Added it working.
Happy scripting :-)

Lee Mulvogue

Thanks for that Math.  What methodology did you use to find the structure, to track down the SVG to alter?

I'm trying to figure out how far we could push js control in Storyline, for example could trigger equivalents be dynamically added to objects, could functions dynamically read which object triggered a call, that kind of thing.  I currently have Animate CC but may well lose that in the future, but I'm guessing any semi-advanced coding will have to be developed outside and brought in as webobjects, trying to work inside Storyline will likely be too much of a headache.

Math Notermans

Basically i use the Code Inspector in Chrome to figure out the structure of elements and how to select them.

I do think all you mention can be achieved, and possibly without the need of Webobjects. As i do think at points its no fun to use them...but i do agree with you its difficult at times to get it right.

Another way i explore Storyline is by unminifying and changing the default javascript files residing in the Articulate folder. For example i added all GSAP plugins there so i have them always available...and a generic_functions.js in which i added functions i can call anywhere anytime.

Gladly coop in some way and team up to learn from eachother.
You can contact me directly at

Kind regards,

Stefan K.

Hi Math,

please forgive the "stupid questions", I'm a total beginner when it comes to javascript/GSAP.

  • GSAP only works with imported SVGs, right?
  • Is it possible to zoom in/out images using GSAP?
  • If I want to learn more about GSAP and how to use it in Storyline: What would you recommend? How should I proceed? What should I look at most? Javascript to begin with?

Many thanks in advance. :-)

Math Notermans

You can animate any page element with GSAP. Images, shapes, Storyline UI-elements...even create elements from scratch. Anything is possible. Yes, you can zoom in/out of image. scaleX, scaleY or scale will do that. To achieve a zoom-effect you need to keep the 'mask' of an object static... or scale down probably..

Check starting with my posts..

I would love to start a tutorial series to help anyone with GSAP in Storyline...not sure how to post and maintain that on the community though...

Daniel Berlin

Hi. Now that I made Storyline 3 stand at attention with GSAP yet another question has arisen for me. Sorry if it's annoying...

The command line:

var element2Animate = document.querySelector("[data-acc-text='star']");

for example, uses the text within an object to gain control of it (in the above case ,it's 'star'). But what can I do if I don't want to place any text within the actual object whatsoever? In the SL timeline I can change the 'name' of the object on the leftmost, white part of the timeline but the text that appears in the light blue part of the timeline can only be changed by actually typing text in the object (to the best of my understanding). Without adding any text within the object, is there a  way to access the object, I guess, is my question.

I hope my question is clear and not too annoying.



Math Notermans

Annoying questions dont exist. Any question is good. An answer or lack of that can be annoying ;-) Trying never to do that though. Actually just yesterday got a question about GSAP and Storyline ( esp. SL3 ) on the GSAP forum and planned answering that today. As i however do not have SL3, only Storyline360 ( Can you actually have both on your computer ? ) answering questions about SL3 is a bit of a guessing game for me. Thx to you Daniel, i just yesterday discovered there is quite some difference in SL3 and SL360, first of all the missing of the GSAP 3.5.1 libraries. So if you want to use that, you need to add them first.

Getting back to your question Daniel...
The name in the timeline window is not the 'acc-name'. That name is only intended for Storyline triggers. See the image below.


On the right of it, in the timeline itself you see the actual acc-name. In Storyline360 ( i am not sure if SL3 has that too ) you can right click an element , select 'Accessibility' and a window with the accessibility name pops up. As seen in the image below.


The size/pos button on the top gets you to the same window.

In that window you can change the acc-name and use it in your code. Make sure when changing it to press 'Enter' because that inputfield has the tendency to keep unchanged if you donot.

Offcourse you can use the default acc-name, but you need to be sure you have the correct one.


Daniel Berlin

Hi Math.

Thanks so much for your in-depth explanation. Yes, SL3 does have access to the accessibility name which can be changed in the pop-up, as you explained. Curiously, that doesn't update the accessibility name as it appears in the timeline, but that's a small detail.

The GSAP libraries are easily accessible in SL3 (and they work!) once I figured out (thanks to you) how to add them in, so no problem there.

I've learned so much thanks to you and your great explanations, so thanks again.