Мозайка JavaScript

128
21 июня 2019, 05:40

Сейчас мозаику можно собрать в любой последовательности, но надо чтобы последовательно, то есть сначала к первой мозаике вторую, ко второй третью, к третьей четвертую, иначе не будет работать, не могу понять как реализовать

"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;">

READ ALSO
Работа с фреймом

Работа с фреймом

Есть фрейм с вычислением площадиНикак не могу понять как сделать, чтобы при совершении вычислений, менялся фон фрейма

132
Как сделать такую форму для секции?

Как сделать такую форму для секции?

сколько себя помню всегда верстал такие секции след образомПросто брал картинку в таком формате и ставил как background

172
Как создать такую кнопку с помощью СSS?

Как создать такую кнопку с помощью СSS?

Здравсвтуйте! Есть прикрепленное изображениеОно является кнопкой меню навигации по сайту

152
Выполнить submit при checked recaptcha [закрыт]

Выполнить submit при checked recaptcha [закрыт]

Как автоматически отправить форму (выполнить submit), если галочка "Я не робот" установлена?

119