Борис К,
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
td {
width: 150px;
height: 150px;
background-size: cover;
background-image: var(--url);
}
.game.end{
border-collapse: collapse;
border-spacing: 0px;
}
#rotate{
transform: rotate(var(--angle, 0deg));
transition: transform 1s;
}
</style>
</head>
<body>
<br /><br />
<table class="game">
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
<br /><br /><br />
<img id="rotate" src="https://via.placeholder.com/150x150.png" />
<script>
function imagedata_to_image(imagedata) {
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
canvas.width = imagedata.width;
canvas.height = imagedata.height;
ctx.putImageData(imagedata, 0, 0);
return canvas.toDataURL();
}
function shuffle(array) {
let i = array.length;
while (i--) {
let j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
const x = 150;
const y = 150;
const w = 2;
const images = [
"https://loremflickr.com/150/150/girl?random=1",
"https://loremflickr.com/150/150/dog?random=2",
"https://loremflickr.com/150/150/cat?random=3",
"https://loremflickr.com/150/150/boy?random=4"
];
const h = Math.ceil(images.length / w);
const canvas = Object.assign(document.createElement('canvas'), {
width: w * x,
height: h * y
});
const ctx = canvas.getContext('2d'),
arrSrc = [],
tb = document.querySelector('.game'),
cells = Array.from(tb.querySelectorAll('td'));
let win, temp = [];
function endGame()
{
tb.classList.add('end');
}
let angle = 0;
function exch(event) {
if (win) return;
let td = event.target.closest('.game td');
if (td) {
let cellIndex = td.cellIndex;
let rowIndex = td.closest("tr").rowIndex;
if (temp.length) {
let x = Math.abs(cellIndex - temp[1]);
let y = Math.abs(rowIndex - temp[2]);
if ((x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0]) {
let url = td.style.getPropertyValue('--url');
td.style.setProperty('--url', temp[0].style.getPropertyValue('--url'));
temp[0].style.setProperty('--url', url);
td !== temp[0] && rotate.style.setProperty('--angle', `${angle += 90}deg`);
temp = [];
}
} else {
temp = [td, cellIndex, rowIndex];
}
}
}
tb.addEventListener("click", exch);
const createImg = () => Promise.all(
shuffle(images).map((src, i) => new Promise(
(onload, onerror) => Object.assign(new Image(), {
crossOrigin: 'anonymous',
src,
onerror,
onload
})
).then(({
target
}) => {
const hPos = Math.floor(i / w);
const wPos = i - (hPos * w);
ctx.drawImage(
target,
wPos * x,
hPos * y,
x,
y
)
}))
).then(() => {
const wh = w * x / tb.rows.length;
arrSrc.length = 0;
win = false;
temp = [];
tb.classList.remove('end');
for (let i = 0; i < tb.rows.length; i++) {
for (let j = 0; j < tb.rows[i].cells.length; j++) {
let imagedata = ctx.getImageData(wh * j, wh * i, wh, wh);
let url = imagedata_to_image(imagedata);
arrSrc.push(`url(${url})`);
}
}
shuffle(arrSrc.slice(0)).forEach((url, i) => cells[i].style.setProperty('--url', url))
});
createImg()
</script>
</body>
</html>