162 lines
4.1 KiB
JavaScript
162 lines
4.1 KiB
JavaScript
import { createNoise2D } from "simplex-noise";
|
|
import { createCanvas, ImageData } from "canvas";
|
|
import alea from "alea";
|
|
|
|
const SEED = "runtimefee.lol";
|
|
var log_once = false;
|
|
|
|
/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */
|
|
export default function (eleventyConfig) {
|
|
// Directory configs
|
|
eleventyConfig.setInputDirectory("content");
|
|
eleventyConfig.setIncludesDirectory("../_includes"); // relative to the input directory, therefore the ../
|
|
eleventyConfig.setDataDirectory("../_data"); // relative to the input directory, therefore the ../
|
|
eleventyConfig.setOutputDirectory("_site");
|
|
|
|
eleventyConfig.setFrontMatterParsingOptions({
|
|
excerpt: true,
|
|
// Optional, default is "---"
|
|
excerpt_separator: "<!-- excerpt -->",
|
|
});
|
|
|
|
// Custom date filter
|
|
eleventyConfig.addFilter("date", (dateObj) => {
|
|
return new Intl.DateTimeFormat("de-DE", {
|
|
day: "numeric",
|
|
month: "long",
|
|
year: "numeric",
|
|
}).format(dateObj);
|
|
});
|
|
|
|
eleventyConfig.addFilter("capitalize", function (value) {
|
|
return value.toUpperCase();
|
|
});
|
|
|
|
// generate a nice preview image for articles that don't have one
|
|
eleventyConfig.addShortcode("generateThumbnail", function (hash) {
|
|
return getThumbnailImage(hash);
|
|
});
|
|
|
|
// Collections
|
|
eleventyConfig.addCollection("posts", (collectionApi) => {
|
|
return collectionApi.getFilteredByTag("posts");
|
|
});
|
|
|
|
eleventyConfig.addPassthroughCopy({ "public/": "/" });
|
|
}
|
|
|
|
function getRandomFloat(min, max) {
|
|
return parseFloat((Math.random() * (max - min) + min).toFixed(2));
|
|
}
|
|
|
|
function getRandomPaletteValues() {
|
|
// Generate random arrays for a, b, c, and d
|
|
const a = [
|
|
getRandomFloat(0.5, 1.0),
|
|
getRandomFloat(0.5, 1.0),
|
|
getRandomFloat(0.5, 1.0),
|
|
];
|
|
const b = [
|
|
getRandomFloat(0.2, 0.8),
|
|
getRandomFloat(0.2, 0.8),
|
|
getRandomFloat(0.2, 0.8),
|
|
];
|
|
const c = [
|
|
getRandomFloat(0.0, 2.0),
|
|
getRandomFloat(0.0, 2.0),
|
|
getRandomFloat(0.0, 2.0),
|
|
];
|
|
const d = [
|
|
getRandomFloat(0.0, 1.0),
|
|
getRandomFloat(0.0, 1.0),
|
|
getRandomFloat(0.0, 1.0),
|
|
];
|
|
|
|
if (log_once == false) {
|
|
log_once = true;
|
|
//console.log({ a, b, c, d });
|
|
}
|
|
|
|
return { a, b, c, d };
|
|
}
|
|
|
|
function getPalette(t, a, b, c, d) {
|
|
const result = [];
|
|
|
|
for (let i = 0; i < 3; i++) {
|
|
// Apply the formula element-wise to each component of the vectors
|
|
result[i] =
|
|
255 * (a[i] + b[i] * Math.cos(2.0 * Math.PI * (c[i] * t + d[i])));
|
|
}
|
|
|
|
if (log_once == false) {
|
|
log_once = true;
|
|
//console.log(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function getThumbnailImage(hash) {
|
|
var width = 400;
|
|
var height = 400;
|
|
var rng = alea(SEED + hash);
|
|
|
|
var noise2D = createNoise2D(rng);
|
|
|
|
const canvas = createCanvas(width, height);
|
|
const ctx = canvas.getContext("2d");
|
|
const imageData = ctx.createImageData(width, height);
|
|
const paletteSettings = getRandomPaletteValues();
|
|
|
|
var dist = 0;
|
|
for (let x = 0; x < width; x++) {
|
|
for (let y = 0; y < height; y++) {
|
|
const value = noise2D(x / 50, y / 50);
|
|
var threshold = Math.floor((value + 1) * 128);
|
|
threshold = value > 0.2 ? 128 : 0;
|
|
|
|
const index = (x + y * width) * 4;
|
|
|
|
const dx = x - width / 2;
|
|
const dy = y - height / 2;
|
|
const distance = Math.sqrt(dx * dx + dy * dy); // Euclidean distance
|
|
|
|
// Normalize the distance to be between 0 and 1 (for a radial gradient effect)
|
|
const maxDistance = Math.sqrt(
|
|
((width / 2) * width) / 2 + ((height / 2) * height) / 2
|
|
);
|
|
|
|
const t = (distance / maxDistance) * 3.0 * Math.sin(dist);
|
|
dist += 0.00001;
|
|
|
|
const a = [0.5, 0.5, 0.5];
|
|
const b = [0.5, 0.5, 0.5];
|
|
const c = [1.0, 1.0, 1.0];
|
|
const d = [0.0, 0.1, 0.2];
|
|
|
|
const palette = getPalette(
|
|
t,
|
|
paletteSettings.a,
|
|
paletteSettings.b,
|
|
paletteSettings.c,
|
|
paletteSettings.d
|
|
);
|
|
|
|
if (threshold == 0) {
|
|
imageData.data[index] = palette[0] * 0.05; // Red
|
|
imageData.data[index + 1] = palette[1] * 0.09; // Green
|
|
imageData.data[index + 2] = palette[2] * 0.3; // Blue
|
|
imageData.data[index + 3] = 255; // Alpha
|
|
} else {
|
|
imageData.data[index] = palette[0]; // Red
|
|
imageData.data[index + 1] = palette[1]; // Green
|
|
imageData.data[index + 2] = palette[2]; // Blue
|
|
imageData.data[index + 3] = 255; // Alpha
|
|
}
|
|
}
|
|
}
|
|
|
|
ctx.putImageData(imageData, 0, 0);
|
|
return canvas.toDataURL("image/jpeg");
|
|
}
|