GSAP timeline to speedup / slowdown any animations on it

Jan 30, 2022

As i mentioned before in some posts GSAP has a timeline that controls all animation. And probably Storyline uses that timeline for its animation too. As i didnot find a way to control Storyline's timeline i made a sample showing how perfectly and easily GSAP's timelines control the speed of animations.

https://360.articulate.com/review/content/bc85877a-e885-42c1-b216-bb771ca0e007/review

Im gonna add some more elements to it soon to test whether audio and video speed are controllable this way too.

~Math

34 Replies
Math Notermans

When you plan your project with GSAP, and ensure all is build with GSAP instead of using default Storyline transitions and animations.... you can use GSAPs timeline functions and global timescale functionality to speed up or slow down the complete setup. The newest version of GSAP 3.11.1 has a new function called gsap.context() that makes it even easier to maintain and control behaviour of all your gsap animations.

As now all this still isnot possible with the default Storyline timeline and animations...i suspect they use GSAP internally for it, but i tried controlling it and that doesnot work. Mentioned this to Articulate though and hope they implement it in the near future.

Another great new feature in the latest gsap version is gsap.matchMedia()

This feature gives you the option to adapt animations based on screensize and resizing. Whether and how this works in Storyline360 ( Storyline being not responsize ) i have to test.

Mayra Alheli Rios

Thank you very much Math,
I have a conflict with the background audio help, since also within my functionalities I added to be able to speed up the voiceover audio (https://community.articulate.com/discussions/articulate-storyline/can-you-speed-up-the-player-in-articulate-360?page=3), however, when I do this, it also speeds up my background audio.
Can you help me to find the solution in the java so that it does not take the background audio speed.

https://community.articulate.com/discussions/articulate-storyline/continuous-playing-background-music-over-all-slides-in-storyline360

My code:

speed up audio

var allAudios = document.getElementsByTagName("audio");
for (var i = 0; i < allAudios.length; i++) {
   allAudios[i].playbackRate = 1.25;
}

slow down audio

var allAudios = document.getElementsByTagName("audio");
for (var i = 0; i < allAudios.length; i++) {
   allAudios[i].playbackRate = 0.5;
}

Audio background

//load the scripts dynamically into the head of the document

function add_line() {
    var line = document.createElement("audio");
    var head=document.getElementsByTagName('body')[0];
    line.type = "audio/mp3";
    line.src="";
    line.id="bgSong" ;
    line.autoplay = true;
    line.loop = true;
    head.appendChild(line);
}

//but we only want to add these once!
if(document.getElementById('bgSong')==null){
    add_line();
var audio = document.getElementById('bgSong');
audio.volume = 0.5;
}

play audio background

var audio = document.getElementById('bgSong');
audio.src="story_content/external_files/MusicaDiversidad.mp3";
audio.load();
audio.play();

I hope you can help me

Thanks

 

Mayra Alheli Rios

Hi Math,

Hope you find the solution in the java so that it does not take the background audio speed, also I would like the speed respect in the other slides, because I keep continuing the slides I need to set up the velocity in each one.

I wish I had knowledge of java, but this time it's beyond my knowledge.

Thanks for the support!

Math Notermans

What you did wrong is looping all the audios in the Storyline and changing their playback speed.

A for loop basically acts on all elements it finds. To fix that you need to only act on your embedded audio. How to do that ? Well several solutions...for one you can check the name of the audio...if that is the one you want changed....act.

for (var i = 0; i < allAudios.length; i++) {
       allAudios[i].playbackRate = 0.25;
}

Like this...it changes th playbackRate of all your audios...

for (var i = 0; i < allAudios.length; i++) {
    if(mp3Name !="MusicaDiversidad.mp3"){
       allAudios[i].playbackRate = 0.25;
    }
}

And like this it changes all audios except your background music.
To get this working we still need to know the names of our mp3s. Especially because Storyline generates a custom name for embedded audio.

Like this when checking for allAudios[i].url:
.../story_content/external_files/MusicaDiversidad.mp3
.../story_content/5UxkXXG1RPh_44100_48_0.mp3

Also you notice the folder structure for embedded and external audio is different.

So splitting the url in an array and getting the last value of that array gives us the proper names.
Then this works.

for (var i = 0; i < allAudios.length; i++) {
    var mp3URL = allAudios[i].src;
    var tmpArr = mp3URL.split("/");
    mp3Name = tmpArr[tmpArr.length-1];
    audioNamesArray.push(mp3Name);
    console.log(mp3Name+" pushed into ["+audioNamesArray+"]");
    if(mp3Name !="MusicaDiversidad.mp3"){
       allAudios[i].playbackRate = 0.25;
    }
}

Kind regards,

Math

Mayra Alheli Rios

Woooooow that's great news...
Thank you very much Math, you don't know how grateful I am.
It is that I was taking several post codes on the subject and so I did not know how to configure it correctly, what course I need to take to learn java.


One more question, is there any way to add in the code that respects the speed of playback from one slide to another, because every time I advance to the next slide the user would have to click on speed +/-, and we need it because this configuration is for people with disabilities and should be as few clicks as possible .

Math Notermans

In easy to follow steps...

Create a custom variable. In this case 'audioSpeed', a numeric variable


s1

Its default value will be 1. Then we go to the Javascript ( PS. it is Javascript, Java is something completely different ;-)

In this case we cannot add all of the script simply to the Maximo and Minimo buttons as you want the audio to be speed up or down on next pages when a user set it earlier. So we need 2 changes...one on the buttons that saves the chosen speed to the variable 'audioSpeed' and one on the start of every slide that sets the speed of the audio. Let us first change the buttons Maximo and Minimo.

This is the code needed on Minimo.
// player is your StorylinePlayer and GetPlayer() is a command to connect to it.
var player = GetPlayer();

// the audiospeed we want
var audioSpeed = 0.25;

// Now we can set the Storyline variable
player.SetVar("audioSpeed",audioSpeed);

And offcourse in your loop like this.
allAudios[i].playbackRate = audioSpeed;

On Maximo its the same except for the different speed.

Change this, and test it :-)

