How can a non-programmer create captivating effects in Storyline using JavaScript?
Natalia Vostretsova ??
Freelance | Contract | Instructional Designer (ID) | Learning Experience Designer (LXD) | E-learning Developer | Educational Technology (EdTech) | UX/UI Designer
Good morning, class! This is a continuation of my series where I explore JavaScript and share my findings with you in the form of practical notes. Together, we’re figuring out:
Since more of you are joining in, let me repeat what I usually say. If this is your first time here and all you know about programming is that it’s for programmers, remember:
?? Instructional designers don’t have to know how to code! Learning JavaScript is totally optional for you. But if you’re combining instructional design with course development and want to go beyond Storyline’s built-in features to create something unique and truly yours, trust me—coding is absolutely within your reach.
You can do it!
That’s enough motivation—let’s get to work. To make sense of this article, you should first read the three previous ones. And not just read—practice as you go!
?? Previous articles:
?? Today, we’ll be revisiting what we’ve learned so far and learn a couple more things:
? I’ll show you how to control the starting point of an animation.
? We’ll talk about data arrays—a must-know for creating effects beyond simple button animations.
? We’ll get familiar with the super useful .forEach(); method.
? And with one small trick, we’ll solve one minor issue with code size and one huge issue with object positioning when resizing the browser window.
By the end of this lesson, you’ll walk away with this animated interactive template:
Intrigued? Let’s go!
Sketching the Mechanism
Take a look at the example above. At first glance, is it immediately clear what it consists of? How each element works?
I’m guessing the answer might be something like: “Uhh… a few circles… they appear and disappear?”
Not the best starting point for writing code. Programming is all about precision and clarity—no adjectives needed.
??That’s why I strongly recommend (and will keep recommending in the future): save yourself time and frustration—sketch out your idea first.
Your sketch should include:
Think of it as “drawing” a blueprint for your code. Keep it in front of you—it’s your visual guide for coding.
Here’s what my version looks like today:
If you’ve read the previous article—and I really hope you have—then right now you should be thinking: “Aha! I know how to write the code for this thing!”
For those of you who do—feel free to scroll ahead to the bug-fixing section. Because—spoiler alert—if you follow the steps you already know, you’ll end up with a mechanism that almost works as intended.
For everyone who needs a step-by-step breakdown—I totally get it.
But! You have to make an effort to write the code yourself. Or with the help of AI. But the key point here is: do it yourself! Understanding the code and knowing how to tweak it is half the battle. If you’re not actually writing or at least attempting it, studying won’t get you very far.
Alright, where does a sketch start? With the elements, of course. So, let’s begin.
1?? Defining Variables
Why variables first? Because JavaScript works with variables.
And what are variables? They’re boxes that store data about objects on the slide.
To assign objects to variables, you need to either find their ID attributes or set an Alternative Text.
?? Just a reminder: experienced JavaScript users in Storyline strongly recommend using ID attributes. But if you’re lazy—or just want a more visual way to explain your code (like me here)—you can use Alternative Text instead.
The choice is yours. Just remember the primary role of Alternative Text and don’t put random stuff in there.
Now, let’s open Storyline and create the objects. For clarity, I’ve made a screenshot with all the objects lined up.
?? Key things to note: First—always… no, scratch that—ALWAYS name your objects on the timeline with clear, meaningful names that relate to the objects on the slide.
In my case:
?? Just to be clear—this screenshot is for visual reference only. Of course, in the final version, all objects should be perfectly centered on the slide, stacked one on top of the other.
Next, we assign an Alternative Text to each object. Let me show you an example using the black circle:
The other objects will have the following Alternative Text values:
?? Here's something new. In this example, I have a group of four text fragments. But how do we assign them to a variable? How do we introduce this group to JavaScript?
The same way as individual circles—by using an Alternative Text! Yes, groups can have Alternative Text too! To do this:
Prep work is done—time to write some code! You'll be working in JavaScript window, here:
And I'll be in Notion—it's just more convenient for writing the article.
You should end up with five variables for the circles and one for the text group:
A couple of important details to keep in mind in this code snippet:
Done!
2?? Moving on to Animation
We're using animations from the GSAP library. In its simplest form, it looks something like this (example):
And yeah, you can do it this way for today's example (why this method works but isn’t optimal—we covered last time).
Since we’re animating five circles and one text group, we’ll, of course, animate them as part of an animation sequence. To do that, we first need to create the animation sequence (which we store in a variable).
?? Don’t forget to pause it right away!
If you’re wondering, “But why?”—shame on you! Go read the previous article.
Then, inside the sequence, we add animations for all the slide objects in order and set their delays. Here’s my version:
I’ve added a comment in the code explaining what’s happening in this animation. But I hope you already understand what parameters like scale, opacity, ease, and so on are used for.
There are two new things here: comment formatting and the .fromTo(); method.
The new comment format /* comment */ is used when you have a really long comment that doesn’t fit in a single visible line.
If the comment is short, just one line, then it stays the same as before: //comment.
And for the text group, there’s a new method—not just .to, but .fromTo.
?? Pay close attention! This method has a different syntax, something we haven’t used before:
The difference is that we’re not just defining how the object should change—we’re also specifying the starting state, which is different from what we see on the Storyline's slide.
Sounds a bit tricky? Let’s break it down:
That’s the whole trick!
3?? Setting Up Events
Now, let’s talk about the triggers that will start and rewind the whole thing. To do that, we need to remember how the .addEventListener method works, along with the special methods for handling animation sequences: .play(); and .reverse();. (We discussed in detail what it is and how these guys work in previous articles.)
Last time, I used a not-so-elegant solution, and I was really frustrated with its imperfections, but I couldn't come up with a better one. It drove me crazy!
For today's article, it's important to recall this solution and stick with it for now:
What this code does:
At this point, your code should look something like this:
领英推荐
Essentially, we've just transformed our sketch into a set of code lines. Everything is clear and structured, even though we're now speaking JavaScript instead of using visual or human language.
Take a moment to celebrate—and hit play on the slide.
Drum roll!
WTF! Sorry… ??
Why, JavaScript?! Why?!! ??
Don't get too discouraged. It's annoying, but the reality is that problems like this are part of the process.
It’s time for the fourth stage, which wasn’t in the sketch: debugging!
Let’s figure out why the code isn’t working as expected and fix it.
?? Debugging and Fixing the Code
Let’s take a quick detour. Just like we started with a sketch in the beginning, debugging also requires us to clearly understand the problem first before taking action.
Remember, programming isn’t about adjectives—it’s about data. Everything is precise and structured. So, pause for a moment and try to analyze the issue just by looking at the previous example. Can you describe what went wrong?
.
.
.
The issue lies in how JavaScript interprets the coordinates for object movement. Looking at top and bottom elements:
For right/left elements, the same issue happens, but with the x coordinate instead.
So, JavaScript doesn’t consider the actual placement of objects on the slide as their default (x, y) coordinates. Instead, it assumes they start at (0,0).
To move objects from the exact position where they were originally placed, we need to:
At this point, giving up on JavaScript seems like the most reasonable decision in life. But hold on! There’s a solution: xPercent / yPercent.
?? xPercent and yPercent are relative positioning units that move an element by a percentage of its own width or height. The transformations are relative to the center of the element, which is exactly what we need!
Formula:
After experimenting, I found that shifting by 45% of the circles’ size works perfectly.
So, let’s replace x/y with xPercent/yPercent:
Time to test it out! Fingers crossed—let’s see if it works.
Yeehaw!
Celebrate for a moment… and then move on to the next issue—object overlap. It’s not very informative, and honestly, it just doesn’t look great.
How do we fix it?
The solution depends on your creativity, but I see two main options.
1?? Keep the Code, Change Objects
To do this, we need to remove the colored fill.
?? If you make the objects fully transparent (100% opacity), JavaScript will stop recognizing them (!). It will treat the circles as if they don’t exist wherever there’s no fill. Basically, it will "see through" them. And if JavaScript can see through an object, it means it detects the slide itself instead. If that happens, the "mouseleave" event gets triggered. Ups!
I learned this the hard way—painful, frustrating experience. Imagine: the code was working perfectly, and then suddenly… boom, it stopped.
Funny thing is, when working with object colors, you have to define a whole separate variable for the color. But if an object has a fill and you set its opacity to 100%, JavaScript just goes: nope, nothing here!—and poof! The inside of the object ceases to exist.
So, I went with a white fill, played around with the opacity, and settled on 99%. The result? A sleek, minimalist black-and-white version. Looks pretty cool!
I did a little research and turns out… I'm the only one who likes the black-and-white minimalist version. Conclusion? The solution works technically, but not aesthetically.
Which means—time to move on to the second approach.
2?? Tweaking the Code
Actually, tweaking isn't the right word here. Everything works, so we’re not fixing anything—we’re just adding a new piece.
Just like when we worked with the sketch or analyzed the coordinate issue, this is the moment to pause and think. How can you even approach a solution if your JavaScript knowledge is only surface-level?
Let me walk you through my thought process. You don’t need to be a JavaScript expert to think logically—shoutout to brain for that!
So, thanks to working with graphic design tools like Adobe Illustrator and Procreate, I know about blending modes like multiply, overlay, darken, etc. These are ways objects mix colors when layered on top of each other—super useful in certain cases.
Knowing that, I asked AI if there was a way to use blending modes in JavaScript. I got a ton of results, tested different options, and went from 10 lines of code… down to just one.
Here’s what it looks like:
Add this line to your code right after defining the variables, and go test it out!
Meanwhile, let me break down what this line actually does and how it works. Let's take a look at what the example consists of:
The task is to make the color properties of each circle such that when they overlap, their colors mix in a specific way. This means we need to change a certain property (mixBlendMode) for each object. To access this property, we need to first tell JavaScript where to look for it (style).
You can write a line of code for each object to update the blend mode, like this:
You can indeed optimize and combine the variables into an array, then use the .forEach() method to change the property for all the elements at once.
Here’s how this can work:
?? In JavaScript, an array is like a box where you can store several values and refer to them by their order.
I believe this blending technique holds a huge creative potential. You can experiment with different options. Here's a list of blend modes and their effects:
This approach can allow you to experiment and add a creative touch to your design. Have fun playing with it!
Test the mechanics again—does everything work correctly?
How about this?
When testing the code without resizing the browser window, everything works perfectly. But as soon as you resize the browser during testing, everything falls apart.
The code works correctly, but the coordinates of the moving objects don't update when the slide is resized.
I spent a long time searching for a solution on my own and with advice from experienced colleagues. I found several solutions, but they were either unfeasible or only worked correctly in certain cases.
The final solution came by accident, as a result of solving another problem. Specifically, because, as I mentioned a couple of times already, I didn't like the solution involving the duplication of .addEventListener();.
So, follow me:
And in this case, two goals are achieved at once:
?? The solution to the scaling issue is temporary. We're waiting for the promised update from Articulate, where this problem will be fixed.
Oookay, we’re done for today! Phew!
Summary
Today, we reviewed the key points of creating animations with GSAP and sequences, and discussed several new concepts:
Good luck with your projects, and see you next time, N.
Training Manager
5 天前Can I ask what is the typical time to create a 2 hour delivery elearn ?
Freelance eLearning Developer and Instructional Designer ?? Specializing in Articulate Storyline 360, Camtasia, game-based learning, and 3D modeling
2 周I couldn't agree more. Earlier today I was working on a personal project where I wanted to shuffle a series of variables. In the past I would have done this with a series of triggers and slides. Now I use a few lines of code. It makes some things in Storyline so much easier.
Instructional Designer ? eLearning Developer ? Learning Experience Designer and Facilitator ? Transforming training into impactful and engaging experiences
2 周Javascript is still a bit intimidating for me but I can see it has such great potential to boost the Storyline projects. Thank you for sharing your experience!
Learning and Development Consultant
3 周Love this
Learning and Design Expert // eLearning
3 周Please continue this series Natalia Vostretsova ?? ! And thank you for what you bring to the ID community. I feel seen being able to blend my love for tech with ID. You are my one of my virtual ID mentors whether you realize it or not!