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 array of 2D points into an iterator of pairwise 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: number[][], tint: (t: number)=> string) {
    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({ 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