Skip to content

Instantly share code, notes, and snippets.

@diauweb
Created June 27, 2023 08:21
Show Gist options
  • Save diauweb/c9dcc89e39a48f16c93f6a3c7e082981 to your computer and use it in GitHub Desktop.
Save diauweb/c9dcc89e39a48f16c93f6a3c7e082981 to your computer and use it in GitHub Desktop.
Map area painter for some anime game
import { loadImage, createCanvas } from 'canvas'
import fs from 'fs'
const fse = fs.promises;
console.time('paint')
const posFile = JSON.parse((await fse.readFile('./scene3_worldArea.json')).toString());
const img = await loadImage('./Teyvat_Map_3.4.png')
const blockSize = 1024;
const offset = [0, 0];
const expand = [0, 0];
const center = [7 * blockSize + offset[0], 4 * blockSize + offset[1]];
const mapSize = [img.width + offset[0] + expand[0], img.height + offset[1] + expand[1]];
const canvas = createCanvas(mapSize[0], mapSize[1]);
const ctx = canvas.getContext('2d')
ctx.drawImage(img, offset[0], offset[1])
function xy(pos) {
return [center[0] - pos[2], center[1] - pos[0]];
}
function drawPolygonShape(pos, color = 'red', width = 8) {
// const color = generateLightColorHex();
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = width;
ctx.moveTo(...xy(pos[0]));
for (const point of pos) {
ctx.lineTo(...xy(point));
ctx.stroke();
}
ctx.lineTo(...xy(pos[0]));
ctx.stroke();
ctx.closePath();
for (const point of pos) {
ctx.beginPath();
// const colorIndex = Math.round(((point[1] - minH) / (maxH - minH)) * 100)
// ctx.fillStyle = colors[colorIndex]
ctx.strokeStyle = color;
ctx.fillStyle = '';
ctx.arc(center[0] - point[2], center[1] - point[0], width + 0.5, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
}
}
function generateLightColorHex() {
let color = "#";
for (let i = 0; i < 3; i++)
color += ("0" + Math.floor(((1 + Math.random()) * Math.pow(16, 2)) / 2).toString(16)).slice(-2);
return color;
}
posFile.level1Areas.forEach(e => {
const level1Area = e.level1Area;
const level2Areas = e.level2Areas ?? [];
const pos1 = level1Area.polygonData.roadPoints.map(o => [o.x, 0, o.z]);
level2Areas.forEach(e => {
const pos2 = e.polygonData.roadPoints.map(o => [o.x, 0, o.z]);
drawPolygonShape(pos2, 'blue', 6);
})
drawPolygonShape(pos1, 'red');
});
const out = fs.createWriteStream('./out.png')
const stream = canvas.createPNGStream()
stream.pipe(out)
await new Promise(resolve => out.on('finish', () => resolve()));
console.timeEnd('paint')
{
"name": "map",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"canvas": "^2.10.1",
"colormap": "^2.3.2"
},
"type": "module"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment