Move shape generator to seperate repo

This commit is contained in:
tobspr 2020-06-02 07:43:39 +02:00
parent 2d6e98953c
commit 9afc28bb7e
4 changed files with 0 additions and 547 deletions

View File

@ -1,81 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>
shapez.io shape generator
</title>
<script async src="index.js"></script>
<style>
html,
body {
width: 100%;
height: 100%;
padding: 0;
}
body {
font-family: "Source Sans Pro", "Roboto", sans-serif;
background: #fafafa;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#resultWrapper {
border: 1px solid #ccc;
margin-top: 10px;
background: #fff;
padding: 40px;
}
#resultWrapper #result {
}
#code {
width: 600px;
font-family: monospace;
padding: 30px;
border: 1px solid #ccc;
background: #fff;
font-size: 17px;
}
#code:focus {
outline: none;
border-color: #39f;
}
#error {
height: 40px;
color: #f77;
margin-top: 10px;
display: flex;
text-align: left;
align-items: center;
}
#error:not(.hasError) {
color: rgb(71, 179, 71);
}
</style>
</head>
<body>
<h2>Shape generator</h2>
<input
value="CuCuCuCu"
id="code"
placeholder="shape code"
onkeypress="debounce(generate)"
onkeydown="debounce(generate)"
onkeyup="debounce(generate)"
onchange="debounce(generate)"
/>
<div id="error">Error</div>
<br />
<div id="resultWrapper">
<canvas id="result" width="256" height="256"></canvas>
</div>
</body>
</html>

View File

