Using background-position
is a very well-known way to divide some image into small pieces. From that technique you can totally solve your problem step by step. I've tried this code to demonstrate the techinque as well as solve your problem.
HTML:
<div class='canvas'></div>
CSS:
.canvas {
background:url('http://placekitten.com/500/300');
width:500px;
height:300px;
}
.cell {
float:left;
position:relative;
cursor:pointer;
}
.cell > .front {
-webkit-backface-visibility: hidden;
backface-visibility:hidden;
-webkit-transform-style:preserve-3d;
transition:all 1s;
}
.cell:not(.flipped) > .back {
-webkit-transform:rotateY(180deg);
}
.cell.flipped > .front {
-webkit-transform:rotateY(180deg);
}
.back {
background:pink;
}
.cell > .back {
position:absolute;
text-align:center;
font-size:30px;
color:red;
left:0;
top:0;
transition:all 1s;
}
.cell > .back:before {
content:'';
display:inline-block;
height:100%;
vertical-align:middle;
}
.cell > * {
border: 1px solid orange;
box-sizing:border-box;
width:100%;
height:100%;
}
JS:
//get the canvas
var canvas = $('div.canvas');
var backgroundImage = canvas.css('background-image');
//remove the background from canvas
canvas.css('background-image','none');
//number of columns and rows
var col = 8;
var row = 4;
var colWidth = canvas.width() / col;
var rowHeight = canvas.height() / row;
//loop through the cells
for(var i = 0; i < row; i++){
for(var j = 0; j < col; j++){
//append new cell to canvas
var cell = $("<div class='cell flipped'><div class='back'>?</div><div class='front'></div></div>")
.width(colWidth).height(rowHeight).appendTo(canvas);
//set the background for the cell
//note that calculate the em unit for more flexible
//font-size
cell.find('.front')
.css('background',backgroundImage)
.css('background-position', -(j * colWidth) + 'px ' + -(i * rowHeight) + 'px');
//register click handler for the cell
cell.click(function(){$(this).toggleClass('flipped')});
}
}
NOTE: Please test the demo in webkit-based browsers, I've just added prefix for webkit-based browsers (for the backface-visibility
, transform
, ...). Also note that this code is not complete, it just helps you get started to fulfil your actual requirement.
A little explanation on the CSS, in fact you need 2 faces on a cell, the .front
and .back
face, the .front
to render the image and the .back
to render the text (after cell flipped). At flipped state, the .front
should be rotated 180deg
around the Y
axis (the vertical axis), however its backface-visibility
should be set to hidden
. In contradiction, .back
should be rotated 180deg
around the Y axis in normal state.
UPDATED: Some browsers have not supported backface-visibility
feature (such as Maxthon), so you have another beautiful workaround by using z-index
instead. In flipped state, the .back
should have higher z-index
(such as 1
) to cover the .front
, while in normal state, it should have a zero z-index
so that it's hidden behind the .front
. Here is the Updated Demo working on browsers which don't support backface-visibility
)