Skip to content

Commit

Permalink
feat(hiccup-svg): add numericAttribs(), fix svg()
Browse files Browse the repository at this point in the history
- update svg() to format some attribs using ff()
  • Loading branch information
postspectacular committed Aug 22, 2021
1 parent 6a55d11 commit d6cb992
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 22 deletions.
44 changes: 29 additions & 15 deletions packages/hiccup-svg/src/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
21 changes: 14 additions & 7 deletions packages/hiccup-svg/src/svg.ts
Original file line number Diff line number Diff line change
@@ -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 <svg> root element with default XML namespaces. By default
Expand All @@ -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);
Expand Down

0 comments on commit d6cb992

Please sign in to comment.