Skip to main content
SSSSSSBenay
Known Participant
March 15, 2019
Answered

Correctly adding simple sound effects to Animate HTML5 Canvas timeline

  • March 15, 2019
  • 5 replies
  • 8410 views

Hello,

I am making the transition from Flash and AS3 to HTML5 Canvas. My work is to create interactive children's lessons which involved a main timeline of 6 frames with navigation buttons allowing the user to cycle through the 6 frames. On each of the 6 frames are numerous simple animations and interactive elements such as buttons, drag and drop with targets, etc. Throughout the program I use very short sound effects which are played when certain frames are reached within my animations, or when a button is clicked, etc. Currently, I am importing the .mp3s to my library, giving them a Linkage name in the library (i.e. "SELsound1"), and then using this code on the appropriate frame or in the appropriate function to play the sound effect:

createjs.Sound.play("SELsound1", false, 0, 0, 0, 1);

This appears to be working just fine, however I am worried that it is not the correct way to go about adding simple sound effects. I have read on the SoundJS library website about registering each sound before playing it? As a beginner to Javascript and the createjs libraries, I am confused about the registering part. The code above that I am using works just fine. Usually, if a bit of code works, I just go with it...however since I am making the transition to HTML5 Canvas and will create many of these programs, I want to make sure I am doing things correctly from the start.

Thanks in advance...

This topic has been closed for replies.
Correct answer kdmemory

Well, it might be allright to put sounds into the timeline, but me too, I never did or do that. Probably this goes back a long time, it all started with a certain method called puppetSound . I just got used to deal with sounds and soundFXs through code. Having sounds or soundFXs in the timeline means lousy control of those.

And as SSSSSSBenay writes "I use very short sound effects which are played when certain frames are reached within my animations, or when a button is clicked, etc.", or when a button is clicked! I mean, seriously, nobody should suggest here to go to a certain frame in the timeline, only to play a soundFX on a click on a button. I don't believe it.

So i think Benay's wish to learn SoundJS in order to be more versatile with sound effects in his work, is a good plan. And sometimes one has to go an extra mile to learn the craft well. Even if there were simpler ways for the lazy.

I admit I'm too still learning to manage SoundJS to such an extend that I feel perfectly at home. But I paste here my latest experiment and hope it might help to get into SoundJS. The packaged file including sounds is here https://adobe.ly/2Y7tdw3.

var here = this;

here.stop();

/* make a listing of all sounds used with sub-folder (assetPath) and file names and id to reference later */

var assetPath = "sounds/";

var sounds = [{

    src: "airport.mp3",

    id: "id_air"

}, {

    src: "samisen.mp3",

    id: "id_sam"

}, {

    src: "whoosh.mp3",

    id: "id_who"

}];

/* I use the next two variables to detect later if all sounds are loaded */

var soundsCount = 0;

var soundsLength = sounds.length;

var btns = ["t_air", "t_sam", "t_who", "t_next"];

/* The fileload event is fired for each loaded sound */

createjs.Sound.on("fileload", handleLoad);

/* Register an array of audio files for loading and future playback in Sound */

createjs.Sound.registerSounds(sounds, assetPath);

function handleLoad(e) {

    soundsCount++;

    if (soundsCount == soundsLength) {

        /* all sounds are loaded */

        here.airport = createjs.Sound.createInstance("id_air");

        here.samisen = createjs.Sound.createInstance("id_sam");

        here.whoosh = createjs.Sound.createInstance("id_who");

        /* set all sound buttons to visible */

        here.toggleBtnsVisi();

    }

}

this.on("click", clickHandler, here, false);

function clickHandler(e) {

    var etn = e.target.name;

    if (etn == "t_air") {

        here.airport.play({

            volume: 0.33

        });

        e.target.visible = false;

        /* Listen to when sound play has finished */

        here.airport.on("complete", handleSoundCompletes, null, true)

    }

    if (etn == "t_sam") {

        here.samisen.play();

        e.target.visible = false;

        here.samisen.on("complete", handleSoundCompletes, null, true);

    }

    if (etn == "t_who") {

        here.whoosh.play({

            loop: 1

        });

        e.target.visible = false;

        here.whoosh.on("complete", handleSoundCompletes, null, true);

    }

    if (etn == "t_next") {

        here.gotoAndStop(9);

    }

    if (etn == "t_prev") {

        here.gotoAndStop(0);

    }

}

function handleSoundCompletes(e) {

    if (e.target.src.indexOf("airport") != -1) {

        here.t_air.visible = true;

    }

    if (e.target.src.indexOf("samisen") != -1) {

        here.t_sam.visible = true;

    }

    if (e.target.src.indexOf("whoosh") != -1) {

        here.t_who.visible = true;

    }

}

here.toggleBtnsVisi = function () {

    for (var i = 0; i < btns.length; i++) {

        if (!here.start) {

            here[btns].visible = false;

            here.start = true;

        } else {

            here[btns].visible = true;

        }

    }

};

stage.on("drawstart", here.toggleBtnsVisi, here, true);

This code is valid in all frames of this timeline. One can jump between frame 0 or frame 9 and the sound references and completeHandler work throughout.

Klaus

5 replies

SSSSSSBenay
Known Participant
March 18, 2019

Thank you EVERYONE for all the helpful advice!

kdmemory
kdmemoryCorrect answer
Inspiring
March 18, 2019