@ -1,301 +0,0 @@
/*
* Lots of code here is copied 1:1 from actual game files
*
*/
/** @enum {string} */
const enumSubShape = {
rect: "rect",
circle: "circle",
star: "star",
windmill: "windmill",
};
/** @enum {string} */
const enumSubShapeToShortcode = {
[enumSubShape.rect]: "R",
[enumSubShape.circle]: "C",
[enumSubShape.star]: "S",
[enumSubShape.windmill]: "W",
};
/** @enum {enumSubShape} */
const enumShortcodeToSubShape = {};
for (const key in enumSubShapeToShortcode) {
enumShortcodeToSubShape[enumSubShapeToShortcode[key]] = key;
}
const arrayQuadrantIndexToOffset = [
{ x: 1, y: -1 }, // tr
{ x: 1, y: 1 }, // br
{ x: -1, y: 1 }, // bl
{ x: -1, y: -1 }, // tl
];
// From colors.js
/** @enum {string} */
const enumColors = {
red: "red",
green: "green",
blue: "blue",
yellow: "yellow",
purple: "purple",
cyan: "cyan",
white: "white",
uncolored: "uncolored",
};
/** @enum {string} */
const enumColorToShortcode = {
[enumColors.red]: "r",
[enumColors.green]: "g",
[enumColors.blue]: "b",
[enumColors.yellow]: "y",
[enumColors.purple]: "p",
[enumColors.cyan]: "c",
[enumColors.white]: "w",
[enumColors.uncolored]: "u",
};
/** @enum {string} */
const enumColorsToHexCode = {
[enumColors.red]: "#ff666a",
[enumColors.green]: "#78ff66",
[enumColors.blue]: "#66a7ff",
// red + green
[enumColors.yellow]: "#fcf52a",
// red + blue
[enumColors.purple]: "#dd66ff",
// blue + green
[enumColors.cyan]: "#87fff5",
// blue + green + red
[enumColors.white]: "#ffffff",
[enumColors.uncolored]: "#aaaaaa",
};
/** @enum {enumColors} */
const enumShortcodeToColor = {};
for (const key in enumColorToShortcode) {
enumShortcodeToColor[enumColorToShortcode[key]] = key;
}
CanvasRenderingContext2D.prototype.beginCircle = function (x, y, r) {
if (r < 0.05) {
this.beginPath();
this.rect(x, y, 1, 1);
return;
}
this.beginPath();
this.arc(x, y, r, 0, 2.0 * Math.PI);
};
/////////////////////////////////////////////////////
function radians(degrees) {
return (degrees * Math.PI) / 180.0;
}
/**
* Generates the definition from the given short key
*/
function fromShortKey(key) {
const sourceLayers = key.split(":");
let layers = [];
for (let i = 0; i < sourceLayers.length; ++i) {
const text = sourceLayers[i];
if (text.length !== 8) {
throw new Error("Invalid layer: '" + text + "' -> must be 8 characters");
}
const quads = [null, null, null, null];
for (let quad = 0; quad < 4; ++quad) {
const shapeText = text[quad * 2 + 0];
const subShape = enumShortcodeToSubShape[shapeText];
const color = enumShortcodeToColor[text[quad * 2 + 1]];
if (subShape) {
if (!color) {
throw new Error("Invalid shape color key: " + key);
}
quads[quad] = {
subShape,
color,
};
} else if (shapeText !== "-") {
throw new Error("Invalid shape key: " + shapeText);
}
}
layers.push(quads);
}
return layers;
}
function renderShape(layers) {
const canvas = /** @type {HTMLCanvasElement} */ (document.getElementById("result"));
const context = canvas.getContext("2d");
context.save();
context.fillStyle = "#fff";
context.fillRect(0, 0, 1000, 1000);
const w = 256;
const h = 256;
const dpi = 1;
context.translate((w * dpi) / 2, (h * dpi) / 2);
context.scale((dpi * w) / 23, (dpi * h) / 23);
context.fillStyle = "#e9ecf7";
const quadrantSize = 10;
const quadrantHalfSize = quadrantSize / 2;
context.fillStyle = "rgba(40, 50, 65, 0.1)";
context.beginCircle(0, 0, quadrantSize * 1.15);
context.fill();
for (let layerIndex = 0; layerIndex < layers.length; ++layerIndex) {
const quadrants = layers[layerIndex];
const layerScale = Math.max(0.1, 0.9 - layerIndex * 0.22);
for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) {
if (!quadrants[quadrantIndex]) {
continue;
}
const { subShape, color } = quadrants[quadrantIndex];
const quadrantPos = arrayQuadrantIndexToOffset[quadrantIndex];
const centerQuadrantX = quadrantPos.x * quadrantHalfSize;
const centerQuadrantY = quadrantPos.y * quadrantHalfSize;
const rotation = radians(quadrantIndex * 90);
context.translate(centerQuadrantX, centerQuadrantY);
context.rotate(rotation);
context.fillStyle = enumColorsToHexCode[color];
context.strokeStyle = "#555";
context.lineWidth = 1;
const insetPadding = 0.0;
switch (subShape) {
case enumSubShape.rect: {
context.beginPath();
const dims = quadrantSize * layerScale;
context.rect(
insetPadding + -quadrantHalfSize,
-insetPadding + quadrantHalfSize - dims,
dims,
dims
);
break;
}
case enumSubShape.star: {
context.beginPath();
const dims = quadrantSize * layerScale;
let originX = insetPadding - quadrantHalfSize;
let originY = -insetPadding + quadrantHalfSize - dims;
const moveInwards = dims * 0.4;
context.moveTo(originX, originY + moveInwards);
context.lineTo(originX + dims, originY);
context.lineTo(originX + dims - moveInwards, originY + dims);
context.lineTo(originX, originY + dims);
context.closePath();
break;
}
case enumSubShape.windmill: {
context.beginPath();
const dims = quadrantSize * layerScale;
let originX = insetPadding - quadrantHalfSize;
let originY = -insetPadding + quadrantHalfSize - dims;
const moveInwards = dims * 0.4;
context.moveTo(originX, originY + moveInwards);
context.lineTo(originX + dims, originY);
context.lineTo(originX + dims, originY + dims);
context.lineTo(originX, originY + dims);
context.closePath();
break;
}
case enumSubShape.circle: {
context.beginPath();
context.moveTo(insetPadding + -quadrantHalfSize, -insetPadding + quadrantHalfSize);
context.arc(
insetPadding + -quadrantHalfSize,
-insetPadding + quadrantHalfSize,
quadrantSize * layerScale,
-Math.PI * 0.5,
0
);
context.closePath();
break;
}
default: {
assertAlways(false, "Unkown sub shape: " + subShape);
}
}
context.fill();
context.stroke();
context.rotate(-rotation);
context.translate(-centerQuadrantX, -centerQuadrantY);
}
}
context.restore();
}
/////////////////////////////////////////////////////
function showError(msg) {
const errorDiv = document.getElementById("error");
errorDiv.classList.toggle("hasError", !!msg);
if (msg) {
errorDiv.innerText = msg;
} else {
errorDiv.innerText = "Shape generated";
}
}
// @ts-ignore
window.generate = () => {
showError(null);
// @ts-ignore
const code = document.getElementById("code").value.trim();
let parsed = null;
try {
parsed = fromShortKey(code);
} catch (ex) {
showError(ex);
return;
}
renderShape(parsed);
};
// @ts-ignore
window.debounce = fn => {
setTimeout(fn, 0);
};
// @ts-ignore
window.addEventListener("load", window.generate);

