Now the mosaic can be assembled in any sequence, but it is necessary to consistently, that is, first to the first mosaic the second, to the second third, to the third fourth, otherwise it will not work, I can not understand how

"use strict"; // массив элСмСнтов IMG. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для получСния ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ var imgs = [] imgs.push(document.getElementById("r1")); imgs.push(document.getElementById("r2")); imgs.push(document.getElementById("r3")); imgs.push(document.getElementById("r4")); // массив, хранящий ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ располоТСния элСмСнтов ΠΌΠΎΠ·Π°ΠΈΠΊΠΈ var expectedPositions = [ [0, 0], [0, 160], [90, 0], [90, 160] ]; // "сосСдниС" элСмСнты для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ элСмСнта ΠΌΠΎΠ·Π°ΠΈΠΊΠΈ var neighbors = { 0: [1, 2], 1: [0, 3], 2: [0, 3], 3: [1, 2] } // событиС, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π΅Π΅ ΠΏΡ€ΠΈ ΠΊΠ»ΠΈΠΊΠ΅ ΠΌΡ‹ΡˆΡŒΡŽ. Начало пСрСмСщСния изобраТСния document.onmousedown = function(e) { if (!e.target.classList.contains('draggable')) { return false; } // Π² Π½Π°Ρ‡Π°Π»Π΅ пСрСмСщСния сохраняСм ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ курсора ΠΎΡ‚Π½ΠΎΡΡ‚ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌΠΎΠΉ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ ΠΈ саму ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ (Π²Π½ΡƒΡ‚Ρ€ΠΈ события event) var event = e; var offsetX = e.offsetX; var offsetY = e.offsetY; // функция, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°ΡŽΡ‰Π°Ρ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ ΠΏΡ€ΠΈ событии пСрСмСщСния (onmousemove) function moveAt(e) { event.target.style.left = e.pageX - offsetX + 'px'; event.target.style.top = e.pageY - offsetY + 'px'; } // функция, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰Π°Ρ, ΠΊΠ°ΠΊ Π΄Π΅Π»Π΅ΠΊΠΎ находится пСрСмСщаСмая ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ° ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅ Π½Π° ΡΠΎΠ±Ρ€Π°Π½Π½ΠΎΡΡ‚ΡŒ ΠΌΠΎΠ·Π°ΠΈΠΊΠΈ ΠΈ для "прилипания" ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ Π΄Ρ€ΡƒΠ³ ΠΊ Π΄Ρ€ΡƒΠ³Ρƒ function getCoordDifferenceFromExpected(imgIdx1, imgIdx2) { var img1 = {} var img2 = {} var realDiff = {} var expectedDiff = {} img1.X = parseInt(imgs[imgIdx1].style.left); img1.Y = parseInt(imgs[imgIdx1].style.top); img2.X = parseInt(imgs[imgIdx2].style.left); img2.Y = parseInt(imgs[imgIdx2].style.top); realDiff.X = img1.X - img2.X; realDiff.Y = img1.Y - img2.Y; expectedDiff.X = expectedPositions[imgIdx1][0] - expectedPositions[imgIdx2][0] expectedDiff.Y = expectedPositions[imgIdx1][1] - expectedPositions[imgIdx2][1] var result = { "diff": Math.abs((expectedDiff.X - realDiff.X)) + Math.abs((expectedDiff.Y - realDiff.Y)), "expectedDiff": expectedDiff, "img1": img1, "img2": img2 } return result; } // ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ ΠΏΠΎ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Π°ΠΌ function moveAtCoordinates(x, y) { event.target.style.left = x + 'px'; event.target.style.top = y + 'px'; } // функция, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰Π°Ρ "ΠΏΡ€ΠΈΠ»ΠΈΠΏΠ°Π½ΠΈΠ΅" ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ Π² случаС, ΠΊΠΎΠ³Π΄Π° ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½Π° достаточно Π±Π»ΠΈΠ·ΠΊΠΎ ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ полоТСнию // для этого ΡΡ€Π°Π²Π½ΠΈΠ²Π°ΡŽΡ‚ΡΡ позиция ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌΠΎΠΉ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π΄Π²ΡƒΡ… "сосСдних" ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ // вызываСтся ΠΏΡ€ΠΈ отпускании ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΌΡ‹ΡˆΠΈ послС пСрСтаскивания function correctPosition() { var id = event.target.id; var alpha = 25; var imgIndex = parseInt(id.replace("r", "")) - 1; var posDiff; for (var i = 0; i < neighbors[imgIndex].length; i++) { posDiff = getCoordDifferenceFromExpected(imgIndex, neighbors[imgIndex][i]) if (Math.abs(posDiff.diff) < alpha) { moveAtCoordinates(posDiff.img2.X + posDiff.expectedDiff.X, posDiff.img2.Y + posDiff.expectedDiff.Y); break; } } } // функция, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‰Π°Ρ ΠΌΠΎΠ·Π°ΠΈΠΊΡƒ Π½Π° ΡΠΎΠ±Ρ€Π°Π½Π½ΠΎΡΡ‚ΡŒ // вызываСтся ΠΏΡ€ΠΈ отпускании ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΌΡ‹ΡˆΠΈ послС пСрСтаскивания function checkMosaic() { var posDiff; var mosaicAssembled = true; for (var i = 0; i < neighbors[0].length; i++) { posDiff = getCoordDifferenceFromExpected(0, neighbors[0][i]) if (Math.abs(posDiff.diff) != 0) { mosaicAssembled = false; break; } } for (var i = 0; i < neighbors[3].length; i++) { posDiff = getCoordDifferenceFromExpected(3, neighbors[3][i]) if (Math.abs(posDiff.diff) != 0) { mosaicAssembled = false; break; } } if (mosaicAssembled) { setTimeout(alert, 300, "Π’Ρ‹ собрали ΠΌΠΎΠ·Π°ΠΈΠΊΡƒ!"); } } // ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌΠΎΠΉ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ "Π½Π°Π²Π΅Ρ€Ρ…", Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° Π½Π΅ ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Π²Π°Π»Π°ΡΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ°ΠΌΠΈ; Π½Π°Ρ‡Π°Π»ΠΎ двиТСния e.target.style.zIndex = 1000; moveAt(e); // события пСрСмСщСния document.onmousemove = function(e) { moveAt(e); } // событиС отпускания клавиши ΠΌΡ‹ΡˆΠΈ (Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ пСрСтаскивания ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ) document.onmouseup = function(e) { document.onmousemove = null; correctPosition(); checkMosaic(); document.onmouseup = null; } } // Π·Π°ΠΌΠ΅Π½Π° стандатной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° ΠΏΡ€ΠΈ пСрСтаскивании ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ document.ondragstart = function() { return false; }; 
 body { background-color: #CCE6FF; } 
 <h1 style="text-align: center">Π‘ΠΎΠ±Π΅Ρ€ΠΈ ΠΌΠΎΠ·Π°ΠΈΠΊΡƒ!</h1> <p>ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Ρ ΠΊΠ°Ρ€Ρ‚ΠΈΠΊΠΈ ΠΌΡ‹ΡˆΠΊΠΎΠΉ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ рисунок</p> <img src="images/r1.gif" id="r1" class="draggable" style="position: absolute; top: 120px; left: 25px;"> <img src="images/r2.gif" id="r2" class="draggable" style="position: absolute; top: 120px; left: 130px;"> <img src="images/r4.gif" id="r4" class="draggable" style="position: absolute; top: 300px; left: 25px;"> <img src="images/r3.gif" id="r3" class="draggable" style="position: absolute; top: 300px; left: 130px;"> 

  • it would be easier if they did it in jsfiddle.net - Lev Shportak

0