mirror of
				https://github.com/tobspr/shapez.io.git
				synced 2025-06-13 13:04:03 +00:00 
			
		
		
		
	
		
			
	
	
		
			227 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			227 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | /** | ||
|  |  * | ||
|  |  * Run `yarn global add canvas` first | ||
|  |  */ | ||
|  | 
 | ||
|  | const { createCanvas } = require("canvas"); | ||
|  | const fs = require("fs"); | ||
|  | const path = require("path"); | ||
|  | 
 | ||
|  | const outputFolder = path.join(__dirname, "..", "wires", "sets"); | ||
|  | 
 | ||
|  | const dimensions = 192; | ||
|  | const lineSize = 12; | ||
|  | const lowerLineSize = 20; | ||
|  | 
 | ||
|  | function hexToRGB(h) { | ||
|  |     let r = 0, | ||
|  |         g = 0, | ||
|  |         b = 0; | ||
|  | 
 | ||
|  |     // 3 digits
 | ||
|  |     if (h.length == 4) { | ||
|  |         r = "0x" + h[1] + h[1]; | ||
|  |         g = "0x" + h[2] + h[2]; | ||
|  |         b = "0x" + h[3] + h[3]; | ||
|  | 
 | ||
|  |         // 6 digits
 | ||
|  |     } else if (h.length == 7) { | ||
|  |         r = "0x" + h[1] + h[2]; | ||
|  |         g = "0x" + h[3] + h[4]; | ||
|  |         b = "0x" + h[5] + h[6]; | ||
|  |     } | ||
|  | 
 | ||
|  |     return [+r, +g, +b]; | ||
|  | } | ||
|  | 
 | ||
|  | function RGBToHSL(r, g, b) { | ||
|  |     // Make r, g, and b fractions of 1
 | ||
|  |     r /= 255; | ||
|  |     g /= 255; | ||
|  |     b /= 255; | ||
|  | 
 | ||
|  |     // Find greatest and smallest channel values
 | ||
|  |     let cmin = Math.min(r, g, b), | ||
|  |         cmax = Math.max(r, g, b), | ||
|  |         delta = cmax - cmin, | ||
|  |         h = 0, | ||
|  |         s = 0, | ||
|  |         l = 0; | ||
|  |     // Calculate hue
 | ||
|  |     // No difference
 | ||
|  |     if (delta == 0) h = 0; | ||
|  |     // Red is max
 | ||
|  |     else if (cmax == r) h = ((g - b) / delta) % 6; | ||
|  |     // Green is max
 | ||
|  |     else if (cmax == g) h = (b - r) / delta + 2; | ||
|  |     // Blue is max
 | ||
|  |     else h = (r - g) / delta + 4; | ||
|  | 
 | ||
|  |     h = Math.round(h * 60); | ||
|  | 
 | ||
|  |     // Make negative hues positive behind 360°
 | ||
|  |     if (h < 0) h += 360; | ||
|  | 
 | ||
|  |     // Calculate lightness
 | ||
|  |     l = (cmax + cmin) / 2; | ||
|  | 
 | ||
|  |     // Calculate saturation
 | ||
|  |     s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)); | ||
|  | 
 | ||
|  |     // Multiply l and s by 100
 | ||
|  |     s = +(s * 100).toFixed(1); | ||
|  |     l = +(l * 100).toFixed(1); | ||
|  | 
 | ||
|  |     return [h, s, l]; | ||
|  | } | ||
|  | 
 | ||
|  | function HSLToRGB(h, s, l) { | ||
|  |     // Must be fractions of 1
 | ||
|  |     s /= 100; | ||
|  |     l /= 100; | ||
|  | 
 | ||
|  |     let c = (1 - Math.abs(2 * l - 1)) * s, | ||
|  |         x = c * (1 - Math.abs(((h / 60) % 2) - 1)), | ||
|  |         m = l - c / 2, | ||
|  |         r = 0, | ||
|  |         g = 0, | ||
|  |         b = 0; | ||
|  | 
 | ||
|  |     if (0 <= h && h < 60) { | ||
|  |         r = c; | ||
|  |         g = x; | ||
|  |         b = 0; | ||
|  |     } else if (60 <= h && h < 120) { | ||
|  |         r = x; | ||
|  |         g = c; | ||
|  |         b = 0; | ||
|  |     } else if (120 <= h && h < 180) { | ||
|  |         r = 0; | ||
|  |         g = c; | ||
|  |         b = x; | ||
|  |     } else if (180 <= h && h < 240) { | ||
|  |         r = 0; | ||
|  |         g = x; | ||
|  |         b = c; | ||
|  |     } else if (240 <= h && h < 300) { | ||
|  |         r = x; | ||
|  |         g = 0; | ||
|  |         b = c; | ||
|  |     } else if (300 <= h && h < 360) { | ||
|  |         r = c; | ||
|  |         g = 0; | ||
|  |         b = x; | ||
|  |     } | ||
|  |     r = Math.round((r + m) * 255); | ||
|  |     g = Math.round((g + m) * 255); | ||
|  |     b = Math.round((b + m) * 255); | ||
|  | 
 | ||
|  |     return [r, g, b]; | ||
|  | } | ||
|  | 
 | ||