View File

@ -1,13 +0,0 @@
{
"name": "shape_generator",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"devDependencies": {
"http-server": "^0.12.3"
},
"scripts": {
"serve": "http-server . -p 9000 -g --cors -o -c-1"
}
}

View File

@ -1,152 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
async@^2.6.2:
version "2.6.3"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
dependencies:
lodash "^4.17.14"
basic-auth@^1.0.3:
version "1.1.0"
resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.1.0.tgz#45221ee429f7ee1e5035be3f51533f1cdfd29884"
integrity sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=
colors@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
corser@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87"
integrity sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=
debug@^3.0.0, debug@^3.1.1:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
dependencies:
ms "^2.1.1"
ecstatic@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-3.3.2.tgz#6d1dd49814d00594682c652adb66076a69d46c48"
integrity sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog==
dependencies:
he "^1.1.1"
mime "^1.6.0"
minimist "^1.1.0"
url-join "^2.0.5"
eventemitter3@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb"
integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==
follow-redirects@^1.0.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.11.0.tgz#afa14f08ba12a52963140fe43212658897bc0ecb"
integrity sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==
dependencies:
debug "^3.0.0"
he@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
http-proxy@^1.18.0:
version "1.18.0"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a"
integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==
dependencies:
eventemitter3 "^4.0.0"
follow-redirects "^1.0.0"
requires-port "^1.0.0"
http-server@^0.12.3:
version "0.12.3"
resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.12.3.tgz#ba0471d0ecc425886616cb35c4faf279140a0d37"
integrity sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA==
dependencies:
basic-auth "^1.0.3"
colors "^1.4.0"
corser "^2.0.1"
ecstatic "^3.3.2"
http-proxy "^1.18.0"
minimist "^1.2.5"
opener "^1.5.1"
portfinder "^1.0.25"
secure-compare "3.0.1"
union "~0.5.0"
lodash@^4.17.14:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
mime@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
minimist@^1.1.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
mkdirp@^0.5.1:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
dependencies:
minimist "^1.2.5"
ms@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
opener@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==
portfinder@^1.0.25:
version "1.0.26"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70"
integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==
dependencies:
async "^2.6.2"
debug "^3.1.1"
mkdirp "^0.5.1"
qs@^6.4.0:
version "6.9.4"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
secure-compare@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/secure-compare/-/secure-compare-3.0.1.tgz#f1a0329b308b221fae37b9974f3d578d0ca999e3"
integrity sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=
union@~0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/union/-/union-0.5.0.tgz#b2c11be84f60538537b846edb9ba266ba0090075"
integrity sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==
dependencies:
qs "^6.4.0"
url-join@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728"
integrity sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=