📜
cutout_copy.js
Back
📝 Javascript ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
// cutout.js - Sprite sheet cutting tool (function(){ let selectedImage = null; let selectedFolder = null; let tileSize = 32; // default // Listen for image selection from Files module window.addEventListener('imageSelected', (e) => { selectedImage = e.detail.url; selectedFolder = e.detail.folder; // Try to parse folder name as grid size (16, 32, 64, 128) const folderSize = parseInt(selectedFolder); if ([16, 32, 64, 128].includes(folderSize)) { tileSize = folderSize; } console.log('Image selected for cutting:', selectedImage, 'Folder:', selectedFolder, 'Grid:', tileSize); // Immediately refresh (safe no-op if view isn't mounted yet) updateContent(selectedImage, tileSize); }); function renderTileSizeSelector(currentSize) { const sizes = [16, 32, 64, 128]; return ` <div style="margin-bottom: 1rem; padding: 1rem; background: rgba(30, 41, 59, 0.6); border-radius: 0.75rem; border: 1px solid rgba(71, 85, 105, 0.4);"> <label style="display: block; color: #94a3b8; font-size: 0.875rem; margin-bottom: 0.5rem; text-transform: uppercase; letter-spacing: 0.05em;"> Grid Size </label> <select id="grid-size-select" style=" width: 100%; background: rgba(15, 23, 42, 0.8); border: 1px solid rgba(71, 85, 105, 0.4); color: #f1f5f9; padding: 0.75rem; border-radius: 0.5rem; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; " onmouseover="this.style.borderColor='rgba(59, 130, 246, 0.6)'" onmouseout="this.style.borderColor='rgba(71, 85, 105, 0.4)'" > ${sizes.map(size => ` <option value="${size}" ${size === currentSize ? 'selected' : ''}> ${size}×${size} pixels </option> `).join('')} </select> </div> `; } function renderCuttingCanvas(imageSrc, gridSize) { if (!imageSrc) { return ` <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 300px; color: #94a3b8; text-align: center; padding: 2rem;"> <div style="font-size: 3rem; margin-bottom: 1rem;">✂️</div> <p>No image selected</p> <p style="font-size: 0.875rem; margin-top: 0.5rem;">Select an image from the Files tab to start cutting</p> </div> `; } return ` <div style="position: relative; overflow: auto; max-height: 60vh; background: #0a0f1c; border-radius: 0.75rem; border: 1px solid rgba(71, 85, 105, 0.4);"> <div id="canvas-container" style="position: relative; display: inline-block;"> <img id="sprite-sheet" src="${imageSrc}" style="display: block; max-width: none; image-rendering: pixelated;" crossorigin="anonymous" onload="window.cutoutDrawGrid && window.cutoutDrawGrid()" > <canvas id="grid-overlay" style="position: absolute; top: 0; left: 0; pointer-events: none;" ></canvas> </div> </div> <div style="margin-top: 1rem; padding: 0.75rem; background: rgba(30, 41, 59, 0.4); border-radius: 0.5rem; font-size: 0.875rem; color: #94a3b8;"> <strong style="color: #f1f5f9;">Tip:</strong> Grid automatically adjusts to your spritesheet. Each cell is ${gridSize}×${gridSize}px. </div> `; } function drawGrid() { const img = document.getElementById('sprite-sheet'); const canvas = document.getElementById('grid-overlay'); if (!canvas || !img) return; const ctx = canvas.getContext('2d'); canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; // Position canvas over image canvas.style.width = img.width + 'px'; canvas.style.height = img.height + 'px'; // Clear previous grid ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw grid with simple path ctx.strokeStyle = 'rgba(59, 130, 246, 0.6)'; ctx.lineWidth = 1; ctx.beginPath(); // All vertical lines for (let x = 0; x <= canvas.width; x += tileSize) { ctx.moveTo(x, 0); ctx.lineTo(x, canvas.height); } // All horizontal lines for (let y = 0; y <= canvas.height; y += tileSize) { ctx.moveTo(0, y); ctx.lineTo(canvas.width, y); } ctx.stroke(); } // Expose drawGrid globally for inline onload window.cutoutDrawGrid = drawGrid; function updateContent(imageSrc = selectedImage, gridSize = tileSize) { const container = document.getElementById('cutout-content'); if (!container) return; tileSize = gridSize; container.innerHTML = ` ${renderTileSizeSelector(gridSize)} ${renderCuttingCanvas(imageSrc, gridSize)} `; wireUpControls(); } function wireUpControls() { // Dropdown const select = document.getElementById('grid-size-select'); if (select) { select.addEventListener('change', () => { const newSize = parseInt(select.value); tileSize = newSize; updateContent(selectedImage, newSize); }); } // Draw grid if image already loaded const img = document.getElementById('sprite-sheet'); if (img && img.complete) { drawGrid(); } } // Initial HTML const initialHtml = ` <div id="cutout-content" style="height: 100%; overflow-y: auto; padding: 1rem;"> ${renderTileSizeSelector(tileSize)} ${renderCuttingCanvas(selectedImage, tileSize)} </div> `; // Register with onRender callback window.AppItems = window.AppItems || []; window.AppItems.push({ title: '✂️ Cut', html: initialHtml, onRender: function(slideEl) { // Ensure current image/grid render whenever the overlay opens updateContent(selectedImage, tileSize); } }); })();