Put cards in square grid and add scaling

pull/18/head
Frode Petterson 2017-01-23 14:12:33 +01:00
parent e60a425f2c
commit 7f800195e2
3 changed files with 119 additions and 39 deletions

30
card.js
View File

@ -17,21 +17,18 @@
var path = H5P.getPath(image.path, id);
var width, height, margin, $card;
var a = 96;
if (image.width !== undefined && image.height !== undefined) {
if (image.width > image.height) {
width = a;
height = image.height * (width / image.width);
margin = '' + ((a - height) / 2) + 'px 0 0 0';
width = '100%';
height = 'auto';
}
else {
height = a;
width = image.width * (height / image.height);
margin = '0 0 0 ' + ((a - width) / 2) + 'px';
height = '100%';
width = 'auto';
}
}
else {
width = height = a;
width = height = '100%';
}
/**
@ -81,18 +78,19 @@
*/
self.appendTo = function ($container) {
// TODO: Translate alt attr
$card = $('<li class="h5p-memory-card" role="button" tabindex="1">' +
$card = $('<li class="h5p-memory-wrap"><div class="h5p-memory-card" role="button" tabindex="1">' +
'<div class="h5p-front"></div>' +
'<div class="h5p-back">' +
'<img src="' + path + '" alt="Memory Card" width="' + width + '" height="' + height + '"' + (margin === undefined ? '' : ' style="margin:' + margin + '"') + '/>' +
'<img src="' + path + '" alt="Memory Card" style="width:' + width + ';height:' + height + '"/>' +
'</div>' +
'</li>')
'</div></li>')
.appendTo($container)
.children('.h5p-front')
.click(function () {
self.flip();
})
.end();
.children('.h5p-memory-card')
.children('.h5p-front')
.click(function () {
self.flip();
})
.end();
};
};

View File

