Put cards in square grid and add scaling
parent
e60a425f2c
commit
7f800195e2
30
card.js
30
card.js
|
@ -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();
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue