Final clean up
Some checks failed
Check & deploy / build (pull_request) Failing after 1m16s

This commit is contained in:
Andras Schmelczer 2026-05-24 10:52:20 +01:00
commit c40c5d97db
74 changed files with 863 additions and 669 deletions

View file

@ -1,4 +1,4 @@
import { appConfig } from '../config';
import { appConfig, type GardenAppConfig } from '../config';
import { AGENT_FLOAT_COUNT, writeAgentValues } from '../pipelines/agents/agent-limits';
import { clamp, easeOutQuad, mix, mixAngle, smoothstep } from '../utils/math';
@ -18,8 +18,11 @@ interface IntroTitleAgentOptions {
}
type RandomSource = () => number;
type IntroPathEasing = GardenAppConfig['simulation']['intro']['pathEasing'];
const INTRO_TITLE = appConfig.simulation.intro.title;
const isLinearPathEasing = (pathEasing: IntroPathEasing): boolean =>
pathEasing === 'linear';
export const createIntroTitleAgents = ({
count,
@ -169,16 +172,22 @@ const createIntroTitlePoints = (
width: number,
height: number
): Array<IntroTitlePoint> => {
const safeMaxPixels = Math.max(1, appConfig.simulation.intro.maskMaxPixels);
const maskScale = Math.min(1, Math.sqrt(safeMaxPixels / Math.max(1, width * height)));
const maskWidth = Math.max(1, Math.round(width * maskScale));
const maskHeight = Math.max(1, Math.round(height * maskScale));
const pointScaleX = width / maskWidth;
const pointScaleY = height / maskHeight;
const maskCanvas = document.createElement('canvas');
maskCanvas.width = width;
maskCanvas.height = height;
maskCanvas.width = maskWidth;
maskCanvas.height = maskHeight;
const context = maskCanvas.getContext('2d', { willReadFrequently: true });
if (!context) {
return [];
}
const fontSize = getIntroTitleFontSize(context, width, height);
context.clearRect(0, 0, width, height);
const fontSize = getIntroTitleFontSize(context, maskWidth, maskHeight);
context.clearRect(0, 0, maskWidth, maskHeight);
context.font = `${fontSize}px ${appConfig.simulation.intro.fontFamily}`;
context.textAlign = 'center';
context.textBaseline = 'middle';
@ -192,42 +201,44 @@ const createIntroTitlePoints = (
const letterSpacing = fontSize * appConfig.simulation.intro.letterSpacingEm;
drawIntroTitleText(
context,
width / 2,
height * appConfig.simulation.intro.verticalAnchor,
maskWidth / 2,
maskHeight * appConfig.simulation.intro.verticalAnchor,
letterSpacing,
'stroke'
);
drawIntroTitleText(
context,
width / 2,
height * appConfig.simulation.intro.verticalAnchor,
maskWidth / 2,
maskHeight * appConfig.simulation.intro.verticalAnchor,
letterSpacing,
'fill'
);
const { data } = context.getImageData(0, 0, width, height);
const { data } = context.getImageData(0, 0, maskWidth, maskHeight);
const step = Math.max(
1,
Math.floor(Math.min(width, height) / appConfig.simulation.intro.maskSampleDensity)
Math.floor(
Math.min(maskWidth, maskHeight) / appConfig.simulation.intro.maskSampleDensity
)
);
const points: Array<IntroTitlePoint> = [];
const characterColorBoundaries = getIntroTitleColorBoundaries(
context,
width,
maskWidth,
letterSpacing
);
for (let y = 0; y < height; y += step) {
for (let x = 0; x < width; x += step) {
const alpha = getMaskAlpha(data, width, height, x, y);
for (let y = 0; y < maskHeight; y += step) {
for (let x = 0; x < maskWidth; x += step) {
const alpha = getMaskAlpha(data, maskWidth, maskHeight, x, y);
if (alpha < appConfig.simulation.intro.maskAlphaThreshold) {
continue;
}
points.push({
x,
y,
tangent: estimateMaskTangent(data, width, height, x, y),
x: x * pointScaleX,
y: y * pointScaleY,
tangent: estimateMaskTangent(data, maskWidth, maskHeight, x, y),
colorIndex: getIntroTitleColorIndex(x, characterColorBoundaries),
});
}
@ -244,8 +255,10 @@ const getIntroTitleColorBoundaries = (
const letters = Array.from(INTRO_TITLE);
const totalWidth = measureIntroTitleText(context, letters, letterSpacing);
let x = width / 2 - totalWidth / 2;
const [firstCutLetter, secondCutLetter] =
appConfig.simulation.intro.titleColorCutLetters;
const cutLetters = appConfig.simulation.intro.titleColorCutLetters
.map((cutLetter) => Math.min(letters.length - 1, Math.max(1, Math.round(cutLetter))))
.sort((a, b) => a - b);
const [firstCutLetter, secondCutLetter] = cutLetters;
const letterBoxes = letters.map((letter, index) => {
const letterWidth = context.measureText(letter).width;
const box = {
@ -401,7 +414,7 @@ const createSeededRandom = (seed: number): RandomSource => {
};
const easePathProgress = (amount: number): number => {
if (appConfig.simulation.intro.pathEasing === 'linear') {
if (isLinearPathEasing(appConfig.simulation.intro.pathEasing)) {
return amount;
}