@ -1,17 +1,21 @@
.h5p-memory-game {
overflow: hidden;
}
html .h5p-memory-game > ul {
list-style: none;
padding: 0;
margin: 0;
overflow: hidden;
.h5p-memory-game > ul {
list-style: none !important;
padding: 0.25em 0.5em !important;
/*padding: 0 !important;*/
margin: 0 !important;
overflow: hidden !important;
font-size: 16px;
box-sizing: border-box;
-moz-box-sizing: border-box;
}
.h5p-memory-game .h5p-memory-card,
.h5p-memory-game .h5p-memory-card .h5p-back,
.h5p-memory-game .h5p-memory-card .h5p-front {
width: 100px;
height: 100px;
width: 6.25em;
height: 6.25em;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
@ -19,17 +23,24 @@ html .h5p-memory-game > ul {
}
.h5p-memory-game img {
-webkit-user-drag: none;
display: inline-block !important;
margin: auto !important;
vertical-align: middle;
}
.h5p-memory-game .h5p-memory-wrap {
float: left;
text-align: center;
}
.h5p-memory-game .h5p-memory-card {
float: left;
display: inline-block;
outline: none;
position: relative;
margin: 1em;
margin: 0.75em 0.5em;
padding: 0;
background: transparent;
-webkit-perspective: 400px;
-moz-perspective: 400px;
perspective: 400px;
-webkit-perspective: 25em;
-moz-perspective: 25em;
perspective: 25em;
-webkit-transition: opacity 0.4s, filter 0.4s;
-moz-transition: opacity 0.4s, filter 0.4s;
transition: opacity 0.4s, filter 0.4s;
@ -61,17 +72,16 @@ html .h5p-memory-game > ul {
}
.h5p-memory-game .h5p-memory-card .h5p-front {
cursor: pointer;
text-align: center;
}
.h5p-memory-game .h5p-memory-card .h5p-front:hover {
background: #dfdfdf;
}
.h5p-memory-game .h5p-memory-card .h5p-front:before {
position: absolute;
content: "?";
font-size: 60px;
font-size: 3.75em;
color: #909090;
line-height: 100px;
left: 35px;
line-height: 1.67em;
}
.h5p-memory-game .h5p-memory-card .h5p-front:after {
content: "";
@ -88,6 +98,8 @@ html .h5p-memory-game > ul {
background-image: radial-gradient(ellipse closest-side, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0) 100%);
}
.h5p-memory-game .h5p-memory-card .h5p-back {
line-height: 5.9em;
text-align: center;
background: #f0f0f0;
-webkit-transform: rotateY(-180deg);
-moz-transform: rotateY(-180deg);
@ -163,9 +175,9 @@ html .h5p-memory-game > ul {
left: 50%;
margin-left: -10em;
box-shadow: 0 0 1em #666;
-webkit-transform: translateZ(24px);
-moz-transform: translateZ(24px);
transform: translateZ(24px);
-webkit-transform: translateZ(1.5em);
-moz-transform: translateZ(1.5em);
transform: translateZ(1.5em);
}
.h5p-memory-game .h5p-memory-image {
float: left;
@ -175,6 +187,9 @@ html .h5p-memory-game > ul {
-moz-box-sizing: border-box;
border-radius: 4px;
background: #f0f0f0;
width: 100px;
height: 100px;
width: 6.25em;
height: 6.25em;
}
.h5p-memory-game .h5p-row-break {
clear: left;
}

View File

@ -1,5 +1,11 @@
H5P.MemoryGame = (function (EventDispatcher, $) {
// We don't want to go smaller than 100px per card(including the required margin)
var CARD_MIN_SIZE = 100; // PX
var CARD_STD_SIZE = 116; // PX
var STD_FONT_SIZE = 16; // PX
var LIST_PADDING = 1; // EMs
/**
* Memory Game Constructor
*
@ -13,7 +19,7 @@ H5P.MemoryGame = (function (EventDispatcher, $) {
// Initialize event inheritance
EventDispatcher.call(self);
var flipped, timer, counter, popup, $feedback;
var flipped, timer, counter, popup, $feedback, $wrapper, maxWidth, numCols;
var cards = [];
var removed = 0;
@ -132,7 +138,7 @@ H5P.MemoryGame = (function (EventDispatcher, $) {
self.attach = function ($container) {
this.triggerXAPI('attempted');
// TODO: Only create on first attach!
$container.addClass('h5p-memory-game').html('');
$wrapper = $container.addClass('h5p-memory-game').html('');
// Add cards to list
var $list = $('<ul/>');
@ -172,6 +178,67 @@ H5P.MemoryGame = (function (EventDispatcher, $) {
});
}
};
/**
* Will try to scale the game so that it fits within its container.
* Puts the cards into a grid layout to make it as square as possible  
* which improves the playability on multiple devices.
*
* @private
*/
function scaleGameSize() {
// Check how much space we have available
var $list = $wrapper.children('ul');
var newMaxWidth = parseFloat(window.getComputedStyle($list[0]).width);
if (maxWidth === newMaxWidth) {
return; // Same size, no need to recalculate
}
else {
maxWidth = newMaxWidth;
}
// Get the card holders
var $elements = $list.children();
if ($elements.length < 4) {
return; // No need to proceed
}
// Determine the optimal number of columns
var newNumCols = Math.ceil(Math.sqrt($elements.length));
// Do not exceed the max number of columns
var maxCols = Math.floor(maxWidth / CARD_MIN_SIZE);
if (newNumCols > maxCols) {
newNumCols = maxCols;
}
if (numCols !== newNumCols) {
// We need to change layout
numCols = newNumCols;
// Calculate new column size in percentage and round it down (we don't
// want things sticking out…)
var colSize = Math.floor((100 / numCols) * 10000) / 10000;
$elements.css('width', colSize + '%').each(function (i, e) {
if (i === numCols) {
$(e).addClass('h5p-row-break');
}
});
}
// Calculate how much one percentage of the standard/default size is
var onePercentage = ((CARD_STD_SIZE * numCols) + STD_FONT_SIZE) / 100;
var paddingSize = (STD_FONT_SIZE * LIST_PADDING) / onePercentage;
var cardSize = (100 - paddingSize) / numCols;
var fontSize = (((maxWidth * (cardSize / 100)) * STD_FONT_SIZE) / CARD_STD_SIZE);
// We use font size to evenly scale all parts of the cards.
$list.css('font-size', fontSize + 'px');
// due to rounding errors in browsers the margins may vary a bit…
}
self.on('resize', scaleGameSize);
}
// Extends the event dispatcher