// Debug alert for mobile debugging
if (typeof debugAlert === 'function') {
debugAlert('tilepicker.js loaded');
}
// Global variables for tile picking
let groups = [{ id: 0, url: null, tiles: [] }];
let currentGroup = 0;
let nextUniqueId = 1; // start at 1 (0 = "no object")
/**
* Initialize the tile picker functionality
*/
function initializeTilePicker() {
renderTabs();
renderPicked();
setupTileGrid();
}
/**
* Setup the tile grid overlay on the image
*/
function setupTileGrid() {
const imgEl = document.getElementById('tileImage');
imgEl.onload = () => {
const container = document.getElementById('tileContainer');
const w = imgEl.naturalWidth;
const h = imgEl.naturalHeight;
// Set container and image dimensions
imgEl.style.width = w + "px";
imgEl.style.height = h + "px";
container.style.width = w + "px";
container.style.height = h + "px";
// Remove existing grid cells
container.querySelectorAll('.grid-cell').forEach(c => c.remove());
// Calculate grid dimensions
const cols = Math.floor(w / selectedTileSize);
// Create grid cells
for (let y = 0; y < h; y += selectedTileSize) {
for (let x = 0; x < w; x += selectedTileSize) {
const cell = document.createElement('div');
cell.className = 'grid-cell';
cell.style.left = x + 'px';
cell.style.top = y + 'px';
cell.style.width = selectedTileSize + 'px';
cell.style.height = selectedTileSize + 'px';
// Calculate tile index for display
const row = Math.floor(y / selectedTileSize);
const col = Math.floor(x / selectedTileSize);
const tileIndex = row * cols + col + 1;
// Add label to cell
const label = document.createElement('span');
label.textContent = tileIndex;
cell.appendChild(label);
// Add click handler to pick this tile
cell.onclick = () => pickTile(imgEl, x, y, selectedTileSize, selectedImage);
container.appendChild(cell);
}
}
};
}
/**
* Render the group tabs
*/
function renderTabs() {
const tabBar = document.getElementById('groupTabs');
if (!tabBar) return;
tabBar.innerHTML = '';
// Render existing group tabs
groups.forEach((g, idx) => {
const btn = document.createElement('button');
btn.textContent = "Group " + (idx + 1);
if (idx === currentGroup) {
btn.classList.add('active');
}
btn.onclick = () => {
currentGroup = idx;
renderTabs();
renderPicked();
};
tabBar.appendChild(btn);
});
// Add "+" button to create new group
const addBtn = document.createElement('button');
addBtn.textContent = "+";
addBtn.onclick = () => {
groups.push({ id: groups.length, url: null, tiles: [] });
currentGroup = groups.length - 1;
renderTabs();
renderPicked();
};
tabBar.appendChild(addBtn);
}
/**
* Render the picked tiles for the current group
*/
function renderPicked() {
const container = document.getElementById('pickedImages');
if (!container) return;
container.innerHTML = '';
const group = groups[currentGroup];
group.tiles.forEach((tile, idx) => {
const wrapper = document.createElement('div');
wrapper.className = 'pickedTile';
// Create canvas to display the tile
const canvas = document.createElement('canvas');
canvas.width = tile.size;
canvas.height = tile.size;
const ctx = canvas.getContext('2d');
ctx.putImageData(tile.data, 0, 0);
// Create remove button
const removeBtn = document.createElement('button');
removeBtn.className = 'removeBtn';
removeBtn.textContent = "×";
removeBtn.onclick = () => {
group.tiles.splice(idx, 1);
renderPicked();
};
// Create ID label
const idLabel = document.createElement('span');
idLabel.textContent = `ID ${tile.uniqueId}`;
wrapper.appendChild(canvas);
wrapper.appendChild(removeBtn);
wrapper.appendChild(idLabel);
container.appendChild(wrapper);
});
}
/**
* Pick a tile from the image at specified coordinates
* @param {HTMLImageElement} imgEl - The source image element
* @param {number} x - X coordinate of the tile
* @param {number} y - Y coordinate of the tile
* @param {number} size - Size of the tile (width and height)
* @param {string} url - URL of the source image
*/
function pickTile(imgEl, x, y, size, url) {
const group = groups[currentGroup];
// Check if group already uses a different image
if (group.url && group.url !== url) {
alert("This group already uses a different image. Make a new group.");
return;
}
// Set the group's image URL
group.url = url;
// Extract the tile data using canvas
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext('2d');
// Draw the tile portion of the image
ctx.drawImage(imgEl, x, y, size, size, 0, 0, size, size);
// Get the image data
const data = ctx.getImageData(0, 0, size, size);
// Add tile to current group
group.tiles.push({
size,
data,
uniqueId: nextUniqueId++,
sourceX: x,
sourceY: y,
sourceUrl: url
});
// Re-render the picked tiles display
renderPicked();
}
/**
* Get the current group data
* @returns {Object} Current group object
*/
function getCurrentGroup() {
return groups[currentGroup];
}
/**
* Get all groups data
* @returns {Array} Array of all group objects
*/
function getAllGroups() {
return groups;
}
/**
* Set the current group
* @param {number} groupIndex - Index of the group to set as current
*/
function setCurrentGroup(groupIndex) {
if (groupIndex >= 0 && groupIndex < groups.length) {
currentGroup = groupIndex;
renderTabs();
renderPicked();
}
}
/**
* Clear all tiles from the current group
*/
function clearCurrentGroup() {
const group = groups[currentGroup];
group.tiles = [];
group.url = null;
renderPicked();
}
/**
* Remove a group by index
* @param {number} groupIndex - Index of the group to remove
*/
function removeGroup(groupIndex) {
if (groups.length > 1 && groupIndex >= 0 && groupIndex < groups.length) {
groups.splice(groupIndex, 1);
// Adjust current group if necessary
if (currentGroup >= groups.length) {
currentGroup = groups.length - 1;
}
renderTabs();
renderPicked();
}
}