Реализация сборки пазла с использованием 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, время: 18:09. |