Skip to content

hiccup svg recipes

Karsten Schmidt edited this page Jul 3, 2018 · 6 revisions

@thi.ng/hiccup-svg recipes

Multi-colored polyline

The coloredPolyline function below uses transducers to transform an iterable of 2D points into an iterator of pairwise hiccup line segments. Each line is colored using the user provided tint function. This function takes an argument (a number between 0.0 ... 1.0) and must return a CSS color string.

import * as svg from "@thi.ng/hiccup-svg";
import * as tx from "@thi.ng/transducers";

function coloredPolyline(points: Iterable<number[]>, tint: (t: number)=> string) {
    const _points = tx.ensureArray(points);
    const n = 1 / (_points.length - 1);
    return tx.iterator(
        tx.comp(
            tx.partition(2, 1),
            tx.mapIndexed((i, [a, b]: number[][]) => svg.line(a, b, { stroke: tint(i*n) }))
        ),
        _points
    );
}

Usage example

import * as fs from "fs";

function spiral(r1: number, r2: number, twist: number) {
    return (t: number) => {
        const r = r1 + (r2 - r1) * t;
        t *= twist;
        return [
            100 + Math.cos(t) * r,
            100 + Math.sin(t) * r,
        ];
    };
}

fs.writeFileSync("colored-spiral.svg",
    serialize(
        svg.svg({ width: 200, height: 200 },
            ...coloredPolyline(
                tx.iterator(
                    tx.map(spiral(20, 90, Math.PI * 10)),
                    tx.normRange(500)
                ),
                (t) => `rgba(${~~(t * 255)}, 0, ${~~(255 - t * 255)}, 1)`
            )
        )
    )
);

Example output

colored spiral