Skip to content

Instantly share code, notes, and snippets.

@park-brian
Last active January 30, 2021 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save park-brian/913be75f4ee1b7730c9d3f487879f598 to your computer and use it in GitHub Desktop.
Save park-brian/913be75f4ee1b7730c9d3f487879f598 to your computer and use it in GitHub Desktop.
RWS Editor Test 2
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GistRun</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<input id="height" placeholder="Height">
<input id="width" placeholder="Width">
<button id="load">Load</button>
<button id="save">Save</button>
<textarea id="input" style="width: 100%" rows="20">7Z3LzTy3DcABH9NGrm7AJbiOHF1BKvDFp1RgwDX44lYMGB+QGpxjnCwEgZRESqTEx8zumPD/26dE8idSz5n9619/Ocr3/y3/fv/f
f/xhI68SX+XVv36aQw2c/jv1g+7wuH3vJd/9gEVfT/0GVZ6n13otrJiDyPyusxE+C0RmzE/aX/+NWk5L/LsfSkvXlt1KyzyGOvab
ZdxX6jMrdMxxhNTX1u3Pgnmt9VV2yxzatq6WbOqgAbbNNvJX9He15tsatuy87r6mwnvMKrv6V+a2HtLpQnmzbd8n/G1aM8+8/ZSm
RP4dWVY70f67H6xJav3J8bahznlBqyXFfa89zduiJPudMv/HHx4k9/Tpee8xb6nzXj/TdTeDrPKPrMfTjk/aMvMye9GH4mwX6XOv
t5+D3rjtpUceu31GO9egW6Z0lCPVoX7uvLXa8G7HkrbMZxm8j9fR9zBeb0fx0tnh3OoZOx/mFhnKivma+A71dW7nmPfj8FH0Xhvn
4FQL1REHve/GXEZ8h3nxLG0d5fORep+FeU4Sn/O147J0c9d5q27r17eVezEHShbM57VomVNlQk+kXa/g+bX2tGthJb/mUPdjTnkb
hPfdLLJnNa2Zw6hg1kZ3hLLxz9+g1vK4tzNrXcaHeT8eGmu187qU+TlZjRZQ04v36/++fVTPU6v9Y1lxzG08QPuDo66va+4RnD+8
iI/MS2T/+VvPHGtbmbd9WdsfWPDue5+aY+x4Ux6QMd+vTbYG8PqkB+9Rh5rPC/OXtHkGM8fkKbEhjusojy15r5lXXXjvaXPwapTo
Fd2j1rhNv4jD+zvMT3m36y98fFtEuUzb2aqMjnqfufwZc8xhlFhivLxb/7Yke+Z4B9mqF5eP106Ya3TF/Sx+FayWU88kXuuvteMI
L9ldxtxe5MRPRm/a/aZ1i5DWm8G6ZU63uZY5zcMql48+jGBurbN85TuLN+Y5a3m9b1qP9/2Tlfe8mVu3VXn0ZhOv1tPaljjXMbcZ
sfvmdrux5kj9Hsw5Kbl99Ezvc8gTMI63iBgv6pbzi1H3bGrn1Cm/jD5vGZ17UxfnGuZeY0458/zenCZddCtrMhLmVOSfec46u3vG
to75lXJ7bX91j6UQ32N+Mp7X5nV5nPvvC10zhqXeqSuvlGUyDpHMpZHuzbzon01PKyWvl7Hbi/wu830P63nL4jxq9/euzKuPTpj3
npCua/sQj4zz+1EHD3E+Wkd4ZJSf22NPPZvePnHOS2ve4z7EZzG/H3WanJQ55wUf6jqrYphXi+/EvtLmqO8Q94p1nV1xzMGWbJoa
5nyka5lr9140czVtO36oSzwlZ86vv+k87rHW7sv8a/puNkWZf8BLWua8X3N79Jgo/yL43yPO4aSt1Riu2C6doXvspcLZLXvKPG9v
5rZl783PbaLJYyfVnzlvjTXnVmxL5aywJk7VZsu8lu+T4bkI96COZ1SW3HeZS/dQMQFujgCRvqKv8ZWPfC3I22fgNmNpqHOf3Wcu
udfMSHqsrWZ3ePeUuSf1L0Tdnznud/FfC+a8jWf9OeaMqbafwCW239hl7rUm89VE+MjdfjVuzJOaM7erUs+Yc6VgenPicPYC7Nwl
7kP9q4nyL5K5PXFKbMrVMh/pcSX0Md4z7+82it+9FnPg/kUSlzOnyNEs7UdwuGSOuaRPnjPv83ZLvOWO51ktc71N9rz/aoifrMhI
4xde9+g3OGKnnmr7IWCOn+H8j9+7GnOgfR7luB/DVlM24FZhFe98nNutu8yYUyP8k7w+t+mUOZ3ZNSRwa+fLoOY3tn26rX9abXv6
8Iy36SzK7a9fAc7l0an3cRxgL3DM8TWxNnG+5uXbGjB1/HiXOD4ZYEkd5NznVKsEnvN9S4s4z2DeZzcu0q1tOtf71N+V+YzprP7r
5/aVB1vpZ+1XI27H/Mxj78C8XZM5I+5rUS5zq/78rN1ZUce9+QnvytzLIt+Z0rp2uzXeazCvr5zeI8qPue/4KU6H3OxOzVjs9ok9
dH0X5tGc11ad2mU9QwfdzvU69c2OJ7BPXs/y6M5tO/GvH/Mz6hnEqdWPLK5rC0+Jvxdz/T7OeMYqk6e9lRHET3P7aZTv+eA+vHd9
PM4EcvVpNYuqe1zXzCLo72XKUkt7z5jv16qr+97E9ywt3/Ox+GSUsVujbkSL1zpsrI9uM9Izf71+fq18fwd1rzZtprO2NjJX1BGI
JLo5NuV/e82uyNxrnlIk9nda5jb3q3hYVz9PXI+5H3HqjKq/zH8/gdP1k5h7zVJqhMePBNtTQ0B7ronXGG5/XWZHk1VtfixwVve7
gz9fO+YstdNjFKcdQ5/zmdXnzaFdw4tnXmlrLLXVFnqLPeL7jDjqcWPpDOYgeuZ2WuyyPqc01h3PILI26oRkbP2gRxb1PtLvuLqm
t5g6RxWtxTnxl+z7ICvGM6RdTYzryXotbJifr8J+CnPvObdEi2zmnyT99Xk5bT2f+SfEN7a178+iqdte/y23O8fj2dLP0zI8EXX9
d2t1dD9wlRZ2jXlaNHOqJytzF3vLcI0ZvqVt97JXroUt8UpyZrP001b+LTVmebj3dn4L9GBO3VcAHlEtxG/nzI757///71wjX5ul
engwb+85kcMcr3fZMD/V5bWDN+a3O8/SVvz7GUpvu491bZzv1/T772dxTl2fmjWai2DeWhdHvGV+tk/uwRzfNSuOORV33tTjiIOV
hXn86Qisw+rOA/SpKA9NopjjcyGxxKuVmcxld5ugtLPO+pHEi03rlu3j8VdtWcwLNdndwiL0iyQ+2hfl71JfHnH5XZ05Da91Omaf
uD+BtjfJmBPTxPXMLfXJJR7DHOr0rY2un76X9Mwz3hrlMvf3OLbRtza6du7+4VmeyWMekWPHeaF3jW3tHO0z5uctIot6xCrMaJtf
naMOu8Tn3rFasaPWSXCLuy/xyDhvOcyJr5lzY3fb03O9r/D6f/yZCktLWub2VzNDrfX5rB+XMudWZ+atYtdb2AJ49V7Mab1tR0ct
mbadreJc9nt6VH32PuSZW3LP2kuwYk7lRA1vGXPqDAKO9AjvWTGP3DG038/huGqZ62O9Zx61U3Fv5udrr1qqp9S5SPedw898KKec
s0c8Mj+9n4Q+ls+4t/7qxw5RntTzhjlfnJ61fVLMT/yl77fPyPdxPj6K8KQ2vqn5X4Se1AgEPLyriR9zjnoc25nNWtLYW7l6tsx3
tNkZoVtGeo5gm2vu7vsf7qxH9hm/lvgp9Zg4j/ac3H7QjD7TdY1RR8/8xG5r4utdl+uQH3Wh14/yo7wyt5ivRRLHGfQuAqP2uBq9
mUdl9j7Wozx46v/rxDn8krWFVZHEr0Z9pQvN/Ndvf/3WT6M587Oyy7+xUX6tnn2tBYzw8WdezL24r3K7hb05zIG9F0+dFzSnOyrx
WOo2ce5B/W7MYZ1zpQnN3Is6dS3k+0S6h880PtC2vpZ4HPVKynoU9/O/f/53NPXMPn1nhzqCOMX8bAWOKr+0oBf1jPyutcLGciqS
1uVWzt5R3lPHzG2o58X5ztzt1O7Wn9SdOymW7Wu+cT6e7inMa3Y/tx94WTD3zO79CvmuxbhurMmv375ekbD0JQ620nF+4oHCG0jH
M98hvtsjjMxBatwW8mvenrQ5e4vNK+rz9lBi3IbzHnNNawU763dnZMdvYaFoV+ZXmEGONlDk+tclrcGadWScy9hAjNB3helH4dJy
swVm6/g8/Dz3exL3Yw4Ue+pcu6br42K8Rvn1mePZFsy6CmdoDe2ZGk/i+jHcPvPZuTXp+bd7M18JeMWTeCzz9u4+XJ8tpx41PrOh
LiV5LeJa5nQJ1N3E35155d7m9Dsw18+41iVqmffks0nqqeeKb5TLeulT5vfjfi/qO2vtklLbvyvaI/M7Uc+P9bg4t7raFDP/6Z/3
o55NXEv9JM6pKxP2mb/kp3++5F7M86NcH+l6C/vVODvmhfq9It2KeZ0DRDDf2z3fGaXJqN+LuBVzvKJ5PeZVN2np60/itfb7MT/v
z9uVx566rBVome9ebycpWZYRcJwD9WyWUcQp3+LWIKGuYw7U9adlxlhe751KiZfzE9lEZX6wZT7u1fow53d9eUspruNui4Q53Z/f
g/kZdW5HsqexqoNn296nkY5MHXOaf7u/NmeO99TwmP3FPJumzBNnUS71Oc74Uuo1GjlC8K6Ud98O62tja+Cjelx/o5nvtEt/2lis
8vpZbVz+xveT2Wcu6f/p3pxmPtKn9bzODnt7lYOevN6ONqogT9Tn9e+s1+Yz8qpmuY50LpfEOV/OFZjTHpNT32253NkkOgdYMdd6
pc023Gx8xpw+n+NNVWId9bq8H7f29qjB7FqRndmaXBc8bmy54rXWdt21j/R+LJp/HTX3joa51o7ZFbyUDjkjINwLQ5xXxrCrgvdX
6t82I/W9VKwdo1XcO3Lm2hwvtxv377H+GnuOPsZpoVfi2llHjAVQd28X/0nNOA74U77DNbfjNInGsii3uuaSFwlxoE6VbEVRqn3x
SlvzTIvdWdv8+gj9uEv26XOP4jEbjOCgVlmUA3N5dNnwptc0KPFn3vf6p9T3fTe3Fl+3Ao/0xIG5NLrOreFXC2vP21KwZd6uz0CN
dU+djnuJhbJ2uu9BGFePcyo98XLFYq+xbDVoV3dO1v2vFfPab8/7feh1LJif+60fYQPxFeuXcJHW22GnNe6RJMypXHzKHOJXnv/X
vZ00yul3115ue+92vWxNHGcBmjnkNNvZmuz0xzwXnzOH7C1nrvHBfBTHM1+3FizjjFxGnGIOGcMyV8kinGfOeWqPeSlz9X6v/6kP
+DXk1fhv/AR+pmXOR7pmf0diq4Q2x5zu1+eReir9WttuBFCr7yNPvnfF8dKzL99bMafW2jnmVu1ZR5xmTkeeL3OQ8ZUdH43f4jwz
zwPwuXFtXUJ8pG1BvW2XGt5z5lgv/5PuLfGZLjq/lEfzWMB2cswlxFejN6B+2ovvkF4zp2LPn7msBWr8QscszYKSnrhsLs4zhytm
TrO7B/O4+wrUurh3dn8rBjKpzidcjNdTMavZeMu8zee7fZU1c45rDPNa/oz53kmM/QxI9+T4E/PVF/xZTNmKOH2/BDlz6PWimLfl
rudxu3466/VkzGXtp9cqlzl9IsG3N9eXvesjP+a7PrZZfTizqy2pz6YeWR1HrTdzK+pnYs381KZeG3vGFPOxnXlSz+Vun9ttmfsT
7+NczvyesU4RzmVO721HMNePEH2Z66+MkzMf9TldkbFqhVEz8Z6+7uT8nqfmXoIarEi3czVan92ZyGnWGtedIpnrx4m7czYZcUvq
rYf7CK+rNHridjplMT9pKRbMx7I9meMVOT1zu7HoHZlXOjKf8bZz5XpQp7LyOLbbz1b7xO9Everf5kw58flegzV37vU+53sTx8z1
I6p8ARtaeyyY71PXrdj1GYCmbzvbbDnfifq6HWvPf1qSt+Bi3Y9ju8ezKdk8Y2hE16enbjE3m9kNGSWa+o+/ZBCnqFOvWdXpQc/C
ajyTrK9cjbmf9eMrJ7qMZy2vwrzvy6EPgdeuxNza/r5kre68X3vKVyHeXrPGnz99X+Yt9R3tZ8SvE9tYM5zHKcLXGtN5eMFep37V
IJszrVke4R9/qfIuzOlZ1tfRaSY/4hmiYe7jCXvmPispVsyziWuY+/nCljmcQ6nMrxDjlXk+cY75uDrk6Qtr5pBDsymPeuGZ2pWY
j9fke4+EPKhfa/SGVwiymRfu7XPuqsG7MS+Pr5HZa18eyZzqs1/PcZzX9/kTZF7cT62jfZzNudUHepvrMefueOC1y2TjhWymMuaF
ei5zLOX5+nyr707Te1OPHbePzIFz/96cuc94GLN7T+rxO+UjWZ75OtI9fNIyez/mQD6K+aottGM4WDGixnNxHnpP6jl82z58tibj
fTZsLe/H/arMWy+2qzRX91E2Uxt7LMoYiff8eWmvBLmmj+5D3UrXPebSPRbcv9+B+bW52+kopd6P22T7arpdF1sGe8yvS91Sw13f
SM9G9bPLHS0i7boqd1vddnhrzsnwHtV+i6ZC9xsPc1vqZ8wtBHjz4wVP5vHtw762uzGvv9U2mxeclS731V2Z63x0BeaSNR975vpv
WNLxKvcezMerwCOY733rYW5DnLqrUzzz8VVP5n4lX585tYfTxnod1dky5z8TwdxP7sCcP5UDvE93HynPREX0dblnyuwXWc5PhHP+
6B+/k2QTPaWuuyvtSHx8xLeH95FsohLms3O2nmfIstl8LnOKe//buP5nS7I5fSZ1erYWd24wm9PnkedOZUSeGcxm9GnU+7uqZGic
TejTqMf9ktxMsgl9GvNrXJ2dzeizuOfzLjJ6K5vZO1O/ioyeymb2cJdzO/nu/dbk1/c2zqbiK2dWUt/NJmrB/L25n9lIfy+bqZVk
s/ETewuzWT3UpYysy3sHySbjKw/zh/lJSe8j2VR8xcq+bEoP82jJZvQwj5dsRg/zaMkm9DCPlmw+D/NIySbzUI+VbCYP83jJZvIw
j5ZsIg/1eMnm8TCPlmwaD/F4yebxMI+XbB7RzP/8rZdsAg9zP+L/+RuWT6aeTSSS+Td//+bv9d/PJf4JzCt1Ls6zCTzM/ZiPPfmn
Mv8E6sVOOs6zvf8w96Te9+fZfn+YRzBv4zzb7w9zf+r9iD3b7w/zCObjzPxTyWfTiJJxZv5Qf3eh4/xh/s7yzM8/jzrH/KH+7vIQ
/0TqRbK9fQ3JpvBQjxcfz/4P</textarea>
<fieldset>
<legend>Roofs</legend>
<label><input type="radio" name="cellType" onchange="window.cellType = event.target.value" value="0">NONE</input></label>
<label><input type="radio" name="cellType" onchange="window.cellType = event.target.value" value="5133">CONSTRUCTED_ROOF</input></label>
<label><input type="radio" name="cellType" onchange="window.cellType = event.target.value" value="6699">THIN_ROCK_ROOF</input></label>
<label><input type="radio" name="cellType" onchange="window.cellType = event.target.value" value="10820">MOUNTAIN_ROOF</input></label>
</fieldset>
<fieldset>
<legend>Terrains</legend>
<label><input type="radio" name="cellType" onchange="window.cellType = event.target.value" value="37631">NONE</input></label>
<label><input type="radio" name="cellType" onchange="window.cellType = event.target.value" value="27449">MARBLE</input></label>
<label><input type="radio" name="cellType" onchange="window.cellType = event.target.value" value="56931">SANDSTONE</input></label>
</fieldset>
<canvas id="edit" width="400" height="400"></canvas>
<textarea id="output" style="width: 100%" rows="20" readonly></textarea>
<script src="https://cdn.jsdelivr.net/npm/pako@1.0.10/dist/pako.min.js"></script>
<script src="script.js"></script>
</body>
</html>
var heightInput = document.querySelector('#height');
var widthInput = document.querySelector('#width');
var loadButton = document.querySelector('#load');
var saveButton = document.querySelector('#save');
var inputTextArea = document.querySelector('#input');
var editCanvas = document.querySelector('#edit');
var outputTextArea = document.querySelector('#output');
var brushActive = false;
var cellType = 0;
/**
* Inflates a deflated base64 string as an ArrayBuffer
* @param {string} base64 - A base64 string
* @returns {ArrayBuffer} - Inflated data
*/
function loadDeflatedBase64(base64) {
base64 = base64.replace(/\n/g, '');
return pako.inflateRaw(atob(base64)).buffer;
}
/**
* Deflates an ArrayBuffer as a base64 string
* Returns base64 encoded lines, suitable for saving
*/
function saveAsDeflatedBase64(arrayBuffer, lineWidth) {
var uInt8Array = new Uint8Array(arrayBuffer);
var data = btoa(pako.deflateRaw(uInt8Array, {to: 'string'}));
return chunk(data, lineWidth || 100).join('\n');
}
/**
* Splits an array-like object (eg: strings, buffers)
* into chunks of the specified length
*/
function chunk(array, size) {
var parts = [];
for (var i = 0; i < array.length; i += size)
parts.push(array.slice(i, i + size))
return parts;
}
function drawEditor(arrayBuffer, width, height) {
var cells = new Uint16Array(arrayBuffer);
var ctx = editCanvas.getContext('2d');
// do not proceed if the data does not match the dimensions provided
if (cells.length != (width * height)) return;
var cellSize = 8;
var cellDefs = {
0: {
type: 'NONE',
color: '#fff',
},
5133: {
type: 'CONSTRUCTED_ROOF',
color: '#ddd',
},
6699: {
type: 'THIN_ROCK_ROOF',
color: '#666',
},
10820: {
type: 'MOUNTAIN_ROOF',
color: '#222',
},
37631: {
type: 'NONE',
color: '#fff',
},
27449: {
type: 'MARBLE',
color: '#eee',
},
56931: {
type: 'SANDSTONE',
color: '#ddd',
},
};
renderCells(cells, width, height);
editCanvas.onmousedown = function() {
brushActive = true;
}
editCanvas.onmouseup = function() {
brushActive = false;
}
editCanvas.onmouseleave = function() {
brushActive = false;
}
editCanvas.onmousemove = function(event) {
var canvas = event.target;
var x = Math.floor((event.pageX - canvas.offsetLeft) / cellSize);
var y = height - Math.floor((event.pageY - canvas.offsetTop) / cellSize);
var index = y * width + x;
console.log(x, y, cells[index], getColor(cells[index]));
if (!brushActive) return false;
var cell = cells[index];
var cellTypes = Object.keys(cellDefs);
cells[index] = cellType;
renderCell(cells, width, height, x, y);
}
function renderCells(cells, width, height) {
editCanvas.width = cellSize * width;
editCanvas.height = cellSize * height;
for (var y = 0; y < height; y ++) {
for (var x = 0; x < width; x ++) {
renderCell(cells, width, height, x, y)
}
}
}
function renderCell(cells, width, height, x, y) {
// ctx.fillStyle = cellDefs[cells[y * width + x]].color;
var value = cells[y * width + x];
var color = getColor(value);
ctx.fillStyle = color;
ctx.fillRect(x * cellSize, (height - y) * cellSize, cellSize, cellSize);
}
function getColor(value) {
this.colors = this.colors || {};
var randomValue = Math.floor(Math.random() * 255);
if (cellDefs[value])
this.colors[value] = cellDefs[value].color;
if (!this.colors[value]) {
this.colors[value] = `rgb(${randomValue}, ${randomValue}, ${randomValue})`;
console.log(value, this.colors[value])
}
return this.colors[value]
}
}
loadButton.onclick = function() {
var height = +heightInput.value || 250;
var width = +widthInput.value || 250;
var arrayBuffer = loadDeflatedBase64(inputTextArea.value);
drawEditor(arrayBuffer, width, height);
saveButton.onclick = function() {
var output = saveAsDeflatedBase64(arrayBuffer);
outputTextArea.value = output;
}
}
canvas {
border: 1px solid #ddd;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment