From d6cb9929d274c83e89670e9140bba1cb172a0deb Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 22 Aug 2021 02:15:49 +0200 Subject: [PATCH] feat(hiccup-svg): add numericAttribs(), fix svg() - update svg() to format some attribs using ff() --- packages/hiccup-svg/src/format.ts | 44 ++++++++++++++++++++----------- packages/hiccup-svg/src/svg.ts | 21 ++++++++++----- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/packages/hiccup-svg/src/format.ts b/packages/hiccup-svg/src/format.ts index 9eda85b5a6..aba9aec484 100644 --- a/packages/hiccup-svg/src/format.ts +++ b/packages/hiccup-svg/src/format.ts @@ -16,32 +16,46 @@ export const fpoint = (p: Vec2Like) => ff(p[0]) + "," + ff(p[1]); export const fpoints = (pts: Vec2Like[], sep = " ") => pts ? pts.map(fpoint).join(sep) : ""; +/** + * Takes an attributes object and a number of attrib IDs whose values should be + * formatted using {@link ff}. Mutates and returns `attribs` object. + * + * @param attribs + * @param ids + */ +export const numericAttribs = (attribs: any, ...ids: string[]) => { + let v: any; + for (let id of ids) { + (v = attribs[id]) != null && (attribs[id] = ff(v)); + } + return attribs; +}; + /** * Takes an attributes object and converts any `fill`, `stroke` or - * transformation attributes, i.e. `transform`, `rotate`, `scale`, - * `translate`. If the element has a `transform` attrib, conversion of - * the other attribs will be skipped, else the values are assumed to be - * either strings or: + * transformation attributes, i.e. `transform`, `rotate`, `scale`, `translate`. + * + * @remarks + * If the element has a `transform` attrib, conversion of the other attribs will + * be skipped, else the values are assumed to be either strings or: * * - `transform`: 6-element numeric array (mat23) * - `translate`: 2-element array * - `rotate`: number (angle in radians) * - `scale`: number (uniform scale) or 2-elem array * - * If no `transform` is given, the resulting transformation order will - * always be TRS. Any string values given will be used as-is and - * therefore need to be complete, e.g. `{ rotate: "rotate(60)" }` + * If no `transform` is given, the resulting transformation order will always be + * TRS. Any string values given will be used as-is and therefore need to be + * complete, e.g. `{ rotate: "rotate(60)" }` * - * For color related attribs (`fill`, `stroke`), if given value is - * array-like, a number or an {@link @thi.ng/color#IColor} instance, it - * will be converted into a CSS color string using - * {@link @thi.ng/color#asCSS}. + * For color related attribs (`fill`, `stroke`), if given value is array-like, a + * number or an {@link @thi.ng/color#IColor} instance, it will be converted into + * a CSS color string using {@link @thi.ng/color#asCSS}. * - * String color attribs prefixed with `$` are replaced with `url(#...)` - * refs (used for referencing gradients). + * String color attribs prefixed with `$` are replaced with `url(#...)` refs + * (used for referencing gradients). * - * Returns updated attribs or `undefined` if `attribs` itself is - * null-ish. + * Returns updated attribs or `undefined` if `attribs` itself is null-ish. * * @param attribs - attributes object * diff --git a/packages/hiccup-svg/src/svg.ts b/packages/hiccup-svg/src/svg.ts index dc2a803150..a570d8dbb5 100644 --- a/packages/hiccup-svg/src/svg.ts +++ b/packages/hiccup-svg/src/svg.ts @@ -1,6 +1,6 @@ import { XML_SVG, XML_XLINK } from "@thi.ng/prefixes"; import { convertTree } from "./convert"; -import { fattribs } from "./format"; +import { fattribs, numericAttribs } from "./format"; /** * Defines an root element with default XML namespaces. By default @@ -16,12 +16,19 @@ import { fattribs } from "./format"; * @param body - shape primitives */ export const svg = (attribs: any, ...body: any[]): any[] => { - attribs = fattribs({ - version: "1.1", - xmlns: XML_SVG, - "xmlns:xlink": XML_XLINK, - ...attribs, - }); + attribs = fattribs( + numericAttribs( + { + version: "1.1", + xmlns: XML_SVG, + "xmlns:xlink": XML_XLINK, + ...attribs, + }, + "width", + "height", + "stroke-width" + ) + ); if (attribs.convert) { delete attribs.convert; body = body.map(convertTree);