Storyline Secrets: The JavaScript Trick for Pixel-Perfect Animation

Animating Objects with Precision in Articulate Storyline: A JavaScript-Based Approach

Are you looking to add some engaging interactivity to your Articulate Storyline projects? Want to control the movement of objects with more finesse than simple pixel-based positioning? If so, this tutorial is for you. We’ll explore how to leverage JavaScript, specifically the GreenSock Animation Platform (GSAP), to move objects around your Storyline stage based on percentages rather than fixed pixel values. This gives you incredible control over the layout and responsiveness of your animations.

This came about because last year I tried to use GSAP for a project and I wanted the character selection slide to have a graphic to highlight the character but to move around based on which character you selected, but I didn’t want the selection to be all done by 9 or so animated motion paths inside Storyline. There had to be a better way.

Why Percentages Matter

Adopting a percentage-based approach revolutionizes how you design interactive elements in Articulate Storyline. Your animations gracefully adapt to any screen size, ensuring a polished user experience across devices. Modify your layout effortlessly without tedious pixel recalculations. Enjoy cleaner, more intuitive code that’s a breeze to update and maintain.

Step-by-Step Guide

Let’s break down how to get this done.

  1. The Stage Setup:
  • Create your main object (e.g., a ball) on the Storyline slide.
  • Add two arrow buttons (left and right) to trigger animations.
  • Add a rectangle with the same size as the Storyline stage.
  1. JavaScript and GSAP (Section 1: References):
// Get references to the stage, the ball, and the arrow buttons
var rectWidthParent, theBall, leftArrowButton, rightArrowButton;

First, create a rectangle the width of the stage, it can just be the background. Import a ball, and create left and right arrows. Use the accessibility tab by selecting the rectangle and right clicking it and select Accessibility… From there use the alternate name and put in rectWidthParent, theBall, leftArrow, rightArrow for each of our objects. These references are needed to manipulate and animate these elements.

function getReferences() {
rectWidthParent = document.querySelector('[data-acc-text="rectWidthParent"]');
theBall = document.querySelector("[data-acc-text='ball']");
leftArrowButton = document.querySelector('[data-acc-text="leftArrow"]');
rightArrowButton = document.querySelector('[data-acc-text="rightArrow"]');
}

Now we need to be able to determine where we are on the field. Last year when I attempted the character selection slide I was using pixels, but if someone resized the screen it would mess up the calculation. So this year I figured how to use the background rectangle to figure out the percentage needed. For the left offset I don’t really need to worry about anything since objects x and y coordinates is done by the top and left side. Zero is zero for the most left side. On the right I need to know the size of the ball graphic so I can do calculations. Hence xOffsetR = stageWidth – objectWidth;. Now if I wanted to know the exact middle for whatever reason, that is  (stageWidth) – (objectWidth / 2);.

// Variables to store the calculated offsets
var xOffsetL = 0;
var xOffsetR = 0;

// Calculate offsets based on percentages
function calculateOffsets() {
getReferences();
if (rectWidthParent) {
var stageWidth = rectWidthParent.offsetWidth;
var objectWidth = theBall.offsetWidth;
xOffsetL = 0;
xOffsetR = stageWidth - objectWidth;
}
}
calculateOffsets();
window.addEventListener('resize', calculateOffsets);

Finally lets animate this ball left and right using Greensock (GSAP). Duration is measured in seconds. Ease is how you want it to bounce. I suggest going to GSAP documentation on easing to learn more about easing property. Repeat is how often this animation repeats, we don’t want it to, so none. Rotation is either + or – 360 or how much you want the ball to rotate. x is the location you want the ball to animate to. Those properties were calculated in our previous code, but you could put in a number here if desired.

function animateLeft() {
calculateOffsets();
gsap.to(theBall, {
duration: 2,
ease: "bounce.out",
repeat: 0,
rotation: "-=360", 
x: xOffsetL,
});
}

function animateRight() {
calculateOffsets();
gsap.to(theBall, {
duration: 2,
ease: "bounce.out",
repeat: 0,
rotation: "+=360",
x: xOffsetR,
});
}

leftArrowButton.addEventListener('click', animateLeft);
rightArrowButton.addEventListener('click', animateRight);

So there you have it. You now have a ball that animates back and forth on the board. But its not really about soccer or football, you can use the rectangle width hack to other gamify ideas, or UI ideas like character selection and give your eLearning course a little flavor.

See video below.