Forum Discussion
Stop audio when javascript typewriting effect stops
I found out a solution.
By using a variable that stops the sound when changed to true I could use javascript to change the variable instead.
- Nathan_Hilliard8 months agoCommunity Member
The variable change trigger approach is the simplest.
Beyond that, despite what your sample code suggests, there is no StopAudio() function available in standard Storyline. Also, audio clips cannot be referenced directly by name.
Audio objects can be controlled via JavaScript as described here:
https://www.w3schools.com/jsref/dom_obj_audio.aspYou can create an array of all the audio clips on your slide using something like:
const audio = document.querySelectorAll("audio");
You can then use audio[0].play() or audio[0].pause() to play or pause the first available clip.
All of the audio clips are inserted into the slide without any easily accessible identifiers. The src attribute is likely derived from the sort-of-hashed original filename, the frequency, and the bit rate. In theory, you could derive the src string yourself and use it to match to one of the available clips in the audio array. The details for this are complicated and described in another post.
- Mysk8 months agoCommunity Member
I changed the script and it do work. But it workes randomly.
I thought it was the variable tru/false that was the problem but I added a text variable so I can se that it is changing. Also added a line to reset the variable.
What am I missing here?
The script is running first the a trigger in stroyline stop the sound if the variable Stoptypewriter changes to true.
I thought maybee the trigger that checed the variable needed to be before the script but I cant rearange the triggers.
____
// Get the Storyline player object
var player = GetPlayer();
// Reset Stoptypewriter to ensure it can be triggered again
player.SetVar("Stoptypewriter", false);
// Get the value of the Storyline variable that holds the message text
var message = player.GetVar("V_SPLVelkommen");
// Get the player's name entered in the Text Entry box (PlayerName)
var playerName = player.GetVar("PlayerName");
// Insert the player's name into the message (you can customize this message)
var personalizedMessage = "Hei, " + playerName + "! " + message;
// Set the typing speed in milliseconds and initial index
var typingSpeed = 50;
var i = 0;
// Clear the initial text immediately before Storyline renders it
player.SetVar("V_SPLVelkommen", " ");
// Small delay before starting the typewriter effect
setTimeout(function() {
player.SetVar("V_SPLVelkommen", ""); // Ensure text starts from blank
typeWriter();
}, 100); // 100ms delay to prevent initial flicker
// Create the typing effect
function typeWriter() {
if (i < personalizedMessage.length) {
var currentText = player.GetVar("V_SPLVelkommen");
currentText += personalizedMessage.charAt(i);
player.SetVar("V_SPLVelkommen", currentText);
i++;
setTimeout(typeWriter, typingSpeed);
} else {
// When finished, update the Stoptypewriter variable in Storyline
player.SetVar("Stoptypewriter", true);
}
}- Nathan_Hilliard8 months agoCommunity Member
While controlling the audio from SL with a variable trigger is easier, audio from JS is also possible. However, once you start manipulating audio through JavaScript, you may not be able to control it properly through SL triggers anymore. Best to use one or the other, not both.
For a JS only approach, try adding this at the begining of your script:
// Get the Storyline player object var player = GetPlayer(); //Add these lines to target the audio, reset to begining, and play when typing script starts const audio = document.querySelectorAll("audio")[0]; audio.currentTime = 0; audio.play();
then, add this to the end of your script:
} else { // When finished, update the Stoptypewriter variable in Storyline player.SetVar("Stoptypewriter", true); //Add this line to stop the audio when the typing is finished audio.pause(); } }
Note: This will only work if the user has interacted your slides first (e.g., button, text box, other slides, etc.) JavaScript can't play audio directly before some kind of interaction has occured.