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: "", }); // 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 = 800; var height = 300; 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"); }