broadfield-archive/Non-downloadable-Image
0
1document.addEventListener('DOMContentLoaded', () => {2 // DOM elements3 const canvas = document.getElementById('unscramble-canvas');4 const ctx = canvas.getContext('2d');5 const loadingMessage = document.getElementById('loading-message');6 7 // Prevent right-click on the canvas8 canvas.oncontextmenu = (e) => {9 e.preventDefault();10 return false;11 };12 13 // --- Main Unscrambling Logic ---14 15 async function unscramble() {16 try {17 // 1. Fetch the map data and the scrambled image simultaneously18 const [mapResponse, scrambledImage] = await Promise.all([19 fetch('assets/map.json'),20 loadImage('assets/scrambled.png')21 ]);22 23 if (!mapResponse.ok) {24 throw new Error(`Failed to load map.json: ${mapResponse.statusText}`);25 }26 27 const mapData = await mapResponse.json();28 const { gridSize, scrambleMap, width, height } = mapData;29 30 // Hide the loading message and set canvas dimensions31 loadingMessage.style.display = 'none';32 canvas.width = width;33 canvas.height = height;34 35 // 2. Calculate the tile dimensions36 const tileW = canvas.width / gridSize;37 const tileH = canvas.height / gridSize;38 39 // 3. Create an "inverse map" for easy unscrambling.40 // The scrambleMap tells us: new_position -> original_position41 // We need to know where the tile for an original_position is located now.42 const inverseMap = new Array(scrambleMap.length);43 for (let newIndex = 0; newIndex < scrambleMap.length; newIndex++) {44 const originalIndex = scrambleMap[newIndex];45 inverseMap[originalIndex] = newIndex;46 }47 48 // 4. Loop through each TILE of the FINAL image and draw it on the canvas49 for (let originalIndex = 0; originalIndex < scrambleMap.length; originalIndex++) {50 // Find where this tile is located in the SCRAMBLED image51 const scrambledIndex = inverseMap[originalIndex];52 53 // Calculate source (from scrambled.png) and destination (on canvas) coordinates54 const sourceX = (scrambledIndex % gridSize) * tileW;55 const sourceY = Math.floor(scrambledIndex / gridSize) * tileH;56 57 const destX = (originalIndex % gridSize) * tileW;58 const destY = Math.floor(originalIndex / gridSize) * tileH;59 60 // Copy the rectangular tile from the hidden scrambled image to the visible canvas61 ctx.drawImage(62 scrambledImage, // The source image63 sourceX, sourceY, // Top-left corner of the source tile64 tileW, tileH, // Dimensions of the source tile65 destX, destY, // Top-left corner of the destination on the canvas66 tileW, tileH // Dimensions of the destination tile67 );68 }69 70 } catch (error) {71 console.error("Unscrambling failed:", error);72 loadingMessage.textContent = `Error: ${error.message}`;73 loadingMessage.style.color = 'red';74 }75 }76 77 // Helper function to load an image and return a promise78 function loadImage(src) {79 return new Promise((resolve, reject) => {80 const img = new Image();81 img.onload = () => resolve(img);82 img.onerror = (err) => reject(new Error(`Failed to load image: ${src}`));83 img.src = src;84 });85 }86 87 // Run the main function88 unscramble();89});