@kensio/colophon 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -798
- package/dist/background/gradient.d.ts +12 -0
- package/dist/background/gradient.d.ts.map +1 -0
- package/dist/background/gradient.js +21 -0
- package/dist/background/gradient.js.map +1 -0
- package/dist/background/image.d.ts +14 -0
- package/dist/background/image.d.ts.map +1 -0
- package/dist/background/image.js +36 -0
- package/dist/background/image.js.map +1 -0
- package/dist/background/index.d.ts +13 -0
- package/dist/background/index.d.ts.map +1 -0
- package/dist/background/index.js +27 -0
- package/dist/background/index.js.map +1 -0
- package/dist/background/mesh.d.ts +12 -0
- package/dist/background/mesh.d.ts.map +1 -0
- package/dist/background/mesh.js +43 -0
- package/dist/background/mesh.js.map +1 -0
- package/dist/background.d.ts +7 -2
- package/dist/background.d.ts.map +1 -1
- package/dist/background.js +44 -1
- package/dist/background.js.map +1 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/config.d.ts +1 -1
- package/dist/cli/config.js +1 -1
- package/dist/config/defaults.d.ts +8 -7
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +8 -8
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +14 -5
- package/dist/config/index.js.map +1 -1
- package/dist/config/resolve.d.ts +7 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +16 -0
- package/dist/config/resolve.js.map +1 -1
- package/dist/config/size.d.ts +7 -1
- package/dist/config/size.d.ts.map +1 -1
- package/dist/config/size.js +22 -9
- package/dist/config/size.js.map +1 -1
- package/dist/content/props.d.ts +2 -2
- package/dist/content/props.js +2 -2
- package/dist/content/slug.d.ts +5 -5
- package/dist/content/slug.js +6 -6
- package/dist/content/slug.js.map +1 -1
- package/dist/content/walk.d.ts +1 -1
- package/dist/content/walk.js +1 -1
- package/dist/fonts/index.d.ts +3 -2
- package/dist/fonts/index.d.ts.map +1 -1
- package/dist/fonts/index.js +3 -2
- package/dist/fonts/index.js.map +1 -1
- package/dist/fonts/resolve.js +1 -1
- package/dist/generate/extra.js +4 -4
- package/dist/generate/extra.js.map +1 -1
- package/dist/generate/options.d.ts +1 -1
- package/dist/generate/outputs.d.ts +4 -4
- package/dist/generate/outputs.js +4 -4
- package/dist/highlight/language.d.ts +2 -3
- package/dist/highlight/language.d.ts.map +1 -1
- package/dist/highlight/language.js +3 -4
- package/dist/highlight/language.js.map +1 -1
- package/dist/highlight/normalise.d.ts +2 -2
- package/dist/highlight/normalise.js +2 -2
- package/dist/image/index.d.ts +18 -0
- package/dist/image/index.d.ts.map +1 -0
- package/dist/image/index.js +42 -0
- package/dist/image/index.js.map +1 -0
- package/dist/image/jpeg.d.ts +10 -0
- package/dist/image/jpeg.d.ts.map +1 -0
- package/dist/image/jpeg.js +57 -0
- package/dist/image/jpeg.js.map +1 -0
- package/dist/image/load.d.ts +4 -0
- package/dist/image/load.d.ts.map +1 -0
- package/dist/image/load.js +60 -0
- package/dist/image/load.js.map +1 -0
- package/dist/image/media.d.ts +10 -0
- package/dist/image/media.d.ts.map +1 -0
- package/dist/image/media.js +37 -0
- package/dist/image/media.js.map +1 -0
- package/dist/image/resolve.d.ts +13 -0
- package/dist/image/resolve.d.ts.map +1 -0
- package/dist/image/resolve.js +38 -0
- package/dist/image/resolve.js.map +1 -0
- package/dist/image/size.d.ts +22 -0
- package/dist/image/size.d.ts.map +1 -0
- package/dist/image/size.js +60 -0
- package/dist/image/size.js.map +1 -0
- package/dist/image/svg.d.ts +12 -0
- package/dist/image/svg.d.ts.map +1 -0
- package/dist/image/svg.js +61 -0
- package/dist/image/svg.js.map +1 -0
- package/dist/image/uri.d.ts +9 -0
- package/dist/image/uri.d.ts.map +1 -0
- package/dist/image/uri.js +22 -0
- package/dist/image/uri.js.map +1 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/layout/block.d.ts +37 -0
- package/dist/layout/block.d.ts.map +1 -0
- package/dist/layout/block.js +26 -0
- package/dist/layout/block.js.map +1 -0
- package/dist/layout/box.d.ts +20 -0
- package/dist/layout/box.d.ts.map +1 -0
- package/dist/layout/box.js +61 -0
- package/dist/layout/box.js.map +1 -0
- package/dist/layout/distribute.d.ts +15 -0
- package/dist/layout/distribute.d.ts.map +1 -0
- package/dist/layout/distribute.js +30 -0
- package/dist/layout/distribute.js.map +1 -0
- package/dist/layout/image.d.ts +42 -0
- package/dist/layout/image.d.ts.map +1 -0
- package/dist/layout/image.js +34 -0
- package/dist/layout/image.js.map +1 -0
- package/dist/layout/index.d.ts +40 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +30 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/lines.d.ts +45 -0
- package/dist/layout/lines.d.ts.map +1 -0
- package/dist/layout/lines.js +71 -0
- package/dist/layout/lines.js.map +1 -0
- package/dist/layout/measure.d.ts +11 -0
- package/dist/layout/measure.d.ts.map +1 -0
- package/dist/layout/measure.js +11 -0
- package/dist/layout/measure.js.map +1 -0
- package/dist/layout/panel.d.ts +20 -0
- package/dist/layout/panel.d.ts.map +1 -0
- package/dist/layout/panel.js +22 -0
- package/dist/layout/panel.js.map +1 -0
- package/dist/layout/row.d.ts +15 -0
- package/dist/layout/row.d.ts.map +1 -0
- package/dist/layout/row.js +20 -0
- package/dist/layout/row.js.map +1 -0
- package/dist/layout/scrim.d.ts +23 -0
- package/dist/layout/scrim.d.ts.map +1 -0
- package/dist/layout/scrim.js +38 -0
- package/dist/layout/scrim.js.map +1 -0
- package/dist/layout/stack.d.ts +14 -0
- package/dist/layout/stack.d.ts.map +1 -0
- package/dist/layout/stack.js +19 -0
- package/dist/layout/stack.js.map +1 -0
- package/dist/layout/types.d.ts +49 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout/types.js +2 -0
- package/dist/layout/types.js.map +1 -0
- package/dist/manifest/build.d.ts +1 -1
- package/dist/manifest/build.js +1 -1
- package/dist/manifest/index.d.ts +1 -1
- package/dist/manifest/index.js +1 -1
- package/dist/manifest/order.d.ts +1 -1
- package/dist/manifest/order.js +1 -1
- package/dist/manifest/page.d.ts +2 -2
- package/dist/manifest/page.js +3 -3
- package/dist/measure/estimate.d.ts +10 -0
- package/dist/measure/estimate.d.ts.map +1 -0
- package/dist/measure/estimate.js +58 -0
- package/dist/measure/estimate.js.map +1 -0
- package/dist/measure/faces.d.ts +15 -0
- package/dist/measure/faces.d.ts.map +1 -0
- package/dist/measure/faces.js +70 -0
- package/dist/measure/faces.js.map +1 -0
- package/dist/measure/index.d.ts +16 -0
- package/dist/measure/index.d.ts.map +1 -0
- package/dist/measure/index.js +0 -0
- package/dist/measure/index.js.map +1 -0
- package/dist/measure/runs.d.ts +17 -0
- package/dist/measure/runs.d.ts.map +1 -0
- package/dist/measure/runs.js +39 -0
- package/dist/measure/runs.js.map +1 -0
- package/dist/measure/select.d.ts +13 -0
- package/dist/measure/select.d.ts.map +1 -0
- package/dist/measure/select.js +47 -0
- package/dist/measure/select.js.map +1 -0
- package/dist/meta/tags.d.ts +6 -6
- package/dist/meta/tags.js +6 -6
- package/dist/meta/url.d.ts +4 -4
- package/dist/meta/url.js +4 -4
- package/dist/placement/check.d.ts +1 -1
- package/dist/placement/check.js +1 -1
- package/dist/placement/index.js +1 -1
- package/dist/placement/relative.d.ts +3 -3
- package/dist/placement/relative.js +3 -3
- package/dist/pool.d.ts +2 -2
- package/dist/pool.js +3 -3
- package/dist/pool.js.map +1 -1
- package/dist/props.d.ts +7 -0
- package/dist/props.d.ts.map +1 -0
- package/dist/props.js +17 -0
- package/dist/props.js.map +1 -0
- package/dist/render/svg.d.ts +4 -2
- package/dist/render/svg.d.ts.map +1 -1
- package/dist/render/svg.js +28 -6
- package/dist/render/svg.js.map +1 -1
- package/dist/stamp/config-digest.d.ts.map +1 -1
- package/dist/stamp/config-digest.js +21 -1
- package/dist/stamp/config-digest.js.map +1 -1
- package/dist/stamp/index.js +2 -2
- package/dist/stamp/index.js.map +1 -1
- package/dist/stamp/read.d.ts +1 -1
- package/dist/stamp/read.js +4 -4
- package/dist/templates/attribution.d.ts +17 -0
- package/dist/templates/attribution.d.ts.map +1 -0
- package/dist/templates/attribution.js +39 -0
- package/dist/templates/attribution.js.map +1 -0
- package/dist/templates/banner/badge-props.d.ts +16 -0
- package/dist/templates/banner/badge-props.d.ts.map +1 -0
- package/dist/templates/banner/badge-props.js +58 -0
- package/dist/templates/banner/badge-props.js.map +1 -0
- package/dist/templates/banner/badge.d.ts.map +1 -1
- package/dist/templates/banner/badge.js +3 -6
- package/dist/templates/banner/badge.js.map +1 -1
- package/dist/templates/banner/index.d.ts +3 -0
- package/dist/templates/banner/index.d.ts.map +1 -1
- package/dist/templates/banner/index.js +41 -37
- package/dist/templates/banner/index.js.map +1 -1
- package/dist/templates/banner/lines.d.ts +7 -12
- package/dist/templates/banner/lines.d.ts.map +1 -1
- package/dist/templates/banner/lines.js +23 -34
- package/dist/templates/banner/lines.js.map +1 -1
- package/dist/templates/banner/version.d.ts +9 -0
- package/dist/templates/banner/version.d.ts.map +1 -0
- package/dist/templates/banner/version.js +21 -0
- package/dist/templates/banner/version.js.map +1 -0
- package/dist/templates/card/index.d.ts +4 -1
- package/dist/templates/card/index.d.ts.map +1 -1
- package/dist/templates/card/index.js +37 -25
- package/dist/templates/card/index.js.map +1 -1
- package/dist/templates/card/lines.d.ts +17 -13
- package/dist/templates/card/lines.d.ts.map +1 -1
- package/dist/templates/card/lines.js +24 -20
- package/dist/templates/card/lines.js.map +1 -1
- package/dist/templates/code/chrome.d.ts +7 -3
- package/dist/templates/code/chrome.d.ts.map +1 -1
- package/dist/templates/code/chrome.js +12 -11
- package/dist/templates/code/chrome.js.map +1 -1
- package/dist/templates/code/clip.d.ts +1 -1
- package/dist/templates/code/clip.js +1 -1
- package/dist/templates/code/fit.d.ts +2 -2
- package/dist/templates/code/fit.d.ts.map +1 -1
- package/dist/templates/code/fit.js +4 -4
- package/dist/templates/code/fit.js.map +1 -1
- package/dist/templates/code/index.d.ts.map +1 -1
- package/dist/templates/code/index.js +7 -6
- package/dist/templates/code/index.js.map +1 -1
- package/dist/templates/code/layout.d.ts +1 -1
- package/dist/templates/code/layout.d.ts.map +1 -1
- package/dist/templates/code/layout.js +6 -6
- package/dist/templates/code/layout.js.map +1 -1
- package/dist/templates/code/panel.d.ts +13 -0
- package/dist/templates/code/panel.d.ts.map +1 -1
- package/dist/templates/code/panel.js +34 -2
- package/dist/templates/code/panel.js.map +1 -1
- package/dist/templates/code/plate.d.ts +3 -1
- package/dist/templates/code/plate.d.ts.map +1 -1
- package/dist/templates/code/plate.js +11 -9
- package/dist/templates/code/plate.js.map +1 -1
- package/dist/templates/code/spans.js +1 -1
- package/dist/templates/code/spans.js.map +1 -1
- package/dist/templates/code/width.d.ts +10 -0
- package/dist/templates/code/width.d.ts.map +1 -0
- package/dist/templates/code/width.js +26 -0
- package/dist/templates/code/width.js.map +1 -0
- package/dist/templates/footer.d.ts +8 -0
- package/dist/templates/footer.d.ts.map +1 -1
- package/dist/templates/footer.js +11 -1
- package/dist/templates/footer.js.map +1 -1
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +1 -1
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/logo.d.ts +15 -0
- package/dist/templates/logo.d.ts.map +1 -0
- package/dist/templates/logo.js +30 -0
- package/dist/templates/logo.js.map +1 -0
- package/dist/templates/measure.d.ts +11 -0
- package/dist/templates/measure.d.ts.map +1 -0
- package/dist/templates/measure.js +11 -0
- package/dist/templates/measure.js.map +1 -0
- package/dist/templates/props.d.ts +2 -2
- package/dist/templates/props.js +2 -2
- package/dist/templates/text.d.ts +37 -0
- package/dist/templates/text.d.ts.map +1 -0
- package/dist/templates/text.js +26 -0
- package/dist/templates/text.js.map +1 -0
- package/dist/text/break.d.ts +11 -0
- package/dist/text/break.d.ts.map +1 -0
- package/dist/text/break.js +30 -0
- package/dist/text/break.js.map +1 -0
- package/dist/text/fit.d.ts +30 -0
- package/dist/text/fit.d.ts.map +1 -0
- package/dist/text/fit.js +29 -0
- package/dist/text/fit.js.map +1 -0
- package/dist/text/index.d.ts +5 -3
- package/dist/text/index.d.ts.map +1 -1
- package/dist/text/index.js +3 -2
- package/dist/text/index.js.map +1 -1
- package/dist/text/wrap.d.ts +17 -7
- package/dist/text/wrap.d.ts.map +1 -1
- package/dist/text/wrap.js +25 -17
- package/dist/text/wrap.js.map +1 -1
- package/dist/texture/grain.d.ts +17 -0
- package/dist/texture/grain.d.ts.map +1 -0
- package/dist/texture/grain.js +29 -0
- package/dist/texture/grain.js.map +1 -0
- package/dist/texture/index.d.ts +11 -0
- package/dist/texture/index.d.ts.map +1 -0
- package/dist/texture/index.js +20 -0
- package/dist/texture/index.js.map +1 -0
- package/dist/texture/pattern.d.ts +17 -0
- package/dist/texture/pattern.d.ts.map +1 -0
- package/dist/texture/pattern.js +45 -0
- package/dist/texture/pattern.js.map +1 -0
- package/dist/texture/resolve.d.ts +16 -0
- package/dist/texture/resolve.d.ts.map +1 -0
- package/dist/texture/resolve.js +20 -0
- package/dist/texture/resolve.js.map +1 -0
- package/dist/theme/index.d.ts +27 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +41 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/presets.d.ts +38 -0
- package/dist/theme/presets.d.ts.map +1 -0
- package/dist/theme/presets.js +150 -0
- package/dist/theme/presets.js.map +1 -0
- package/dist/types.d.ts +281 -46
- package/dist/types.d.ts.map +1 -1
- package/dist/validate/background.d.ts +12 -0
- package/dist/validate/background.d.ts.map +1 -0
- package/dist/validate/background.js +53 -0
- package/dist/validate/background.js.map +1 -0
- package/dist/validate/collect.d.ts +9 -0
- package/dist/validate/collect.d.ts.map +1 -0
- package/dist/validate/collect.js +34 -0
- package/dist/validate/collect.js.map +1 -0
- package/dist/validate/index.d.ts +1 -1
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +3 -20
- package/dist/validate/index.js.map +1 -1
- package/dist/validate/keys.d.ts +35 -2
- package/dist/validate/keys.d.ts.map +1 -1
- package/dist/validate/keys.js +92 -3
- package/dist/validate/keys.js.map +1 -1
- package/dist/validate/overrides.d.ts.map +1 -1
- package/dist/validate/overrides.js +5 -1
- package/dist/validate/overrides.js.map +1 -1
- package/dist/validate/suggest.d.ts.map +1 -1
- package/dist/validate/suggest.js +21 -3
- package/dist/validate/suggest.js.map +1 -1
- package/dist/validate/texture.d.ts +11 -0
- package/dist/validate/texture.d.ts.map +1 -0
- package/dist/validate/texture.js +34 -0
- package/dist/validate/texture.js.map +1 -0
- package/dist/validate/values.d.ts +10 -10
- package/dist/validate/values.d.ts.map +1 -1
- package/dist/validate/values.js +21 -31
- package/dist/validate/values.js.map +1 -1
- package/package.json +7 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { escapeXml } from "../text/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* One SVG attribute, or nothing where the value was not given.
|
|
4
|
+
*
|
|
5
|
+
* The value is escaped even though most of them are colours out of a config,
|
|
6
|
+
* where nothing needs escaping. A template's props come from frontmatter, and a
|
|
7
|
+
* template is free to pass one straight through as a fill, so a site whose
|
|
8
|
+
* posts are not all written by the same person would otherwise be one `"` away
|
|
9
|
+
* from a document that does not parse.
|
|
10
|
+
*/
|
|
11
|
+
function attribute(name, value) {
|
|
12
|
+
return value === undefined ? "" : ` ${name}="${escapeXml(String(value))}"`;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A rectangle: the plate a badge sits on, the surface of a panel, a rule along
|
|
16
|
+
* an edge. Everything in a template that is not text or an image is one of
|
|
17
|
+
* these.
|
|
18
|
+
*
|
|
19
|
+
* Attributes a style does not name are left out rather than written as their
|
|
20
|
+
* defaults, so the output says only what the template decided.
|
|
21
|
+
*/
|
|
22
|
+
export function box(rect, style = {}) {
|
|
23
|
+
const attributes = [
|
|
24
|
+
attribute("x", rect.x),
|
|
25
|
+
attribute("y", rect.y),
|
|
26
|
+
attribute("width", rect.width),
|
|
27
|
+
attribute("height", rect.height),
|
|
28
|
+
attribute("rx", style.radius),
|
|
29
|
+
attribute("fill", style.fill),
|
|
30
|
+
attribute("fill-opacity", style.fillOpacity),
|
|
31
|
+
attribute("stroke", style.stroke),
|
|
32
|
+
attribute("stroke-opacity", style.strokeOpacity),
|
|
33
|
+
attribute("stroke-width", style.strokeWidth),
|
|
34
|
+
];
|
|
35
|
+
return `<rect${attributes.join("")}/>`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Shrink a rectangle inwards, which is how a template gets its margins. One
|
|
39
|
+
* number insets every edge; a partial one insets the edges it names.
|
|
40
|
+
*
|
|
41
|
+
* An inset larger than the rectangle collapses it to nothing rather than
|
|
42
|
+
* turning it inside out, since a negative width draws nothing anyway and an
|
|
43
|
+
* empty rectangle is easier to reason about than one with its corners crossed.
|
|
44
|
+
*/
|
|
45
|
+
export function inset(rect, amount) {
|
|
46
|
+
const all = typeof amount === "number" ? amount : 0;
|
|
47
|
+
const edges = typeof amount === "number" ? {} : amount;
|
|
48
|
+
const top = edges.top ?? all;
|
|
49
|
+
const right = edges.right ?? all;
|
|
50
|
+
const bottom = edges.bottom ?? all;
|
|
51
|
+
const left = edges.left ?? all;
|
|
52
|
+
return {
|
|
53
|
+
// Clamped so that a rectangle which collapses does so at the far edge of
|
|
54
|
+
// the one it came from, rather than landing outside it with no width.
|
|
55
|
+
x: rect.x + Math.min(left, rect.width),
|
|
56
|
+
y: rect.y + Math.min(top, rect.height),
|
|
57
|
+
width: Math.max(0, rect.width - left - right),
|
|
58
|
+
height: Math.max(0, rect.height - top - bottom),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=box.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/layout/box.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C;;;;;;;;GAQG;AACH,SAAS,SAAS,CAAC,IAAY,EAAE,KAAkC;IACjE,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;AAC7E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,CAAC,IAAU,EAAE,KAAK,GAAa,EAAE;IAClD,MAAM,UAAU,GAAG;QACjB,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QACtB,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QACtB,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;QAC9B,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;QAChC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;QAC7B,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC;QAC7B,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,WAAW,CAAC;QAC5C,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC;QACjC,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC;QAChD,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,WAAW,CAAC;KAC7C,CAAC;IAEF,OAAO,QAAQ,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,KAAK,CACnB,IAAU,EACV,MAA6E;IAE7E,MAAM,GAAG,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACvD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC;IAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC;IACjC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC;IACnC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC;IAE/B,OAAO;QACL,yEAAyE;QACzE,sEAAsE;QACtE,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC;QACtC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC;QACtC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;QAC7C,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC;KAChD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Align, Extent, Placed, Span } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Lay a group of items out along one axis.
|
|
4
|
+
*
|
|
5
|
+
* Stacking rows of text down an image and setting a badge beside a title are
|
|
6
|
+
* the same sum with the coordinates renamed, so both `stack` and
|
|
7
|
+
* `row` are this function. It is the only arithmetic in the toolkit that
|
|
8
|
+
* is worth getting right once.
|
|
9
|
+
*
|
|
10
|
+
* A group taller or wider than the space it was given starts at `span.start`
|
|
11
|
+
* and runs over rather than being squeezed, since a template that has
|
|
12
|
+
* overflowed wants to see it rather than have it hidden.
|
|
13
|
+
*/
|
|
14
|
+
export declare function distribute(items: readonly Extent[], span: Span, align?: Align): readonly Placed[];
|
|
15
|
+
//# sourceMappingURL=distribute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distribute.d.ts","sourceRoot":"","sources":["../../src/layout/distribute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,IAAI,EAAE,IAAI,EACV,KAAK,GAAE,KAAgB,GACtB,SAAS,MAAM,EAAE,CAYnB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lay a group of items out along one axis.
|
|
3
|
+
*
|
|
4
|
+
* Stacking rows of text down an image and setting a badge beside a title are
|
|
5
|
+
* the same sum with the coordinates renamed, so both `stack` and
|
|
6
|
+
* `row` are this function. It is the only arithmetic in the toolkit that
|
|
7
|
+
* is worth getting right once.
|
|
8
|
+
*
|
|
9
|
+
* A group taller or wider than the space it was given starts at `span.start`
|
|
10
|
+
* and runs over rather than being squeezed, since a template that has
|
|
11
|
+
* overflowed wants to see it rather than have it hidden.
|
|
12
|
+
*/
|
|
13
|
+
export function distribute(items, span, align = "centre") {
|
|
14
|
+
const advances = items.map((item) => (item.gapBefore ?? 0) + item.size);
|
|
15
|
+
const total = advances.reduce((sum, advance) => sum + advance, 0);
|
|
16
|
+
const spare = Math.max(0, span.end - span.start - total);
|
|
17
|
+
let cursor = span.start + offset(spare, align);
|
|
18
|
+
return items.map((item, index) => {
|
|
19
|
+
const start = cursor + (item.gapBefore ?? 0);
|
|
20
|
+
cursor += advances[index] ?? 0;
|
|
21
|
+
return { start, index };
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function offset(spare, align) {
|
|
25
|
+
if (align === "start") {
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
return align === "end" ? spare : spare / 2;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=distribute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distribute.js","sourceRoot":"","sources":["../../src/layout/distribute.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CACxB,KAAwB,EACxB,IAAU,EACV,KAAK,GAAU,QAAQ;IAEvB,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IAEzD,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAE/C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;QAC7C,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,MAAM,CAAC,KAAa,EAAE,KAAY;IACzC,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Rect } from "./types.js";
|
|
2
|
+
/** How an image fills the rectangle it was given. */
|
|
3
|
+
interface ImageFit {
|
|
4
|
+
/**
|
|
5
|
+
* `cover` fills the rectangle and crops whatever does not fit, which is what
|
|
6
|
+
* a background photo wants. `contain` fits the whole image inside it, which
|
|
7
|
+
* is what a logo wants, since cropping a wordmark ruins it.
|
|
8
|
+
*/
|
|
9
|
+
readonly fit?: "cover" | "contain";
|
|
10
|
+
readonly opacity?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Rounded corners, for an avatar or a screenshot, which need a clip path and
|
|
14
|
+
* so an id to hang it on: SVG has no other way to say it.
|
|
15
|
+
*
|
|
16
|
+
* The two travel together in the type, so a radius without an id does not
|
|
17
|
+
* compile. It is the sort of option that would otherwise be dropped in silence,
|
|
18
|
+
* and a template author asking for a round avatar and getting a square one has
|
|
19
|
+
* nothing to go on.
|
|
20
|
+
*/
|
|
21
|
+
type ImageCorners = {
|
|
22
|
+
readonly radius?: undefined;
|
|
23
|
+
readonly id?: string;
|
|
24
|
+
} | {
|
|
25
|
+
readonly radius: number;
|
|
26
|
+
readonly id: string;
|
|
27
|
+
};
|
|
28
|
+
/** Options for {@link image}. */
|
|
29
|
+
export type ImageOptions = ImageFit & ImageCorners;
|
|
30
|
+
/**
|
|
31
|
+
* Draw an image within a rectangle.
|
|
32
|
+
*
|
|
33
|
+
* `href` is passed through as given, so it can be a `data:` URI, which is the
|
|
34
|
+
* form that travels: an image file read at build time and inlined is an image
|
|
35
|
+
* that renders the same wherever the build runs, with nothing to fetch.
|
|
36
|
+
*
|
|
37
|
+
* An `<image>` establishes its own viewport, so `cover` crops to the rectangle
|
|
38
|
+
* without a clip path. Rounded corners do need one.
|
|
39
|
+
*/
|
|
40
|
+
export declare function image(rect: Rect, href: string, options?: ImageOptions): string;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/layout/image.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,qDAAqD;AACrD,UAAU,QAAQ;IAChB;;;;OAIG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,KAAK,YAAY,GACb;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD,iCAAiC;AACjC,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEnD;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CACnB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,YAAiB,GACzB,MAAM,CA6BR"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { escapeXml } from "../text/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Draw an image within a rectangle.
|
|
4
|
+
*
|
|
5
|
+
* `href` is passed through as given, so it can be a `data:` URI, which is the
|
|
6
|
+
* form that travels: an image file read at build time and inlined is an image
|
|
7
|
+
* that renders the same wherever the build runs, with nothing to fetch.
|
|
8
|
+
*
|
|
9
|
+
* An `<image>` establishes its own viewport, so `cover` crops to the rectangle
|
|
10
|
+
* without a clip path. Rounded corners do need one.
|
|
11
|
+
*/
|
|
12
|
+
export function image(rect, href, options = {}) {
|
|
13
|
+
const fit = (options.fit ?? "cover") === "cover" ? "slice" : "meet";
|
|
14
|
+
const aspect = `xMidYMid ${fit}`;
|
|
15
|
+
const opacity = options.opacity === undefined
|
|
16
|
+
? ""
|
|
17
|
+
: ` opacity="${String(options.opacity)}"`;
|
|
18
|
+
const element = `<image x="${String(rect.x)}" y="${String(rect.y)}"` +
|
|
19
|
+
` width="${String(rect.width)}" height="${String(rect.height)}"` +
|
|
20
|
+
` preserveAspectRatio="${aspect}"${opacity}` +
|
|
21
|
+
` href="${escapeXml(href)}"/>`;
|
|
22
|
+
if (options.radius === undefined) {
|
|
23
|
+
return element;
|
|
24
|
+
}
|
|
25
|
+
// The type pairs the two, so an id is here whenever a radius is.
|
|
26
|
+
const id = escapeXml(options.id);
|
|
27
|
+
return (`<defs><clipPath id="${id}">` +
|
|
28
|
+
`<rect x="${String(rect.x)}" y="${String(rect.y)}"` +
|
|
29
|
+
` width="${String(rect.width)}" height="${String(rect.height)}"` +
|
|
30
|
+
` rx="${String(options.radius)}"/>` +
|
|
31
|
+
`</clipPath></defs>` +
|
|
32
|
+
`<g clip-path="url(#${id})">${element}</g>`);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/layout/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AA8B7C;;;;;;;;;GASG;AACH,MAAM,UAAU,KAAK,CACnB,IAAU,EACV,IAAY,EACZ,OAAO,GAAiB,EAAE;IAE1B,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IACpE,MAAM,MAAM,GAAG,YAAY,GAAG,EAAE,CAAC;IACjC,MAAM,OAAO,GACX,OAAO,CAAC,OAAO,KAAK,SAAS;QAC3B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,aAAa,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;IAE9C,MAAM,OAAO,GACX,aAAa,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;QACpD,WAAW,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;QAChE,yBAAyB,MAAM,IAAI,OAAO,EAAE;QAC5C,UAAU,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;IAEjC,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,iEAAiE;IACjE,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEjC,OAAO,CACL,uBAAuB,EAAE,IAAI;QAC7B,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;QACnD,WAAW,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;QAChE,QAAQ,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QACnC,oBAAoB;QACpB,sBAAsB,EAAE,MAAM,OAAO,MAAM,CAC5C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout primitives for template authors.
|
|
3
|
+
*
|
|
4
|
+
* Importable on its own as `@kensio/colophon/layout`. Writing a template means
|
|
5
|
+
* returning a string of SVG, and this is the set of small functions that build
|
|
6
|
+
* one: rectangles, panels, images, and the arithmetic of putting things in
|
|
7
|
+
* rows and stacks. It is deliberately boring. Nothing here holds state, every
|
|
8
|
+
* function takes values and returns them, and a template that would rather
|
|
9
|
+
* write its own SVG by hand still can.
|
|
10
|
+
*
|
|
11
|
+
* The subpath loads no rasteriser, no syntax highlighter and nothing from
|
|
12
|
+
* Node, so the whole of it runs anywhere a string does.
|
|
13
|
+
*
|
|
14
|
+
* Measuring is the exception to "import it from here": a template is handed a
|
|
15
|
+
* `MeasureText` on its context, because only the build knows which fonts
|
|
16
|
+
* were loaded. What this module exports is what to do with it.
|
|
17
|
+
*/
|
|
18
|
+
export { box, inset } from "./box.js";
|
|
19
|
+
export { distribute } from "./distribute.js";
|
|
20
|
+
export { image } from "./image.js";
|
|
21
|
+
export type { ImageOptions } from "./image.js";
|
|
22
|
+
export { panel } from "./panel.js";
|
|
23
|
+
export type { PanelStyle } from "./panel.js";
|
|
24
|
+
export { row } from "./row.js";
|
|
25
|
+
export type { RowRect } from "./row.js";
|
|
26
|
+
export { scrim } from "./scrim.js";
|
|
27
|
+
export type { ScrimOptions } from "./scrim.js";
|
|
28
|
+
export { stack } from "./stack.js";
|
|
29
|
+
export type { StackedRect } from "./stack.js";
|
|
30
|
+
export type { Align, BoxStyle, Extent, Placed, Rect, Span } from "./types.js";
|
|
31
|
+
export { blockLines } from "./block.js";
|
|
32
|
+
export type { StyledBlock, TextBlock, TextLine } from "./block.js";
|
|
33
|
+
export { baselineFor, drawLines, placeLines } from "./lines.js";
|
|
34
|
+
export type { LinesStyle, PlacedLine } from "./lines.js";
|
|
35
|
+
export { measureIn } from "./measure.js";
|
|
36
|
+
export { optionalString } from "../props.js";
|
|
37
|
+
export { escapeXml, fitText, textElement, wrapText } from "../text/index.js";
|
|
38
|
+
export type { FitOptions, FittedText, MeasureAt, MeasureLine, TextAttributes, } from "../text/index.js";
|
|
39
|
+
export type { Dimensions, MeasureText, MetaImageProps, ResolvedConfig, Template, TemplateContext, TextStyle, } from "../types.js";
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EACV,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,QAAQ,EACR,eAAe,EACf,SAAS,GACV,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout primitives for template authors.
|
|
3
|
+
*
|
|
4
|
+
* Importable on its own as `@kensio/colophon/layout`. Writing a template means
|
|
5
|
+
* returning a string of SVG, and this is the set of small functions that build
|
|
6
|
+
* one: rectangles, panels, images, and the arithmetic of putting things in
|
|
7
|
+
* rows and stacks. It is deliberately boring. Nothing here holds state, every
|
|
8
|
+
* function takes values and returns them, and a template that would rather
|
|
9
|
+
* write its own SVG by hand still can.
|
|
10
|
+
*
|
|
11
|
+
* The subpath loads no rasteriser, no syntax highlighter and nothing from
|
|
12
|
+
* Node, so the whole of it runs anywhere a string does.
|
|
13
|
+
*
|
|
14
|
+
* Measuring is the exception to "import it from here": a template is handed a
|
|
15
|
+
* `MeasureText` on its context, because only the build knows which fonts
|
|
16
|
+
* were loaded. What this module exports is what to do with it.
|
|
17
|
+
*/
|
|
18
|
+
export { box, inset } from "./box.js";
|
|
19
|
+
export { distribute } from "./distribute.js";
|
|
20
|
+
export { image } from "./image.js";
|
|
21
|
+
export { panel } from "./panel.js";
|
|
22
|
+
export { row } from "./row.js";
|
|
23
|
+
export { scrim } from "./scrim.js";
|
|
24
|
+
export { stack } from "./stack.js";
|
|
25
|
+
export { blockLines } from "./block.js";
|
|
26
|
+
export { baselineFor, drawLines, placeLines } from "./lines.js";
|
|
27
|
+
export { measureIn } from "./measure.js";
|
|
28
|
+
export { optionalString } from "../props.js";
|
|
29
|
+
export { escapeXml, fitText, textElement, wrapText } from "../text/index.js";
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { TextLine } from "./block.js";
|
|
2
|
+
import type { Align, Rect } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* The baseline of one line of text sitting in a band of its own font size.
|
|
5
|
+
*
|
|
6
|
+
* A template that has set room aside for a single line, rather than stacking
|
|
7
|
+
* several, wants this rather than a fraction of the font size chosen by eye:
|
|
8
|
+
* the ink then lands inside the band that was written down, so the clear space
|
|
9
|
+
* either side of it is the space that was reserved. The descender takes the
|
|
10
|
+
* rest of the band, which is why the room below a line is not the same as the
|
|
11
|
+
* room above it.
|
|
12
|
+
*/
|
|
13
|
+
export declare function baselineFor(top: number, fontSize: number): number;
|
|
14
|
+
/** How a block of lines is drawn: the font, the fill, and where it sits. */
|
|
15
|
+
export interface LinesStyle {
|
|
16
|
+
readonly fontFamily: string;
|
|
17
|
+
readonly fill: string;
|
|
18
|
+
/** Multiplier on each line's font size. Defaults to `1.2`. */
|
|
19
|
+
readonly lineHeight?: number;
|
|
20
|
+
/** Horizontal anchor. `middle` centres each line in the area. */
|
|
21
|
+
readonly anchor?: "start" | "middle" | "end";
|
|
22
|
+
/** Where the block sits vertically in the area. Defaults to `centre`. */
|
|
23
|
+
readonly align?: Align;
|
|
24
|
+
}
|
|
25
|
+
/** A line with its computed text baseline. */
|
|
26
|
+
export interface PlacedLine {
|
|
27
|
+
readonly y: number;
|
|
28
|
+
readonly index: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Place a block of lines within an area and return each baseline.
|
|
32
|
+
*
|
|
33
|
+
* The lines are placed as one block rather than each finding its own middle,
|
|
34
|
+
* which is what keeps a wrapped title reading as a paragraph. A block taller
|
|
35
|
+
* than its area starts at the top and runs over, since a template that has
|
|
36
|
+
* overflowed wants to see it.
|
|
37
|
+
*/
|
|
38
|
+
export declare function placeLines(lines: readonly TextLine[], area: Rect, lineHeight?: number, align?: Align): readonly PlacedLine[];
|
|
39
|
+
/**
|
|
40
|
+
* Draw a block of lines within an area: place them, then write the `<text>`
|
|
41
|
+
* elements. Once a template has fitted its words, this is the whole of what it
|
|
42
|
+
* does with them.
|
|
43
|
+
*/
|
|
44
|
+
export declare function drawLines(lines: readonly TextLine[], area: Rect, style: LinesStyle): string;
|
|
45
|
+
//# sourceMappingURL=lines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.d.ts","sourceRoot":"","sources":["../../src/layout/lines.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAa9C;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,4EAA4E;AAC5E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC7C,yEAAyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB;AAED,8CAA8C;AAC9C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,IAAI,EAAE,IAAI,EACV,UAAU,SAAoB,EAC9B,KAAK,GAAE,KAAgB,GACtB,SAAS,UAAU,EAAE,CAcvB;AAWD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,UAAU,GAChB,MAAM,CAuBR"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { textElement } from "../text/index.js";
|
|
2
|
+
import { distribute } from "./distribute.js";
|
|
3
|
+
/** Vertical advance of a line, as a multiple of its font size. */
|
|
4
|
+
const defaultLineHeight = 1.2;
|
|
5
|
+
/**
|
|
6
|
+
* Where the baseline sits within a line's advance. A face puts its ascenders
|
|
7
|
+
* around here, and taking it as a fraction of the size rather than as a metric
|
|
8
|
+
* read from the font means a line lands in the same place whichever font the
|
|
9
|
+
* image is eventually drawn in.
|
|
10
|
+
*/
|
|
11
|
+
const baselineRatio = 0.8;
|
|
12
|
+
/**
|
|
13
|
+
* The baseline of one line of text sitting in a band of its own font size.
|
|
14
|
+
*
|
|
15
|
+
* A template that has set room aside for a single line, rather than stacking
|
|
16
|
+
* several, wants this rather than a fraction of the font size chosen by eye:
|
|
17
|
+
* the ink then lands inside the band that was written down, so the clear space
|
|
18
|
+
* either side of it is the space that was reserved. The descender takes the
|
|
19
|
+
* rest of the band, which is why the room below a line is not the same as the
|
|
20
|
+
* room above it.
|
|
21
|
+
*/
|
|
22
|
+
export function baselineFor(top, fontSize) {
|
|
23
|
+
return Math.round(top + fontSize * baselineRatio);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Place a block of lines within an area and return each baseline.
|
|
27
|
+
*
|
|
28
|
+
* The lines are placed as one block rather than each finding its own middle,
|
|
29
|
+
* which is what keeps a wrapped title reading as a paragraph. A block taller
|
|
30
|
+
* than its area starts at the top and runs over, since a template that has
|
|
31
|
+
* overflowed wants to see it.
|
|
32
|
+
*/
|
|
33
|
+
export function placeLines(lines, area, lineHeight = defaultLineHeight, align = "centre") {
|
|
34
|
+
const placed = distribute(lines.map((line) => ({
|
|
35
|
+
size: line.fontSize * lineHeight,
|
|
36
|
+
...(line.gapBefore !== undefined && { gapBefore: line.gapBefore }),
|
|
37
|
+
})), { start: area.y, end: area.y + area.height }, align);
|
|
38
|
+
return placed.map((placement, index) => ({
|
|
39
|
+
y: baselineFor(placement.start, lines[index]?.fontSize ?? 0),
|
|
40
|
+
index,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
/** The x a line is drawn from, which the anchor decides. */
|
|
44
|
+
function anchorX(area, anchor) {
|
|
45
|
+
if (anchor === "middle") {
|
|
46
|
+
return Math.round(area.x + area.width / 2);
|
|
47
|
+
}
|
|
48
|
+
return anchor === "end" ? area.x + area.width : area.x;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Draw a block of lines within an area: place them, then write the `<text>`
|
|
52
|
+
* elements. Once a template has fitted its words, this is the whole of what it
|
|
53
|
+
* does with them.
|
|
54
|
+
*/
|
|
55
|
+
export function drawLines(lines, area, style) {
|
|
56
|
+
const placed = placeLines(lines, area, style.lineHeight ?? defaultLineHeight, style.align ?? "centre");
|
|
57
|
+
const x = anchorX(area, style.anchor);
|
|
58
|
+
return lines
|
|
59
|
+
.map((line, index) => textElement(line.text, {
|
|
60
|
+
x,
|
|
61
|
+
y: placed[index]?.y ?? area.y,
|
|
62
|
+
fontFamily: style.fontFamily,
|
|
63
|
+
fontSize: line.fontSize,
|
|
64
|
+
fontWeight: line.fontWeight,
|
|
65
|
+
fill: style.fill,
|
|
66
|
+
fillOpacity: line.opacity,
|
|
67
|
+
...(style.anchor !== undefined && { anchor: style.anchor }),
|
|
68
|
+
}))
|
|
69
|
+
.join("");
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../src/layout/lines.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,kEAAkE;AAClE,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B;;;;;GAKG;AACH,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,QAAgB;IACvD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,QAAQ,GAAG,aAAa,CAAC,CAAC;AACpD,CAAC;AAoBD;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACxB,KAA0B,EAC1B,IAAU,EACV,UAAU,GAAG,iBAAiB,EAC9B,KAAK,GAAU,QAAQ;IAEvB,MAAM,MAAM,GAAG,UAAU,CACvB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnB,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,UAAU;QAChC,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;KACnE,CAAC,CAAC,EACH,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAC5C,KAAK,CACN,CAAC;IAEF,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACvC,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC;QAC5D,KAAK;KACN,CAAC,CAAC,CAAC;AACN,CAAC;AAED,4DAA4D;AAC5D,SAAS,OAAO,CAAC,IAAU,EAAE,MAA4B;IACvD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACvB,KAA0B,EAC1B,IAAU,EACV,KAAiB;IAEjB,MAAM,MAAM,GAAG,UAAU,CACvB,KAAK,EACL,IAAI,EACJ,KAAK,CAAC,UAAU,IAAI,iBAAiB,EACrC,KAAK,CAAC,KAAK,IAAI,QAAQ,CACxB,CAAC;IACF,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtC,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACnB,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE;QACrB,CAAC;QACD,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC;QAC7B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,WAAW,EAAE,IAAI,CAAC,OAAO;QACzB,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;KAC5D,CAAC,CACH;SACA,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MeasureAt } from "../text/index.js";
|
|
2
|
+
import type { MeasureText } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Bind a measurer to one family and weight, leaving only the size open.
|
|
5
|
+
*
|
|
6
|
+
* That is the shape fitting text wants, since choosing a size is the whole of
|
|
7
|
+
* what it varies, and it keeps a template from repeating the family and weight
|
|
8
|
+
* on every call.
|
|
9
|
+
*/
|
|
10
|
+
export declare function measureIn(measure: MeasureText, fontFamily: string, fontWeight: number): MeasureAt;
|
|
11
|
+
//# sourceMappingURL=measure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../src/layout/measure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,SAAS,CAGX"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bind a measurer to one family and weight, leaving only the size open.
|
|
3
|
+
*
|
|
4
|
+
* That is the shape fitting text wants, since choosing a size is the whole of
|
|
5
|
+
* what it varies, and it keeps a template from repeating the family and weight
|
|
6
|
+
* on every call.
|
|
7
|
+
*/
|
|
8
|
+
export function measureIn(measure, fontFamily, fontWeight) {
|
|
9
|
+
return (text, fontSize) => measure(text, { fontFamily, fontSize, fontWeight });
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=measure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.js","sourceRoot":"","sources":["../../src/layout/measure.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,OAAoB,EACpB,UAAkB,EAClB,UAAkB;IAElB,OAAO,CAAC,IAAY,EAAE,QAAgB,EAAU,EAAE,CAChD,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BoxStyle, Rect } from "./types.js";
|
|
2
|
+
/** A panel is a box that casts a shadow. */
|
|
3
|
+
export interface PanelStyle extends BoxStyle {
|
|
4
|
+
/**
|
|
5
|
+
* How far the shadow falls below the panel. Omit for none, which is right
|
|
6
|
+
* for a panel that is a region of the image rather than a card on top of it.
|
|
7
|
+
*/
|
|
8
|
+
readonly shadow?: number;
|
|
9
|
+
readonly shadowColor?: string;
|
|
10
|
+
readonly shadowOpacity?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A raised plate: a soft shadow, then the surface on top of it.
|
|
14
|
+
*
|
|
15
|
+
* The shadow is a second rectangle rather than a blur filter. It costs a
|
|
16
|
+
* rasteriser nothing, it survives every backend, and at these sizes a hard
|
|
17
|
+
* offset reads as depth just as well as a blurred one.
|
|
18
|
+
*/
|
|
19
|
+
export declare function panel(rect: Rect, style?: PanelStyle): string;
|
|
20
|
+
//# sourceMappingURL=panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/layout/panel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEjD,4CAA4C;AAC5C,MAAM,WAAW,UAAW,SAAQ,QAAQ;IAC1C;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAKD;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,GAAE,UAAe,GAAG,MAAM,CAiBhE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { box } from "./box.js";
|
|
2
|
+
const defaultShadowColor = "#000000";
|
|
3
|
+
const defaultShadowOpacity = 0.22;
|
|
4
|
+
/**
|
|
5
|
+
* A raised plate: a soft shadow, then the surface on top of it.
|
|
6
|
+
*
|
|
7
|
+
* The shadow is a second rectangle rather than a blur filter. It costs a
|
|
8
|
+
* rasteriser nothing, it survives every backend, and at these sizes a hard
|
|
9
|
+
* offset reads as depth just as well as a blurred one.
|
|
10
|
+
*/
|
|
11
|
+
export function panel(rect, style = {}) {
|
|
12
|
+
const { shadow, shadowColor, shadowOpacity, ...surface } = style;
|
|
13
|
+
if (shadow === undefined) {
|
|
14
|
+
return box(rect, surface);
|
|
15
|
+
}
|
|
16
|
+
return (box({ ...rect, y: rect.y + shadow }, {
|
|
17
|
+
...(surface.radius !== undefined && { radius: surface.radius }),
|
|
18
|
+
fill: shadowColor ?? defaultShadowColor,
|
|
19
|
+
fillOpacity: shadowOpacity ?? defaultShadowOpacity,
|
|
20
|
+
}) + box(rect, surface));
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.js","sourceRoot":"","sources":["../../src/layout/panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAc/B,MAAM,kBAAkB,GAAG,SAAS,CAAC;AACrC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAElC;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,IAAU,EAAE,KAAK,GAAe,EAAE;IACtD,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC;IAEjE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,CACL,GAAG,CACD,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,MAAM,EAAE,EAC/B;QACE,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;QAC/D,IAAI,EAAE,WAAW,IAAI,kBAAkB;QACvC,WAAW,EAAE,aAAa,IAAI,oBAAoB;KACnD,CACF,GAAG,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CACvB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Align, Extent, Rect } from "./types.js";
|
|
2
|
+
/** A placed item's rectangle, and which item it belongs to. */
|
|
3
|
+
export interface RowRect extends Rect {
|
|
4
|
+
readonly index: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Set items across an area and give each one its rectangle: an avatar beside a
|
|
8
|
+
* name, a badge beside a title, a row of tags along the bottom.
|
|
9
|
+
*
|
|
10
|
+
* Each keeps the full height of the area, so an item shorter than the row
|
|
11
|
+
* centres itself within the rectangle it was given rather than being told
|
|
12
|
+
* where to sit.
|
|
13
|
+
*/
|
|
14
|
+
export declare function row(items: readonly Extent[], area: Rect, align?: Align): readonly RowRect[];
|
|
15
|
+
//# sourceMappingURL=row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row.d.ts","sourceRoot":"","sources":["../../src/layout/row.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEtD,+DAA+D;AAC/D,MAAM,WAAW,OAAQ,SAAQ,IAAI;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,GAAG,CACjB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,IAAI,EAAE,IAAI,EACV,KAAK,GAAE,KAAgB,GACtB,SAAS,OAAO,EAAE,CAcpB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { distribute } from "./distribute.js";
|
|
2
|
+
/**
|
|
3
|
+
* Set items across an area and give each one its rectangle: an avatar beside a
|
|
4
|
+
* name, a badge beside a title, a row of tags along the bottom.
|
|
5
|
+
*
|
|
6
|
+
* Each keeps the full height of the area, so an item shorter than the row
|
|
7
|
+
* centres itself within the rectangle it was given rather than being told
|
|
8
|
+
* where to sit.
|
|
9
|
+
*/
|
|
10
|
+
export function row(items, area, align = "centre") {
|
|
11
|
+
const placed = distribute(items, { start: area.x, end: area.x + area.width }, align);
|
|
12
|
+
return placed.map((placement, index) => ({
|
|
13
|
+
x: placement.start,
|
|
14
|
+
y: area.y,
|
|
15
|
+
width: items[index]?.size ?? 0,
|
|
16
|
+
height: area.height,
|
|
17
|
+
index: placement.index,
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=row.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row.js","sourceRoot":"","sources":["../../src/layout/row.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQ7C;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,CACjB,KAAwB,EACxB,IAAU,EACV,KAAK,GAAU,QAAQ;IAEvB,MAAM,MAAM,GAAG,UAAU,CACvB,KAAK,EACL,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,EAC3C,KAAK,CACN,CAAC;IAEF,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACvC,CAAC,EAAE,SAAS,CAAC,KAAK;QAClB,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC;QAC9B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,SAAS,CAAC,KAAK;KACvB,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Rect } from "./types.js";
|
|
2
|
+
/** How heavily a scrim shades what is under it, and from which edge. */
|
|
3
|
+
export interface ScrimOptions {
|
|
4
|
+
readonly color?: string;
|
|
5
|
+
/** Opacity at the top edge. Defaults to none, so the image shows through. */
|
|
6
|
+
readonly from?: number;
|
|
7
|
+
/** Opacity at the bottom edge. */
|
|
8
|
+
readonly to?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A wash of colour over an image, so that text on top of it can be read.
|
|
12
|
+
*
|
|
13
|
+
* This is the difference between a designed image and text sitting on a photo.
|
|
14
|
+
* A photograph has light and dark in it wherever it likes, and white text over
|
|
15
|
+
* a bright sky is invisible; a gradient from clear at the top to dark at the
|
|
16
|
+
* bottom keeps a headline legible without hiding the picture.
|
|
17
|
+
*
|
|
18
|
+
* `id` names the gradient and has to be unique within the image. A flat wash
|
|
19
|
+
* needs no gradient, so it needs no `id` either: pass the same value for
|
|
20
|
+
* `from` and `to`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function scrim(rect: Rect, id: string, options?: ScrimOptions): string;
|
|
23
|
+
//# sourceMappingURL=scrim.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrim.d.ts","sourceRoot":"","sources":["../../src/layout/scrim.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;CACtB;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CACnB,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,YAAiB,GACzB,MAAM,CA0BR"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { escapeXml } from "../text/index.js";
|
|
2
|
+
import { box } from "./box.js";
|
|
3
|
+
const defaultColor = "#000000";
|
|
4
|
+
/**
|
|
5
|
+
* A wash of colour over an image, so that text on top of it can be read.
|
|
6
|
+
*
|
|
7
|
+
* This is the difference between a designed image and text sitting on a photo.
|
|
8
|
+
* A photograph has light and dark in it wherever it likes, and white text over
|
|
9
|
+
* a bright sky is invisible; a gradient from clear at the top to dark at the
|
|
10
|
+
* bottom keeps a headline legible without hiding the picture.
|
|
11
|
+
*
|
|
12
|
+
* `id` names the gradient and has to be unique within the image. A flat wash
|
|
13
|
+
* needs no gradient, so it needs no `id` either: pass the same value for
|
|
14
|
+
* `from` and `to`.
|
|
15
|
+
*/
|
|
16
|
+
export function scrim(rect, id, options = {}) {
|
|
17
|
+
const from = options.from ?? 0;
|
|
18
|
+
const to = options.to ?? 0.55;
|
|
19
|
+
if (from === to) {
|
|
20
|
+
return box(rect, {
|
|
21
|
+
fill: options.color ?? defaultColor,
|
|
22
|
+
fillOpacity: from,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Escaped here for the reason `box` escapes what it is given: both of these
|
|
26
|
+
// may have come from a post's frontmatter by way of a template. The fill
|
|
27
|
+
// below takes the id raw, since `box` does its own escaping and the two
|
|
28
|
+
// attributes have to agree once parsed rather than as written.
|
|
29
|
+
const color = escapeXml(options.color ?? defaultColor);
|
|
30
|
+
const gradient = `<defs>` +
|
|
31
|
+
`<linearGradient id="${escapeXml(id)}" x1="0" y1="0" x2="0" y2="1">` +
|
|
32
|
+
`<stop offset="0%" stop-color="${color}" stop-opacity="${String(from)}"/>` +
|
|
33
|
+
`<stop offset="100%" stop-color="${color}" stop-opacity="${String(to)}"/>` +
|
|
34
|
+
`</linearGradient>` +
|
|
35
|
+
`</defs>`;
|
|
36
|
+
return gradient + box(rect, { fill: `url(#${id})` });
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=scrim.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrim.js","sourceRoot":"","sources":["../../src/layout/scrim.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAY/B,MAAM,YAAY,GAAG,SAAS,CAAC;AAE/B;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,KAAK,CACnB,IAAU,EACV,EAAU,EACV,OAAO,GAAiB,EAAE;IAE1B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;IAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC;IAE9B,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChB,OAAO,GAAG,CAAC,IAAI,EAAE;YACf,IAAI,EAAE,OAAO,CAAC,KAAK,IAAI,YAAY;YACnC,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;IACL,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,wEAAwE;IACxE,+DAA+D;IAC/D,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,CAAC;IAEvD,MAAM,QAAQ,GACZ,QAAQ;QACR,uBAAuB,SAAS,CAAC,EAAE,CAAC,gCAAgC;QACpE,iCAAiC,KAAK,mBAAmB,MAAM,CAAC,IAAI,CAAC,KAAK;QAC1E,mCAAmC,KAAK,mBAAmB,MAAM,CAAC,EAAE,CAAC,KAAK;QAC1E,mBAAmB;QACnB,SAAS,CAAC;IAEZ,OAAO,QAAQ,GAAG,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;AACvD,CAAC"}
|