This repository has been archived on 2021-02-20. You can view files and clone it, but cannot push or open issues or pull requests.
shapez.io/res_raw/sprites/belt/generate_wire_sprites.js

214 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 = 14;
const lowerLineSize = 32;
const variants = {
first: "#61ef6f",
second: "#f0bd65",
third: "#5fb2f1",
conflict: "#f74c4c",
};
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 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);
const lineCanvas = createCanvas(dimensions, dimensions);
const lineContext = lineCanvas.getContext("2d");
lineContext.quality = "best";
lineContext.clearRect(0, 0, dimensions, dimensions);
lineContext.strokeStyle = hexDarkenedColor;
lineContext.lineWidth = lowerLineSize;
lineContext.lineCap = "square";
lineContext.imageSmoothingEnabled = false;
// Draw lower lines
partLines.forEach(([x1, y1, x2, y2]) => {
lineContext.beginPath();
lineContext.moveTo(x1 * dimensions, y1 * dimensions);
lineContext.lineTo(x2 * dimensions, y2 * dimensions);
lineContext.stroke();
});
context.globalAlpha = 0.4;
context.drawImage(lineCanvas, 0, 0, dimensions, dimensions);
context.globalAlpha = 1;
context.imageSmoothingEnabled = false;
context.lineCap = "square";
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);
console.log("Done!");
}
run();