Реализация сборки пазла с использованием Drag'N'Drop (чистый JavaScript)
Вложений: 2
Есть три блока: блок изображения пазла, блок изображения пазла разбитого на 25 частей и такой же блок только полупрозрачный (50% прозрачности). Мне нужно чтобы с блока изображения пазла разбитого на 25 частей можно было перетаскивать одну из этих частей на второй такой же, полупрозрачный блок.
Нужно использовать для реализации перестаскивания элементов пазла с одного блока на другой технологию Drag'N'Drop. Вот ссылка на весь программный код реализации пазла: https://codepen.io/nightofpromises/pen/ZPXVva. Я прошу вас не использовать JQuery, Ajax, а использовать чистый JavaScript. Блок слайдера предназначен для выбора случайного изображения. Для получения другого изображения необходима кнопка «>» («Next»). Кнопка «Puzzlify», находящаяся под изображением, подтверждает выбор пользователем. В двух блоках сбора пазлов ниже отображается выбранное изображение. Правый блок представляет из себя подложку для сборки паззла –контейнер с «разрезанными», но не «перемешанными» частями выбранного изображения, прозрачность 50%. Левый блок представляет из себя контейнер с «разрезанными» и «перемешанными» частями выбранного изображения. Бэкграунд веб-приложения должен иметь линейный градиент. Во всех блоках приложения пропорции изображения не должны быть изменены. Курсор в блоке сбора пазлов должен иметь вид «руки» (grab,grabbing). Изображение в блоке сборки пазла должно «разрезаться» на 25 частей (5 отрезков по вертикали и 5 –по горизонтали). Предусмотреть анимацию элементов управления. Реализовать надо логику блока слайдера, воспользовавшись API сервера unsplash.com (https://unsplash.it/600/600/?random) для получения случайных изображений. При открытии в блоке слайдера отображается первое рандомное изображение, последующие генерации при нажатии кнопки «>» («Next»). При длительной загрузке вместо изображения должен отображаться лоадер (https://www.artmajeur.com/img/ajax-loader.gif). После успешной загрузки изображения должна стать активной кнопка «Puzzlify». Надо реализовать функции «разрезания» на части изображения и «перемешивания» их для блока сбора пазлов. Создать обработчик кнопки «Puzzlify». По нажатию кнопки «Puzzlify» в двух блоках сбора пазлов ниже должно отображаться выбранное изображение, в правом только разрезанное, в левом –разрезанное и перемешанное. Также необходимо реализовать функцию сборки пазла, включающую в себя: − перетаскивание частей изображения с левого блока в правый; − при верной локализации перетаскиваемой части реализация запрета дальнейшего движения; − вывод сообщения в случае окончания сборки пазлов. В целом функциональные возможности приложения следующими должны быть: — предоставление выбора изображения в виде слайдера — предоставление выбора изображения указанием ссылки — задавать количество частей разбивки изображения — разбивание выбранного или указанного изображения на заданное количество частей и генерация пазла — предоставление возможности пользователю собирать сгенерированный пазл — проверка статуса компоновки пазла, в случае если пазл собран, выдавать пользователю сообщение об успехе (и затраченном времени) — реализация в приложении счетчика для хранения и отображения количества успешных сборов пазла 1) Так должен выглядеть интерфейс 2) Так выглядит интерфейс который был реализован. Перемешивание пазлов сделано, но я понятия не имею как реализовать перетаскивание частей пазла на другую прозрачную часть. И еще у меня проблема следующего характера. Дело в том что когда я нажимаю на кнопку Next, пазл не должен разбиваться на части, а картинка пазла должна сама обновляться. Как сделать так чтобы с блока пазла который разбивается на 25 частей можно было переносить на полупрозрачный блок как делается здесь: https://codepen.io/kiyutink/pen/NNrBxy, но с использованием чистого JavaScript, а не Ajax, Jquery. Как реализовать это?! :cray: Помогите мне срочно, кто-нибудь, пожалуйста:help: Мне нужна помощь того кто разбирается в Drag'N'Drop на чистом JavaScript без использования Ajax, Jquery. Просто я понятия не имею как все то что я выше перечислила реализовать. |
На всякий случай выкладываю HTML, CSS и JavaScript-коды пазла на Drag'N'Drop:
<!DOCTYPE HTML> <html> <head> <title>Puzzle Game</title> <link rel="stylesheet"> <script type="text/javascript"> </script> </head> <body onload="init();"> <center> <div class="header"> <h1>Javascript Puzzle Game</h1> </div> <div><button type="submit">Next</button><br><br><img width="250px" src=""></div><br> <input type="submit" value="Puzzlify"><br><br> <div class="puzzleFrame"> <canvas id="myCanvas"></canvas> <div class="drop-zone"></div> </div> </center> </body> </html> Код:
* { var img = document.getElementsByTagName("img")[0]; img.src = 'https://picsum.photos/600/600/?random'; document.getElementsByTagName('button')[0].addEventListener("click", function() { var img = document.getElementsByTagName("img")[0]; img.src = 'https://picsum.photos/600/600/?random'; location.reload(true); }) const PUZZLE_DIFFICULTY = 5; const PUZZLE_HOVER_TINT = '#009900'; var canvas; var stage; var img; var pieces; var puzzleWidth; var puzzleHeight; var pieceWidth; var pieceHeight; var currentPiece; var currentDropPiece; var mouse; function init(){ img = new Image(); img.addEventListener('load',onImage,false); img.src = "https://picsum.photos/600/600/?random"; } document.getElementsByTagName('input').addEventListener("onclick", function() { initPuzzle(); }) function onImage(e){ pieceWidth = Math.floor(img.width / PUZZLE_DIFFICULTY) pieceHeight = Math.floor(img.height / PUZZLE_DIFFICULTY) puzzleWidth = pieceWidth * PUZZLE_DIFFICULTY; puzzleHeight = pieceHeight * PUZZLE_DIFFICULTY; setCanvas(); initPuzzle(); } function setCanvas(){ canvas = document.getElementById('myCanvas'); stage = canvas.getContext('2d'); canvas.width = puzzleWidth; canvas.height = puzzleHeight; canvas.style.border = "1px solid black"; } function initPuzzle(){ pieces = []; mouse = {x:0,y:0}; currentPiece = null; currentDropPiece = null; stage.drawImage(img, 0, 0, puzzleWidth, puzzleHeight, 0, 0, puzzleWidth, puzzleHeight); buildPieces(); } function createTitle(msg){ stage.fillStyle = "#000000"; stage.globalAlpha = .5; stage.fillRect(100,puzzleHeight - 100,puzzleWidth - 200,40); stage.fillStyle = "#FFFFFF"; stage.globalAlpha = 1; stage.textAlign = "center"; stage.textBaseline = "middle"; stage.font = "20px Arial"; stage.fillText(msg, puzzleWidth / 2, puzzleHeight - 80); } function buildPieces(){ var i; var piece; var xPos = 0; var yPos = 0; for(i = 0;i < PUZZLE_DIFFICULTY * PUZZLE_DIFFICULTY;i++){ piece = {}; piece.sx = xPos; piece.sy = yPos; pieces.push(piece); xPos += pieceWidth; if(xPos >= puzzleWidth){ xPos = 0; yPos += pieceHeight; } } document.onmousedown = shufflePuzzle; } function shufflePuzzle(){ pieces = shuffleArray(pieces); stage.clearRect(0,0,puzzleWidth,puzzleHeight); var i; var piece; var xPos = 0; var yPos = 0; for(i = 0;i < pieces.length;i++){ piece = pieces[i]; piece.xPos = xPos; piece.yPos = yPos; stage.drawImage(img, piece.sx, piece.sy, pieceWidth, pieceHeight, xPos, yPos, pieceWidth, pieceHeight); stage.strokeRect(xPos, yPos, pieceWidth,pieceHeight); xPos += pieceWidth; if(xPos >= puzzleWidth){ xPos = 0; yPos += pieceHeight; } } document.onmousedown = onPuzzleClick; } function shuffleArray(o){ for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); return o; } function onPuzzleClick(e){ if(e.layerX || e.layerX == 0){ mouse.x = e.layerX - canvas.offsetLeft; mouse.y = e.layerY - canvas.offsetTop; } else if(e.offsetX || e.offsetX == 0){ mouse.x = e.offsetX - canvas.offsetLeft; mouse.y = e.offsetY - canvas.offsetTop; } currentPiece = checkPieceClicked(); if(currentPiece != null){ stage.clearRect(currentPiece.xPos,currentPiece.yPos,pieceWidth,pieceHeight); stage.save(); stage.globalAlpha = .9; stage.drawImage(img, currentPiece.sx, currentPiece.sy, pieceWidth, pieceHeight, mouse.x - (pieceWidth / 2), mouse.y - (pieceHeight / 2), pieceWidth, pieceHeight); stage.restore(); document.onmousemove = updatePuzzle; document.onmouseup = pieceDropped; } } function checkPieceClicked(){ var i; var piece; for(i = 0;i < pieces.length;i++){ piece = pieces[i]; if(mouse.x < piece.xPos || mouse.x > (piece.xPos + pieceWidth) || mouse.y < piece.yPos || mouse.y > (piece.yPos + pieceHeight)){ //PIECE NOT HIT } else{ return piece; } } return null; } function updatePuzzle(e){ currentDropPiece = null; if(e.layerX || e.layerX == 0){ mouse.x = e.layerX - canvas.offsetLeft; mouse.y = e.layerY - canvas.offsetTop; } else if(e.offsetX || e.offsetX == 0){ mouse.x = e.offsetX - canvas.offsetLeft; mouse.y = e.offsetY - canvas.offsetTop; } stage.clearRect(0,0,puzzleWidth,puzzleHeight); var i; var piece; for(i = 0;i < pieces.length;i++){ piece = pieces[i]; if(piece == currentPiece){ continue; } stage.drawImage(img, piece.sx, piece.sy, pieceWidth, pieceHeight, piece.xPos, piece.yPos, pieceWidth, pieceHeight); stage.strokeRect(piece.xPos, piece.yPos, pieceWidth, pieceHeight); if(currentDropPiece == null){ if(mouse.x < piece.xPos || mouse.x > (piece.xPos + pieceWidth) || mouse.y < piece.yPos || mouse.y > (piece.yPos + pieceHeight)){ //NOT OVER } else{ currentDropPiece = piece; stage.save(); stage.globalAlpha = .4; stage.fillStyle = PUZZLE_HOVER_TINT; stage.fillRect(currentDropPiece.xPos,currentDropPiece.yPos,pieceWidth, pieceHeight); stage.restore(); } } } stage.save(); stage.globalAlpha = .6; stage.drawImage(img, currentPiece.sx, currentPiece.sy, pieceWidth, pieceHeight, mouse.x - (pieceWidth / 2), mouse.y - (pieceHeight / 2), pieceWidth, pieceHeight); stage.restore(); stage.strokeRect( mouse.x - (pieceWidth / 2), mouse.y - (pieceHeight / 2), pieceWidth,pieceHeight); } function pieceDropped(e){ document.onmousemove = null; document.onmouseup = null; if(currentDropPiece != null){ var tmp = {xPos:currentPiece.xPos,yPos:currentPiece.yPos}; currentPiece.xPos = currentDropPiece.xPos; currentPiece.yPos = currentDropPiece.yPos; currentDropPiece.xPos = tmp.xPos; currentDropPiece.yPos = tmp.yPos; } resetPuzzleAndCheckWin(); } function resetPuzzleAndCheckWin(){ stage.clearRect(0,0,puzzleWidth,puzzleHeight); var gameWin = true; var i; var piece; for(i = 0;i < pieces.length;i++){ piece = pieces[i]; stage.drawImage(img, piece.sx, piece.sy, pieceWidth, pieceHeight, piece.xPos, piece.yPos, pieceWidth, pieceHeight); stage.strokeRect(piece.xPos, piece.yPos, pieceWidth,pieceHeight); if(piece.xPos != piece.sx || piece.yPos != piece.sy){ gameWin = false; } } if(gameWin){ setTimeout(gameOver,500); alert("You Win!"); } } function gameOver(){ document.onmousedown = null; document.onmousemove = null; document.onmouseup = null; initPuzzle(); } |
Часовой пояс GMT +3, время: 09:37. |