Forum Discussion

Mysk's avatar
Mysk
Community Member
10 days ago

Stop audio when javascript typewriting effect stops

Hi

I have this typewriting effect that writes out a text inside a variable but also writes out the name the user have written.

The text functions works great. 
I do have a typewriter soundclip that I would like to stop when all text is written but I am struggeling.

Any help would be great.

This is the javascript

// Get the Storyline player object
var player = GetPlayer();

// Get the value of the Storyline variable that holds the message text
var message = player.GetVar("V_Spl_Intensiv_Velkomsttext");

// 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 = "Hello, " + 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_Spl_Intensiv_Velkomsttext", " ");

// Small delay before starting the typewriter effect
setTimeout(function() {
    player.SetVar("V_Spl_Intensiv_Velkomsttext", ""); // 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_Spl_Intensiv_Velkomsttext");
        currentText += personalizedMessage.charAt(i);
        player.SetVar("V_Spl_Intensiv_Velkomsttext", currentText);
        i++;
        setTimeout(typeWriter, typingSpeed);
    } else {
        // Stop the audio when all text is written
        player.StopAudio("audio2");  // Ensure this name matches the audio's timeline name
    }
}

  • Mysk's avatar
    Mysk
    Community Member

    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_Hilliard's avatar
      Nathan_Hilliard
      Community 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.asp 

      You 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.

      • Mysk's avatar
        Mysk
        Community 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);
            }
        }

  • I would have gone with Nathan's suggest with a single click that played when variable changed, which would stop when the typewriter effect stopped.