Newer
Older
fractals / src / index.ts
import { InwardSpiral, FractalSequenceElement, ISpiralParameters } from "./SpiralFractal";
import { createSquare, createTriangle, createHexagonalBase } from "./BaseShapes";
import { createSvgRootElement, createBasePolygons, SvgSpiralBody } from "./SvgRenderer";
import { Polygon } from "./Polygon";

function makeSpirals(
    sideLength:number,
    iterations:number,
    startShapes:Polygon[],
)
{
    const root = createSvgRootElement(sideLength);
    const segments:SvgSpiralBody[] = [];
    for (const startShape of startShapes)
    {
        const spiral = InwardSpiral(startShape, iterations);
        const svgPolygons = createBasePolygons(spiral.length);
        svgPolygons.forEach(p => root.appendChild(p));
        segments.push(new SvgSpiralBody(root, svgPolygons, spiral));
    }

    return segments;
}

function createAnimationStep(
    shrinkRate:number,
    svgSpiral:SvgSpiralBody,
    speed:number = 0.0025,
)
{
    const maxTime = shrinkRate;
    let time = 0;
    const animationStep = () => {
        svgSpiral.update({shrinkRate, firstShrinkRate:time});
        time = (time + speed) % maxTime;
        if(time < 0)
        {
            time += maxTime;
        }
    };
    return animationStep;
}

function animatedSpiralFractal(
    sideLength:number,
    iterations:number,
    shrinkRate:number,
    startShapes:Polygon[],
    htmlDivId:string,
)
{
    const animationSpeed = 0.005;
    const svgSpirals = makeSpirals(sideLength, iterations, startShapes);
    const divSpiral = document.getElementById(htmlDivId) as HTMLDivElement;
    divSpiral.appendChild(svgSpirals[0].svgRootElement);
    svgSpirals.forEach(s => s.update({shrinkRate, firstShrinkRate:shrinkRate}));

    return svgSpirals.map((s,i) => createAnimationStep(shrinkRate, s, ((2*((i+1)%2))-1) * animationSpeed));
}

function pageInit(): void
{
    const sideLength = 400;
    const iterations = 50;
    const shrinkRate = 0.1;

    const square = createSquare(sideLength);
    const squareAnimation = animatedSpiralFractal(sideLength, iterations, shrinkRate, [square], "square");

    const triangle = createTriangle(sideLength);
    const triangleAnimation = animatedSpiralFractal(sideLength, iterations, shrinkRate, [triangle], "triangle");

    const hexagonalBase = createHexagonalBase(sideLength);
    const hexagonalAnimations =
        animatedSpiralFractal(sideLength, iterations, shrinkRate, hexagonalBase, "hexagonal");

    const animation = () => {
        squareAnimation.forEach(a => a());
        triangleAnimation.forEach(a => a());
        hexagonalAnimations.forEach(a => a());
        requestAnimationFrame(animation);
    };
    requestAnimationFrame(animation);

}

document.addEventListener("DOMContentLoaded", pageInit);