Edita código
Copiar al portapapeles
Ejecutar »
<!DOCTYPE html> <html lang="es"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=yes,minimal-ui"> <meta name="mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <title>Puzle Interactivo</title> <style> body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; height: 95vh; margin: 0; background-color: #f0f0f0; } .game-container { display: flex; flex-direction: column; align-items: center; gap: 8px; } .grid { width: 400px; height: 400px; display: grid; grid-template-columns: repeat(4, 100px); grid-template-rows: repeat(4, 100px); border: 2px solid #333; } .grid-cell { border: 1px solid #ccc; background-color: #fff; width: 100px; height: 100px; } .pieces-container { width: 400px; height: 200px; border: 2px solid #333; overflow: hidden; position: relative; } .piece { width: 100px; height: 100px; position: absolute; cursor: move; } #message { text-align: center; margin-top: 10px; font-weight: bold; } #imageUpload { margin-bottom: 10px; } </style> </head> <body> <div class="game-container"> <input type="file" id="imageUpload" accept="image/*"> <div class="grid" id="puzzleGrid"></div> <div id="message"></div> <div class="pieces-container" id="piecesContainer"></div> </div> <script> let image = new Image(); document.getElementById('imageUpload').addEventListener('change', function(e) { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = function(event) { image = new Image(); image.onload = function() { resetPuzzle(); const pieces = createPieces(); setupGrid(); distributePieces(pieces); enableDragAndDrop(); } image.src = event.target.result; } reader.readAsDataURL(file); }); function createPieces() { const pieces = []; const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 400; canvas.height = 400; ctx.drawImage(image, 0, 0, 400, 400); for (let y = 0; y < 4; y++) { for (let x = 0; x < 4; x++) { const pieceCanvas = document.createElement('canvas'); pieceCanvas.width = 100; pieceCanvas.height = 100; const pieceCtx = pieceCanvas.getContext('2d'); pieceCtx.drawImage(canvas, x * 100, y * 100, 100, 100, 0, 0, 100, 100); pieceCanvas.className = 'piece'; pieceCanvas.dataset.x = x; pieceCanvas.dataset.y = y; pieceCanvas.id = `piece-${x}-${y}`; pieces.push(pieceCanvas); } } return pieces; } function setupGrid() { const grid = document.getElementById('puzzleGrid'); grid.innerHTML = ''; for (let i = 0; i < 16; i++) { const cell = document.createElement('div'); cell.className = 'grid-cell'; cell.dataset.index = i; grid.appendChild(cell); } } function distributePieces(pieces) { const container = document.getElementById('piecesContainer'); container.innerHTML = ''; pieces.forEach(piece => { positionPieceRandomly(piece, container); container.appendChild(piece); }); } function positionPieceRandomly(piece, container) { piece.style.left = `${Math.random() * 300}px`; piece.style.top = `${Math.random() * 100}px`; } function enableDragAndDrop() { const pieces = document.querySelectorAll('.piece'); const cells = document.querySelectorAll('.grid-cell'); const container = document.getElementById('piecesContainer'); pieces.forEach(piece => { piece.setAttribute('draggable', true); piece.addEventListener('dragstart', dragStart); piece.addEventListener('mousedown', bringToFront); }); [...cells, container].forEach(element => { element.addEventListener('dragover', dragOver); element.addEventListener('drop', drop); }); } function bringToFront(e) { const piece = e.target; piece.parentNode.appendChild(piece); } function dragStart(e) { e.dataTransfer.setData('text/plain', e.target.id); } function dragOver(e) { e.preventDefault(); } function drop(e) { e.preventDefault(); const pieceId = e.dataTransfer.getData('text'); const piece = document.getElementById(pieceId); if (piece) { if (e.target.classList.contains('grid-cell')) { if (e.target.childElementCount === 0 || isNearCell(piece, e.target)) { if (e.target.childElementCount > 0) { const existingPiece = e.target.firstChild; returnPieceToContainer(existingPiece); } e.target.appendChild(piece); piece.style.position = 'static'; piece.style.left = ''; piece.style.top = ''; } } else if (e.target.id === 'piecesContainer' || e.target.classList.contains('piece')) { returnPieceToContainer(piece); } checkPuzzleState(); } } function returnPieceToContainer(piece) { const container = document.getElementById('piecesContainer'); container.appendChild(piece); piece.style.position = 'absolute'; positionPieceRandomly(piece, container); } function isNearCell(piece, cell) { const pieceRect = piece.getBoundingClientRect(); const cellRect = cell.getBoundingClientRect(); const distance = Math.sqrt( Math.pow(pieceRect.left - cellRect.left, 2) + Math.pow(pieceRect.top - cellRect.top, 2) ); return distance < 50; } function checkPuzzleState() { const cells = document.querySelectorAll('.grid-cell'); let isComplete = true; let isOverlapping = false; cells.forEach((cell, index) => { const piece = cell.querySelector('.piece'); if (!piece) { isComplete = false; } else { const correctX = index % 4; const correctY = Math.floor(index / 4); if (parseInt(piece.dataset.x) !== correctX || parseInt(piece.dataset.y) !== correctY) { isComplete = false; } } if (cell.children.length > 1) { isOverlapping = true; } }); const messageElement = document.getElementById('message'); if (isComplete) { messageElement.textContent = "¡Lo lograste, felicitaciones!"; } else if (isOverlapping) { messageElement.textContent = "Piezas montadas"; } else { messageElement.textContent = ""; } } function resetPuzzle() { document.getElementById('puzzleGrid').innerHTML = ''; document.getElementById('piecesContainer').innerHTML = ''; document.getElementById('message').textContent = ''; } // Inicializar con una imagen por defecto image.src = 'images/imagen.webp'; image.onload = function() { const pieces = createPieces(); setupGrid(); distributePieces(pieces); enableDragAndDrop(); }; </script> </body> </html>
Resultado
Instrucciones