broadfield-dev/stack-overflow-game
0
1/**2 * Extracts dominant colors from an image to create a palette for Tetris blocks3 */4export default class ColorExtractor {5 /**6 * Extract 7 dominant colors from a texture7 * @param {Phaser.Scene} scene - The Phaser scene8 * @param {string} textureKey - The key of the loaded texture9 * @returns {number[]} Array of 7 color values in hex format10 */11 static extractPalette(scene, textureKey) {12 const texture = scene.textures.get(textureKey);13 const source = texture.getSourceImage();14 15 // Create a temporary canvas to analyze the image16 const canvas = document.createElement('canvas');17 const ctx = canvas.getContext('2d');18 canvas.width = source.width;19 canvas.height = source.height;20 ctx.drawImage(source, 0, 0);21 22 const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);23 const pixels = imageData.data;24 25 // Sample pixels (every 4th pixel for performance)26 const colorMap = new Map();27 for (let i = 0; i < pixels.length; i += 16) { // RGBA, skip every 4 pixels28 const r = pixels[i];29 const g = pixels[i + 1];30 const b = pixels[i + 2];31 const a = pixels[i + 3];32 33 // Skip transparent pixels34 if (a < 128) continue;35 36 // Quantize colors to reduce similar shades37 const qr = Math.round(r / 32) * 32;38 const qg = Math.round(g / 32) * 32;39 const qb = Math.round(b / 32) * 32;40 41 const colorKey = (qr << 16) | (qg << 8) | qb;42 colorMap.set(colorKey, (colorMap.get(colorKey) || 0) + 1);43 }44 45 // Sort colors by frequency46 const sortedColors = Array.from(colorMap.entries())47 .sort((a, b) => b[1] - a[1])48 .map(entry => entry[0]);49 50 // Get top 7 colors, ensuring variety51 const palette = [];52 for (let i = 0; i < sortedColors.length && palette.length < 7; i++) {53 const color = sortedColors[i];54 55 // Ensure color is not too dark (visible on dark backgrounds)56 const r = (color >> 16) & 0xFF;57 const g = (color >> 8) & 0xFF;58 const b = color & 0xFF;59 const brightness = (r + g + b) / 3;60 61 if (brightness > 70) { // Skip dark colors - minimum brightness threshold62 palette.push(color);63 }64 }65 66 // Fill remaining slots with vibrant defaults if needed67 const defaultColors = [68 0x00F0F0, // Cyan69 0xF0F000, // Yellow70 0xA000F0, // Purple71 0x00F000, // Green72 0xF00000, // Red73 0x0000F0, // Blue74 0xF0A000 // Orange75 ];76 77 while (palette.length < 7) {78 palette.push(defaultColors[palette.length]);79 }80 81 return palette;82 }83}84 85 