|  | async function run() { | ||
|  |     console.log("Running"); | ||
|  | 
 | ||
|  |     const variants = { | ||
|  |         regular: "#25fff2", | ||
|  |         color: "#eba458", | ||
|  |         shape: "#8858eb", | ||
|  |         conflict: "#ff3e3e", | ||
|  |     }; | ||
|  | 
 | ||
|  |     const promises = []; | ||
|  | 
 | ||
|  |     for (const variantId in variants) { | ||
|  |         const variantColor = variants[variantId]; | ||
|  |         const variantHSL = RGBToHSL(...hexToRGB(variantColor)); | ||
|  |         const darkenedColor = HSLToRGB(variantHSL[0], variantHSL[1] - 15, variantHSL[2] - 20); | ||
|  |         const hexDarkenedColor = "rgb(" + darkenedColor.join(",") + ")"; | ||
|  | 
 | ||
|  |         console.log(variantColor, "->", hexToRGB(variantColor), variantHSL, "->", darkenedColor); | ||
|  | 
 | ||
|  |         const parts = { | ||
|  |             forward: [[0.5, 0, 0.5, 1]], | ||
|  |             turn: [ | ||
|  |                 [0.5, 0.5, 0.5, 1], | ||
|  |                 [0.5, 0.5, 1, 0.5], | ||
|  |             ], | ||
|  |             split: [ | ||
|  |                 [0.5, 0.5, 0.5, 1], | ||
|  |                 [0, 0.5, 1, 0.5], | ||
|  |             ], | ||
|  |             cross: [ | ||
|  |                 [0, 0.5, 1, 0.5], | ||
|  |                 [0.5, 0, 0.5, 1], | ||
|  |             ], | ||
|  |         }; | ||
|  | 
 | ||
|  |         for (const partId in parts) { | ||
|  |             const partLines = parts[partId]; | ||
|  | 
 | ||
|  |             const canvas = createCanvas(dimensions, dimensions); | ||
|  |             const context = canvas.getContext("2d"); | ||
|  |             context.quality = "best"; | ||
|  |             context.clearRect(0, 0, dimensions, dimensions); | ||
|  | 
 | ||
|  |             context.strokeStyle = hexDarkenedColor; | ||
|  |             context.lineWidth = lowerLineSize; | ||
|  |             context.lineCap = "square"; | ||
|  |             context.imageSmoothingEnabled = false; | ||
|  | 
 | ||
|  |             // Draw lower lines
 | ||
|  |             partLines.forEach(([x1, y1, x2, y2]) => { | ||
|  |                 context.beginPath(); | ||
|  |                 context.moveTo(x1 * dimensions, y1 * dimensions); | ||
|  |                 context.lineTo(x2 * dimensions, y2 * dimensions); | ||
|  |                 context.stroke(); | ||
|  |             }); | ||
|  | 
 | ||
|  |             context.strokeStyle = variantColor; | ||
|  |             context.lineWidth = lineSize; | ||
|  | 
 | ||
|  |             // Draw upper lines
 | ||
|  |             partLines.forEach(([x1, y1, x2, y2]) => { | ||
|  |                 context.beginPath(); | ||
|  |                 context.moveTo(x1 * dimensions, y1 * dimensions); | ||
|  |                 context.lineTo(x2 * dimensions, y2 * dimensions); | ||
|  |                 context.stroke(); | ||
|  |             }); | ||
|  | 
 | ||
|  |             const out = fs.createWriteStream(path.join(outputFolder, variantId + "_" + partId + ".png")); | ||
|  |             const stream = canvas.createPNGStream(); | ||
|  |             stream.pipe(out); | ||
|  |             promises.push(new Promise(resolve => stream.on("end", resolve))); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     console.log("Waiting for completion"); | ||
|  |     await Promise.all(promises); | ||
|  | 
 | ||
|  |     // Also wait a bit more
 | ||
|  |     await new Promise(resolve => setTimeout(resolve, 1000)); | ||
|  | 
 | ||
|  |     console.log("Copying files to all locations"); | ||
|  | 
 | ||
|  |     // // Copy other files
 | ||
|  |     fs.copyFileSync( | ||
|  |         path.join(outputFolder, "regular_forward.png"), | ||
|  |         path.join(__dirname, "..", "buildings", "wire.png") | ||
|  |     ); | ||
|  |     fs.copyFileSync( | ||
|  |         path.join(outputFolder, "regular_turn.png"), | ||
|  |         path.join(__dirname, "..", "buildings", "wire-turn.png") | ||
|  |     ); | ||
|  |     fs.copyFileSync( | ||
|  |         path.join(outputFolder, "regular_split.png"), | ||
|  |         path.join(__dirname, "..", "buildings", "wire-split.png") | ||
|  |     ); | ||
|  |     fs.copyFileSync( | ||
|  |         path.join(outputFolder, "regular_cross.png"), | ||
|  |         path.join(__dirname, "..", "buildings", "wire-cross.png") | ||
|  |     ); | ||
|  | 
 | ||
|  |     console.log("Done!"); | ||
|  | } | ||
|  | 
 | ||
|  | run(); |