Initial audio version
parent
af920a3d2d
commit
191326cf10
86
card.js
86
card.js
|
@ -12,18 +12,20 @@
|
||||||
* @param {string} [description]
|
* @param {string} [description]
|
||||||
* @param {Object} [styles]
|
* @param {Object} [styles]
|
||||||
*/
|
*/
|
||||||
MemoryGame.Card = function (image, id, alt, l10n, description, styles) {
|
MemoryGame.Card = function (image, id, alt, l10n, description, styles, audio) {
|
||||||
/** @alias H5P.MemoryGame.Card# */
|
/** @alias H5P.MemoryGame.Card# */
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// Initialize event inheritance
|
// Initialize event inheritance
|
||||||
EventDispatcher.call(self);
|
EventDispatcher.call(self);
|
||||||
|
|
||||||
var path = H5P.getPath(image.path, id);
|
var path, width, height, $card, $wrapper, removedState, flippedState, audioPlayer;
|
||||||
var width, height, $card, $wrapper, removedState, flippedState;
|
|
||||||
|
|
||||||
alt = alt || 'Missing description'; // Default for old games
|
alt = alt || 'Missing description'; // Default for old games
|
||||||
|
|
||||||
|
if (image && image.path) {
|
||||||
|
path = H5P.getPath(image.path, id);
|
||||||
|
|
||||||
if (image.width !== undefined && image.height !== undefined) {
|
if (image.width !== undefined && image.height !== undefined) {
|
||||||
if (image.width > image.height) {
|
if (image.width > image.height) {
|
||||||
width = '100%';
|
width = '100%';
|
||||||
|
@ -37,6 +39,45 @@
|
||||||
else {
|
else {
|
||||||
width = height = '100%';
|
width = height = '100%';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audio) {
|
||||||
|
// Check if browser supports audio.
|
||||||
|
audioPlayer = document.createElement('audio');
|
||||||
|
if (audioPlayer.canPlayType !== undefined) {
|
||||||
|
// Add supported source files.
|
||||||
|
for (var i = 0; i < audio.length; i++) {
|
||||||
|
if (audioPlayer.canPlayType(audio[i].mime)) {
|
||||||
|
var source = document.createElement('source');
|
||||||
|
source.src = H5P.getPath(audio[i].path, id);
|
||||||
|
source.type = audio[i].mime;
|
||||||
|
audioPlayer.appendChild(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!audioPlayer.children.length) {
|
||||||
|
audioPlayer = null; // Not supported
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
audioPlayer.controls = false;
|
||||||
|
audioPlayer.preload = 'auto';
|
||||||
|
|
||||||
|
var handlePlaying = function () {
|
||||||
|
if ($card) {
|
||||||
|
$card.addClass('h5p-memory-audio-playing');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var handleStopping = function () {
|
||||||
|
if ($card) {
|
||||||
|
$card.removeClass('h5p-memory-audio-playing');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
audioPlayer.addEventListener('play', handlePlaying);
|
||||||
|
audioPlayer.addEventListener('ended', handleStopping);
|
||||||
|
audioPlayer.addEventListener('pause', handleStopping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the cards label to make it accessible to users with a readspeaker
|
* Update the cards label to make it accessible to users with a readspeaker
|
||||||
|
@ -74,6 +115,10 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (audioPlayer) {
|
||||||
|
audioPlayer.play();
|
||||||
|
}
|
||||||
|
|
||||||
$card.addClass('h5p-flipped');
|
$card.addClass('h5p-flipped');
|
||||||
self.trigger('flip');
|
self.trigger('flip');
|
||||||
flippedState = true;
|
flippedState = true;
|
||||||
|
@ -83,6 +128,11 @@
|
||||||
* Flip card back.
|
* Flip card back.
|
||||||
*/
|
*/
|
||||||
self.flipBack = function () {
|
self.flipBack = function () {
|
||||||
|
if (audioPlayer) {
|
||||||
|
audioPlayer.pause();
|
||||||
|
audioPlayer.currentTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
self.updateLabel(null, null, true); // Reset card label
|
self.updateLabel(null, null, true); // Reset card label
|
||||||
$card.removeClass('h5p-flipped');
|
$card.removeClass('h5p-flipped');
|
||||||
flippedState = false;
|
flippedState = false;
|
||||||
|
@ -100,6 +150,11 @@
|
||||||
* Reset card to natural state
|
* Reset card to natural state
|
||||||
*/
|
*/
|
||||||
self.reset = function () {
|
self.reset = function () {
|
||||||
|
if (audioPlayer) {
|
||||||
|
audioPlayer.pause();
|
||||||
|
audioPlayer.currentTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
self.updateLabel(null, null, true); // Reset card label
|
self.updateLabel(null, null, true); // Reset card label
|
||||||
flippedState = false;
|
flippedState = false;
|
||||||
removedState = false;
|
removedState = false;
|
||||||
|
@ -133,7 +188,7 @@
|
||||||
$wrapper = $('<li class="h5p-memory-wrap" tabindex="-1" role="button"><div class="h5p-memory-card">' +
|
$wrapper = $('<li class="h5p-memory-wrap" tabindex="-1" role="button"><div class="h5p-memory-card">' +
|
||||||
'<div class="h5p-front"' + (styles && styles.front ? styles.front : '') + '>' + (styles && styles.backImage ? '' : '<span></span>') + '</div>' +
|
'<div class="h5p-front"' + (styles && styles.front ? styles.front : '') + '>' + (styles && styles.backImage ? '' : '<span></span>') + '</div>' +
|
||||||
'<div class="h5p-back"' + (styles && styles.back ? styles.back : '') + '>' +
|
'<div class="h5p-back"' + (styles && styles.back ? styles.back : '') + '>' +
|
||||||
'<img src="' + path + '" alt="' + alt + '" style="width:' + width + ';height:' + height + '"/>' +
|
(path ? '<img src="' + path + '" alt="' + alt + '" style="width:' + width + ';height:' + height + '"/>' + (audioPlayer ? '<div class="h5p-memory-audio-button"></div>' : '') : '<i class="h5p-memory-audio-instead-of-image">') +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div></li>')
|
'</div></li>')
|
||||||
.appendTo($container)
|
.appendTo($container)
|
||||||
|
@ -176,6 +231,19 @@
|
||||||
self.flip();
|
self.flip();
|
||||||
})
|
})
|
||||||
.end();
|
.end();
|
||||||
|
|
||||||
|
if (audioPlayer) {
|
||||||
|
$card.children('.h5p-back')
|
||||||
|
.click(function () {
|
||||||
|
if ($card.hasClass('h5p-memory-audio-playing')) {
|
||||||
|
audioPlayer.pause();
|
||||||
|
audioPlayer.currentTime = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
audioPlayer.play();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -236,8 +304,9 @@
|
||||||
*/
|
*/
|
||||||
MemoryGame.Card.isValid = function (params) {
|
MemoryGame.Card.isValid = function (params) {
|
||||||
return (params !== undefined &&
|
return (params !== undefined &&
|
||||||
params.image !== undefined &&
|
(params.image !== undefined &&
|
||||||
params.image.path !== undefined);
|
params.image.path !== undefined) ||
|
||||||
|
params.audio);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -249,8 +318,9 @@
|
||||||
*/
|
*/
|
||||||
MemoryGame.Card.hasTwoImages = function (params) {
|
MemoryGame.Card.hasTwoImages = function (params) {
|
||||||
return (params !== undefined &&
|
return (params !== undefined &&
|
||||||
params.match !== undefined &&
|
(params.match !== undefined &&
|
||||||
params.match.path !== undefined);
|
params.match.path !== undefined) ||
|
||||||
|
params.matchAudio);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
"title": "Memory Game",
|
"title": "Memory Game",
|
||||||
"description": "See how many cards you can remember!",
|
"description": "See how many cards you can remember!",
|
||||||
"majorVersion": 1,
|
"majorVersion": 1,
|
||||||
"minorVersion": 2,
|
"minorVersion": 3,
|
||||||
"patchVersion": 12,
|
"patchVersion": 0,
|
||||||
"runnable": 1,
|
"runnable": 1,
|
||||||
"author": "Joubel",
|
"author": "Joubel",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
@ -318,3 +318,28 @@
|
||||||
.h5p-memory-game .h5p-programatically-focusable {
|
.h5p-memory-game .h5p-programatically-focusable {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
.h5p-memory-audio-instead-of-image {
|
||||||
|
font-family: 'H5PFontAwesome4';
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-style: normal;
|
||||||
|
color: #404040;
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
.h5p-memory-audio-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
font-family: 'H5PFontAwesome4';
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.h5p-memory-audio-instead-of-image:before,
|
||||||
|
.h5p-memory-audio-button:before {
|
||||||
|
content: "\f026";
|
||||||
|
}
|
||||||
|
.h5p-memory-audio-playing .h5p-memory-audio-instead-of-image:before,
|
||||||
|
.h5p-memory-audio-playing .h5p-memory-audio-button:before {
|
||||||
|
content: "\f028";
|
||||||
|
}
|
||||||
|
|
|
@ -384,16 +384,16 @@ H5P.MemoryGame = (function (EventDispatcher, $) {
|
||||||
var cardParams = cardsToUse[i];
|
var cardParams = cardsToUse[i];
|
||||||
if (MemoryGame.Card.isValid(cardParams)) {
|
if (MemoryGame.Card.isValid(cardParams)) {
|
||||||
// Create first card
|
// Create first card
|
||||||
var cardTwo, cardOne = new MemoryGame.Card(cardParams.image, id, cardParams.imageAlt, parameters.l10n, cardParams.description, cardStyles);
|
var cardTwo, cardOne = new MemoryGame.Card(cardParams.image, id, cardParams.imageAlt, parameters.l10n, cardParams.description, cardStyles, cardParams.audio);
|
||||||
|
|
||||||
if (MemoryGame.Card.hasTwoImages(cardParams)) {
|
if (MemoryGame.Card.hasTwoImages(cardParams)) {
|
||||||
// Use matching image for card two
|
// Use matching image for card two
|
||||||
cardTwo = new MemoryGame.Card(cardParams.match, id, cardParams.matchAlt, parameters.l10n, cardParams.description, cardStyles);
|
cardTwo = new MemoryGame.Card(cardParams.match, id, cardParams.matchAlt, parameters.l10n, cardParams.description, cardStyles, cardParams.matchAudio);
|
||||||
cardOne.hasTwoImages = cardTwo.hasTwoImages = true;
|
cardOne.hasTwoImages = cardTwo.hasTwoImages = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Add two cards with the same image
|
// Add two cards with the same image
|
||||||
cardTwo = new MemoryGame.Card(cardParams.image, id, cardParams.imageAlt, parameters.l10n, cardParams.description, cardStyles);
|
cardTwo = new MemoryGame.Card(cardParams.image, id, cardParams.imageAlt, parameters.l10n, cardParams.description, cardStyles, cardParams.audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add cards to card list for shuffeling
|
// Add cards to card list for shuffeling
|
||||||
|
|
|
@ -33,6 +33,15 @@
|
||||||
"importance": "high",
|
"importance": "high",
|
||||||
"description": "Describe what can be seen in the photo. The text is read by text-to-speech tools needed by visually impaired users."
|
"description": "Describe what can be seen in the photo. The text is read by text-to-speech tools needed by visually impaired users."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"state": "new",
|
||||||
|
"name": "audio",
|
||||||
|
"type": "audio",
|
||||||
|
"importance": "high",
|
||||||
|
"label": "Audio Track",
|
||||||
|
"description": "An optional sound that plays when the card is turned.",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "match",
|
"name": "match",
|
||||||
"type": "image",
|
"type": "image",
|
||||||
|
@ -50,6 +59,15 @@
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "Describe what can be seen in the photo. The text is read by text-to-speech tools needed by visually impaired users."
|
"description": "Describe what can be seen in the photo. The text is read by text-to-speech tools needed by visually impaired users."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"state": "new",
|
||||||
|
"name": "matchAudio",
|
||||||
|
"type": "audio",
|
||||||
|
"importance": "low",
|
||||||
|
"label": "Matching Audio Track",
|
||||||
|
"description": "An optional sound that plays when the second card is turned.",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "description",
|
"name": "description",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
|
Loading…
Reference in New Issue