If you have that working as planned, the next step is getting it working on start of every next slide. You could add it to a Masterslide and have it happen on every slide that uses that Masterslide, but for now im showing it just on start of the existing slides.

s2

We start with adding a Javascript trigger that gets executed When the timeline starts.

The code we need now is this.
var allAudios = document.getElementsByTagName("audio");
var audioNamesArray = [];
var mp3Name;

// player is your StorylinePlayer and GetPlayer() is a command to connect to it.
var player = GetPlayer();

// Now we can get the Storyline variable
var audioSpeed = player.GetVar("audioSpeed");


for (var i = 0; i < allAudios.length; i++) {
    var mp3URL = allAudios[i].src;
    var tmpArr = mp3URL.split("/");
    mp3Name = tmpArr[tmpArr.length-1];
    audioNamesArray.push(mp3Name);
    console.log(mp3Name+" pushed into ["+audioNamesArray+"]");
    if(mp3Name !="MusicaDiversidad.mp3"){
       allAudios[i].playbackRate = audioSpeed;
    }

}

Notice GetVar to get a Storyline variable into Javascript.

 

Thats it.

Mayra Alheli Rios

HI MATH;
I'm having problems with the content, but it's weird because when I view the story.html on my computer the button speed works, but when I upload it on an lms it doesn't work.
I leave you here my file and the link of it in the lms to know what I am doing wrong.

Link:

https://app.cloud.scorm.com/sc/InvitationConfirmEmail?publicInvitationId=20ac6d0f-e01c-4187-bfe7-033242c98617

Math Notermans

I know this happened before... Mark Ramsey figured out why i do believe.... something to do with selector in Storyline not correct when published on the LMS. In this post i believe...
https://community.articulate.com/discussions/articulate-storyline/variable-playback-speed On page 4 it states why...getting to the audio file by using getElementsByTagName returns zero indexes on a LMS.

A direct selector to the proper folder the audio is in should work. As this always depends on the LMS you use...i see if i can find a solution.

PS. The invitation to Scorm Cloud is not valid anymore.

I do think that getting the 'getElementsByTagName' so the part where all audio used in the Storyline is gathered... out of the MasterSlide and into the main HTML of the published output might work.

Jürgen Schoenemeyer

i have tested a .story file with some audios - and there is an interesting result

if I start the published files with file:// protokoll, all audios are append at the end of the story.html

BUT, if I start the same files with https:// from my webserver (no lms server), no <audio> elements are appended - so the js query cannot find any audio

it seems articulate uses a pure javascript solution - without dom - to play audio from webserver

i will invest some more hours to learn the exact method how storyline playing audios from webserver

Jürgen Schoenemeyer

new results: if web audio is available, no <audio> elements are added to the DOM


to check: i have disabled "web audio" in firefox

result:

now enable "web audio"

so it's clear -> web audio is used (without DOM)

https://caniuse.com/?search=web%20audio

https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API

 

 

Jürgen Schoenemeyer


one idea - you would have to prevent storyline from switching to web audio

for this you have to patch "html5/lib/scripts/bootstrapper.min.js"

replace
    return window.AudioContext||window.webkitAudioContext||null
with
   return /*window.AudioContext||window.webkitAudioContext||*/null

=> the player gets always the info "no web audio" available, use "normal audio"

important: save your patch js library - which is exacly for one storyline version - and copy the file after every publish

result on a https:// webserver

if you want the patched file for all your courses you could overwrite the library file in the programm folder  - so a manual overwrite after every publish should no longer be necessary
(just not tested !)