Well, it might be allright to put sounds into the timeline, but me too, I never did or do that. Probably this goes back a long time, it all started with a certain method called puppetSound . I just got used to deal with sounds and soundFXs through code. Having sounds or soundFXs in the timeline means lousy control of those.

And as SSSSSSBenay writes "I use very short sound effects which are played when certain frames are reached within my animations, or when a button is clicked, etc.", or when a button is clicked! I mean, seriously, nobody should suggest here to go to a certain frame in the timeline, only to play a soundFX on a click on a button. I don't believe it.

So i think Benay's wish to learn SoundJS in order to be more versatile with sound effects in his work, is a good plan. And sometimes one has to go an extra mile to learn the craft well. Even if there were simpler ways for the lazy.

I admit I'm too still learning to manage SoundJS to such an extend that I feel perfectly at home. But I paste here my latest experiment and hope it might help to get into SoundJS. The packaged file including sounds is here https://adobe.ly/2Y7tdw3.

var here = this;

here.stop();

/* make a listing of all sounds used with sub-folder (assetPath) and file names and id to reference later */

var assetPath = "sounds/";

var sounds = [{

    src: "airport.mp3",

    id: "id_air"

}, {

    src: "samisen.mp3",

    id: "id_sam"

}, {

    src: "whoosh.mp3",

    id: "id_who"

}];

/* I use the next two variables to detect later if all sounds are loaded */

var soundsCount = 0;

var soundsLength = sounds.length;

var btns = ["t_air", "t_sam", "t_who", "t_next"];

/* The fileload event is fired for each loaded sound */

createjs.Sound.on("fileload", handleLoad);

/* Register an array of audio files for loading and future playback in Sound */

createjs.Sound.registerSounds(sounds, assetPath);

function handleLoad(e) {

    soundsCount++;

    if (soundsCount == soundsLength) {

        /* all sounds are loaded */

        here.airport = createjs.Sound.createInstance("id_air");

        here.samisen = createjs.Sound.createInstance("id_sam");

        here.whoosh = createjs.Sound.createInstance("id_who");

        /* set all sound buttons to visible */

        here.toggleBtnsVisi();

    }

}

this.on("click", clickHandler, here, false);

function clickHandler(e) {

    var etn = e.target.name;

    if (etn == "t_air") {

        here.airport.play({

            volume: 0.33

        });

        e.target.visible = false;

        /* Listen to when sound play has finished */

        here.airport.on("complete", handleSoundCompletes, null, true)

    }

    if (etn == "t_sam") {

        here.samisen.play();

        e.target.visible = false;

        here.samisen.on("complete", handleSoundCompletes, null, true);

    }

    if (etn == "t_who") {

        here.whoosh.play({

            loop: 1

        });

        e.target.visible = false;

        here.whoosh.on("complete", handleSoundCompletes, null, true);

    }

    if (etn == "t_next") {

        here.gotoAndStop(9);

    }

    if (etn == "t_prev") {

        here.gotoAndStop(0);

    }

}

function handleSoundCompletes(e) {

    if (e.target.src.indexOf("airport") != -1) {

        here.t_air.visible = true;

    }

    if (e.target.src.indexOf("samisen") != -1) {

        here.t_sam.visible = true;

    }

    if (e.target.src.indexOf("whoosh") != -1) {

        here.t_who.visible = true;

    }

}

here.toggleBtnsVisi = function () {

    for (var i = 0; i < btns.length; i++) {

        if (!here.start) {

            here[btns].visible = false;

            here.start = true;

        } else {

            here[btns].visible = true;

        }

    }

};

stage.on("drawstart", here.toggleBtnsVisi, here, true);

This code is valid in all frames of this timeline. One can jump between frame 0 or frame 9 and the sound references and completeHandler work throughout.

Klaus

Legend
March 15, 2019

It sounds like just putting your sounds directly on the timeline would work for you. Why aren't you doing that?

avid_body16B8
Legend
March 15, 2019

That might be his best bet unless he wants to code for a specific reason.

avid_body16B8
Legend
March 15, 2019

So here is another way:

in Script register the sounds.

createjs.Sound.on("fileload", handleLoad);

createjs.Sound.registerSound("music.mp3", "music");

createjs.Sound.registerSound("sound1.mp3", "sound1");

createjs.Sound.registerSound("sound2.mp3", "sound2");

createjs.Sound.registerSound("sound3.mp3", "sound3");

and then play sounds like this:

toggle the music

if(!this.mySound){

    this.mySound = playSound("music", Infinity);

}else{

    this.mySound.play();

}

or play another sound somewhere else

this.mysound = playSound("sound1");

avid_body16B8
Legend
March 15, 2019

This is what I use and if you needed to manipulate things you could also add a variable.

For example for a sound toggle I do this bellow but of course there are different ways to do things. I know people who do it differently.

this.music = createjs.Sound.play("music", "none", 0, 0, -1, 0.4);   // -1 is to loop and 0.4 is the volume

this.musicBtn.addEventListener("click", musicToggle.bind(this));

var on = 0;

function musicToggle() {

    if (on == 0) {

        this.musicBtn.musicOff.visible = true;

        this.music.paused = true;

        on = 1;

    } else {

        this.musicBtn.musicOff.visible = false;

        this.music.paused = false;

        on = 0;

    }

}