Files
easy-png-tools/web/src/lib/core/gen-tools.ts
T

107 lines
3.0 KiB
TypeScript

import { createPixelImage, type PixelImage } from './types';
import { hslToRgb } from './palette';
import { mulberry32 } from './pixel-fx';
/** Радужный спектр: оттенок 0..360 вдоль выбранной оси. */
export function colorSpectrum(
width: number,
height: number,
direction: 'horizontal' | 'vertical',
saturationPercent: number,
lightnessPercent: number
): PixelImage {
const out = createPixelImage(width, height);
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const t = direction === 'vertical' ? y / Math.max(1, height - 1) : x / Math.max(1, width - 1);
const { r, g, b } = hslToRgb({
h: t * 360,
s: saturationPercent / 100,
l: lightnessPercent / 100
});
const di = (y * width + x) * 4;
out.data[di] = r;
out.data[di + 1] = g;
out.data[di + 2] = b;
out.data[di + 3] = 255;
}
}
return out;
}
/** Случайные яркие блоки: детерминировано по seed. */
export function randomColorBlocks(
width: number,
height: number,
blockSize: number,
seed: number
): PixelImage {
const bs = Math.max(1, Math.round(blockSize));
const out = createPixelImage(width, height);
const rng = mulberry32(seed);
for (let by = 0; by < height; by += bs) {
for (let bx = 0; bx < width; bx += bs) {
const { r, g, b } = hslToRgb({
h: rng() * 360,
s: 0.65 + rng() * 0.35,
l: 0.45 + rng() * 0.25
});
const yMax = Math.min(by + bs, height);
const xMax = Math.min(bx + bs, width);
for (let y = by; y < yMax; y++) {
for (let x = bx; x < xMax; x++) {
const di = (y * width + x) * 4;
out.data[di] = r;
out.data[di + 1] = g;
out.data[di + 2] = b;
out.data[di + 3] = 255;
}
}
}
}
return out;
}
function lineMask(length: number, divisions: number, lineWidth: number): Uint8Array {
const mask = new Uint8Array(length);
const lw = Math.max(1, Math.round(lineWidth));
for (let i = 0; i <= divisions; i++) {
const start = Math.round((i * length) / divisions);
for (let x = start; x < Math.min(start + lw, length); x++) mask[x] = 1;
}
return mask;
}
/** Сетка линий на прозрачном или белом фоне. */
export function drawGrid(
width: number,
height: number,
cols: number,
rows: number,
lineWidth: number,
colorHex: string,
transparentBg: boolean
): PixelImage {
const out = createPixelImage(width, height);
if (!transparentBg) out.data.fill(255);
const m = /^#([0-9a-f]{6})$/i.exec(colorHex.trim());
const r = m ? parseInt(m[1].slice(0, 2), 16) : 0;
const g = m ? parseInt(m[1].slice(2, 4), 16) : 0;
const b = m ? parseInt(m[1].slice(4, 6), 16) : 0;
const colMask = lineMask(width, Math.max(1, cols), lineWidth);
const rowMask = lineMask(height, Math.max(1, rows), lineWidth);
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
if (!colMask[x] && !rowMask[y]) continue;
const di = (y * width + x) * 4;
out.data[di] = r;
out.data[di + 1] = g;
out.data[di + 2] = b;
out.data[di + 3] = 255;
}
}
return out;
}