aplustardcrocodile
aplustardcrocodile

Reputation: 13

How can I run a function while audio is playing randomized in jquery?

(Please bear with me if it seems super-obvious, I'm an absolute beginner, and I'm stuck.)

I built this: https://github.com/aplustardcrocodile/aplustardcrocodile.github.io

The idea: every time you click on the face, and it plays a random sound from the array, and it also animates.

The problem: at the moment it does that but with 2 separate event listeners. Animates on mouseover/leave (I'm swapping files in query using classes) and it plays on click. Not ideal.

How can I fix it so that both things happen for the same event?

My only thought is to swap to the gif file for as long as the sound is playing, and once it's done it swaps back to png. Is that possible?

Thank yoooou.

Upvotes: 1

Views: 419

Answers (1)

Tommie
Tommie

Reputation: 783

Here is a version that binds all this to the click handler and also checks if/when the audio has stopped playing using onended and then resets the face to its orginial css-class (your png).

var audioFiles = [
	'https://cdn.rawgit.com/aplustardcrocodile/aplustardcrocodile.github.io/master/assets/sounds/01.m4a',
	'https://cdn.rawgit.com/aplustardcrocodile/aplustardcrocodile.github.io/master/assets/sounds/02.m4a',
	'https://cdn.rawgit.com/aplustardcrocodile/aplustardcrocodile.github.io/master/assets/sounds/03.m4a',
	'https://cdn.rawgit.com/aplustardcrocodile/aplustardcrocodile.github.io/master/assets/sounds/04.m4a',
	'https://cdn.rawgit.com/aplustardcrocodile/aplustardcrocodile.github.io/master/assets/sounds/05.m4a',
	'https://cdn.rawgit.com/aplustardcrocodile/aplustardcrocodile.github.io/master/assets/sounds/06.m4a',
	'https://cdn.rawgit.com/aplustardcrocodile/aplustardcrocodile.github.io/master/assets/sounds/07.m4a',
	'https://cdn.rawgit.com/aplustardcrocodile/aplustardcrocodile.github.io/master/assets/sounds/08.m4a',
];

var face = $('#face'),
	audio = $('#audio')[0],
	isPlaying = false;

face.on('click', function(){
	
	if( !isPlaying ){
		isPlaying = true;

		// toggle class to change image
		$(this).toggleClass('active');

		// get random from audioFiles
		var currentAudio = audioFiles[Math.floor(Math.random() * audioFiles.length)];

		// set new random audio as src
		audio.src = currentAudio;

		// ..then play it
		audio.currentTime = 0; // 0 always make sure its reset
		audio.play();
	}
})

// check when audio is complete
audio.onended = function(){

	// reset isPlaying
	isPlaying = false;
	
	// remove active-class from face
	face.removeClass('active');

};
body { padding: 1%; background: aliceblue; width: 472px; margin: 0 auto; position: relative; }
#face {
	background: url('https://aplustardcrocodile.github.io/assets/images/Face.png') no-repeat;
	width: 472px; height: 665px;
	cursor: pointer;
	transition: transform .5s ease;
}

#face:hover { opacity: .9; }


#face.active {
	opacity:1;
	background: url('https://aplustardcrocodile.github.io/assets/images/Face-loop.gif') no-repeat;
	transform: rotateZ(5deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<!-- face container -->
<div id="face"></div>

<!-- audio element -->
<audio id="audio"></audio>


See/edit on JSFiddle

https://jsfiddle.net/tommiehansen/svkeebgy/4/


Do note that there will be a lag for when you load the next sound if the user has not cached. A solution to that would be to simply preload all the audiofiles inline and then selecting one of these to play instead of using files in the js array. Other measures can be taken as well, but that is another question. :)

Upvotes: 1

Related Questions