auth

Main authentication module for my projects
git clone git://git.finwo.net/app/auth
Log | Files | Refs

generate-hex-grid.js (2781B)


      1 import fs from 'node:fs';
      2 import path from 'node:path';
      3 import { fileURLToPath } from 'node:url';
      4 
      5 const SETTINGS = {
      6   width: 1024,
      7   height: 576,
      8   amount: 20,
      9   density: 1,
     10   strokeWidth: 0.5,
     11   baseWidth: 512,
     12   randomFillOpacity: true,
     13   light: {
     14     back: '#FFF',
     15     front: '#DDD',
     16   },
     17   dark: {
     18     back: '#000',
     19     front: '#222',
     20   },
     21 };
     22 
     23 const here = path.dirname(fileURLToPath(import.meta.url));
     24 const assets = path.resolve(here, '../web/src/assets');
     25 
     26 function randomAt(column, row) {
     27   let value = Math.imul(column + 1000, 374761393) + Math.imul(row + 1000, 668265263);
     28   value = Math.imul(value ^ (value >>> 13), 1274126177);
     29   return ((value ^ (value >>> 16)) >>> 0) / 4294967295;
     30 }
     31 
     32 function hexPath(cx, cy, radius, halfWidth) {
     33   const halfHeight = radius / 2;
     34   const points = [
     35     [cx, cy - radius],
     36     [cx + halfWidth, cy - halfHeight],
     37     [cx + halfWidth, cy + halfHeight],
     38     [cx, cy + radius],
     39     [cx - halfWidth, cy + halfHeight],
     40     [cx - halfWidth, cy - halfHeight],
     41   ].map(([x, y]) => `${Number(x.toFixed(3))} ${Number(y.toFixed(3))}`);
     42   return `M ${points[0]} L ${points[1]} L ${points[2]} L ${points[3]} L ${points[4]} L ${points[5]} Z`;
     43 }
     44 
     45 function buildSvg({ front, back }) {
     46   const { width, height, amount, density, strokeWidth, baseWidth } = SETTINGS;
     47   const spacing = width / amount;
     48   const radius = (spacing / Math.sqrt(3)) * density;
     49   const verticalSpacing = 1.5 * radius;
     50   const stroke = strokeWidth * (width / baseWidth);
     51   const rows = Math.ceil(height / verticalSpacing) + 1;
     52 
     53   const paths = [];
     54   for (let row = -1; row <= rows; row += 1) {
     55     const parity = ((row % 2) + 2) % 2;
     56     const cy = radius + verticalSpacing * row;
     57     for (let column = 0; column <= amount; column += 1) {
     58       const cx = parity * (spacing / 2) + spacing * column;
     59       const random = randomAt(column, row);
     60       const opacity = !SETTINGS.randomFillOpacity
     61         ? 1
     62         : random >= 0.45
     63           ? Number((random ** 2).toFixed(2))
     64           : 0;
     65       const fill = opacity > 0 ? ` fill="${front}" fill-opacity="${opacity}"` : ' fill="none"';
     66       paths.push(
     67         `<path stroke="${front}" stroke-width="${Number(stroke.toFixed(4))}"${fill} d="${hexPath(
     68           cx,
     69           cy,
     70           radius,
     71           spacing / 2
     72         )}"/>`
     73       );
     74     }
     75   }
     76 
     77   return [
     78     `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">`,
     79     `<rect width="100%" height="100%" fill="${back}"/>`,
     80     ...paths,
     81     '</svg>',
     82     '',
     83   ].join('\n');
     84 }
     85 
     86 fs.writeFileSync(path.join(assets, 'hex-grid-light.svg'), buildSvg(SETTINGS.light));
     87 fs.writeFileSync(path.join(assets, 'hex-grid-dark.svg'), buildSvg(SETTINGS.dark));
     88 
     89 console.log('wrote hex-grid-light.svg and hex-grid-dark.svg');