@cardanvil/frame-kit 0.6.0 → 0.7.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.
Files changed (66) hide show
  1. package/README.md +75 -1
  2. package/dist/authoring/collectorInfo.d.ts +17 -0
  3. package/dist/authoring/collectorInfo.js +62 -0
  4. package/dist/authoring/index.d.ts +2 -0
  5. package/dist/authoring/index.js +2 -0
  6. package/dist/authoring/layoutDefaults.d.ts +20 -2
  7. package/dist/authoring/layoutDefaults.js +48 -13
  8. package/dist/authoring/opacityStops.d.ts +8 -0
  9. package/dist/authoring/opacityStops.js +17 -0
  10. package/dist/cli/index.d.ts +1 -0
  11. package/dist/cli/index.js +1 -0
  12. package/dist/cli/loadFrame.js +1 -1
  13. package/dist/cli/main.js +72 -0
  14. package/dist/cli/studio/boxSets.js +11 -8
  15. package/dist/cli/studio/serve.js +4 -1
  16. package/dist/cli/trim.d.ts +62 -0
  17. package/dist/cli/trim.js +251 -0
  18. package/dist/layout/border.d.ts +27 -0
  19. package/dist/layout/border.js +31 -0
  20. package/dist/layout/boxOverrides.d.ts +28 -0
  21. package/dist/layout/boxOverrides.js +95 -0
  22. package/dist/layout/color.d.ts +23 -0
  23. package/dist/layout/color.js +53 -0
  24. package/dist/layout/cutouts.d.ts +28 -0
  25. package/dist/layout/cutouts.js +29 -0
  26. package/dist/layout/decorations.d.ts +1 -6
  27. package/dist/layout/decorations.js +7 -11
  28. package/dist/layout/frameLayers.d.ts +29 -2
  29. package/dist/layout/frameLayers.js +145 -3
  30. package/dist/layout/index.d.ts +17 -6
  31. package/dist/layout/index.js +17 -6
  32. package/dist/layout/paint.d.ts +36 -0
  33. package/dist/layout/paint.js +148 -0
  34. package/dist/layout/powerToughnessRow.d.ts +26 -0
  35. package/dist/layout/powerToughnessRow.js +13 -0
  36. package/dist/layout/resolveFrameAsset.d.ts +6 -0
  37. package/dist/layout/resolveFrameAsset.js +8 -0
  38. package/dist/layout/rulesSlide.d.ts +13 -0
  39. package/dist/layout/rulesSlide.js +33 -0
  40. package/dist/layout/settings.d.ts +26 -0
  41. package/dist/layout/settings.js +62 -0
  42. package/dist/layout/textStyle.d.ts +29 -0
  43. package/dist/layout/textStyle.js +28 -0
  44. package/dist/layout/turn.d.ts +54 -0
  45. package/dist/layout/turn.js +107 -0
  46. package/dist/manifest/contract.d.ts +6074 -9392
  47. package/dist/manifest/contract.js +46 -1
  48. package/dist/manifest/testFrame.js +9 -0
  49. package/dist/schema/collectorInfo.d.ts +95 -0
  50. package/dist/schema/collectorInfo.js +80 -0
  51. package/dist/schema/condition.d.ts +67 -0
  52. package/dist/schema/condition.js +47 -0
  53. package/dist/schema/frame.d.ts +17291 -25435
  54. package/dist/schema/frame.js +402 -14
  55. package/dist/schema/frameAssets.d.ts +53 -33
  56. package/dist/schema/frameAssets.js +77 -5
  57. package/dist/schema/index.d.ts +3 -0
  58. package/dist/schema/index.js +3 -0
  59. package/dist/schema/layout.d.ts +29 -4
  60. package/dist/schema/layout.js +27 -2
  61. package/dist/schema/paint.d.ts +202 -0
  62. package/dist/schema/paint.js +109 -0
  63. package/dist/studio/assets/index-BnhNwm_r.js +74 -0
  64. package/dist/studio/index.html +1 -1
  65. package/package.json +5 -3
  66. package/dist/studio/assets/index-CNzyV22G.js +0 -76
@@ -13,12 +13,57 @@ import { FrameSchema } from "../schema/frame.js";
13
13
  * render with reduced fidelity.
14
14
  *
15
15
  * Version history:
16
+ * - 1.13: added the optional `fonts` a frame ships; the optional `gradients`,
17
+ * `tintedImages`, `rulesSlide` and `manaSymbols` on a layout; the optional
18
+ * `power` and `toughness` text boxes; the optional `shadowBlur` on text
19
+ * boxes; the optional `frameColor` condition on text box `overrides`; and
20
+ * the optional `when` on gradients and tinted images, the same conditions
21
+ * as `overrides`, so a template setting can pick which are drawn; and the
22
+ * optional `powerToughnessRow` on a layout, with `ptSlot` on the tinted
23
+ * images it places; the optional planeswalker `abilityDivider`, a
24
+ * gradient painted where each two abilities meet; and the optional
25
+ * `anchor` on gradients, the box one moves with.
26
+ * A layout's `base` frame art may now be empty, for a frame with none.
27
+ * - 1.12: added the optional planeswalker knobs `abilityFill`,
28
+ * `abilityFillSize`, `minFontSize`, `lineHeightRatio`, `badgeSlotHeight` and
29
+ * `loyaltyReserve`, which space and size abilities laid out as a column of
30
+ * sections, and `separatorOffsetY`,
31
+ * which places the separators between their bands; `topPadding`,
32
+ * `bottomPadding` and `textFillThreshold` are no longer read.
33
+ * - 1.11: added the optional `sectionDividers` on a layout, fixed dividers
34
+ * drawn with `sectionDivider`; and an `alternateLayouts` entry can now be
35
+ * named by a layout's own select setting as well as by `frameVariant`.
36
+ * - 1.10: added the optional `sectionDivider` frame asset, drawn between the
37
+ * sections of a Case's or Class's column.
38
+ * - 1.9: added the optional `adventureRules`, `adventureRulesRight`,
39
+ * `rulesRight` and `wings` layout masks, colouring the two pages and the
40
+ * page edges of a storybook Adventure's text box on their own.
41
+ * - 1.8: added the optional `fullBorder` frame asset, border art drawn under
42
+ * the base frame while `useFullBorder` is on; the optional
43
+ * `outlineColor`/`outlineWidth` on the set symbol box; the optional
44
+ * `tallMasks`, the planeswalker tall frame's own masks; and the optional
45
+ * planeswalker knobs `abilityBacking` and the loyalty badge and cost
46
+ * offsets. The planeswalker `separator` asset became optional, so a frame
47
+ * that leaves it out needs a 1.8 loader.
48
+ * - 1.7: added the optional `firstArt` on a box set and `art` on a second
49
+ * face's set: the windows a card's two arts go in once it has a second one.
50
+ * - 1.6: added the optional `rotation` on a box set, for text and art read
51
+ * with the card turned; the optional `secondFaceBoxes` set, for a second
52
+ * face printed on the same side as the first; the optional `defense` and
53
+ * `fuse` text boxes; and the `aftermath` layout.
54
+ * - 1.5: added the optional `insetTitle`, `insetMana`, `insetType` and
55
+ * `insetRules` text boxes for the spell inset in an Adventure, Omen or
56
+ * Prepare card's text box, and the `omen` and `prepare` layouts.
57
+ * - 1.4: added the optional `overrides` on text boxes, conditional restyles
58
+ * matched against the border settings and template settings. Also the
59
+ * optional `shadowOffsetX`/`shadowOffsetY` on text boxes,
60
+ * `lines` on the collector info box, and the `dividerBar*` frame assets.
16
61
  * - 1.3: added the optional `border` layout mask, isolating the outer
17
62
  * border ring's own shape so it can be recolored.
18
63
  * - 1.2: added the optional `mask` asset URL on text boxes (shaped text).
19
64
  * - 1.1: added the optional `license` field on the manifest.
20
65
  */
21
- export const CONTRACT_VERSION = "1.3";
66
+ export const CONTRACT_VERSION = "1.13";
22
67
  /** The only manifest kind any loader understands today. */
23
68
  export const DECLARATIVE_KIND = "declarative";
24
69
  export const AssetEntrySchema = z.object({
@@ -38,6 +38,15 @@ export const testFrame = {
38
38
  color: "white",
39
39
  outlineColor: "black",
40
40
  fontFamily: "Beleren",
41
+ overrides: [
42
+ {
43
+ when: {
44
+ border: ["light", "none"],
45
+ settings: { style: "modern" },
46
+ },
47
+ style: { color: "black" },
48
+ },
49
+ ],
41
50
  },
42
51
  type: { x: 0, y: 0, width: 10, height: 10, fontSize: 12 },
43
52
  setSymbol: { x: 0, y: 0, width: 10, height: 10 },
@@ -0,0 +1,95 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * A value the collector line can print. Each resolves from the card and the
4
+ * user's field settings at render time, except `separator` and `artistSymbol`,
5
+ * which are glyphs.
6
+ */
7
+ export declare const CollectorInfoElementTypeSchema: z.ZodEnum<{
8
+ rarity: "rarity";
9
+ cardNumber: "cardNumber";
10
+ creatorName: "creatorName";
11
+ setCode: "setCode";
12
+ separator: "separator";
13
+ language: "language";
14
+ artistSymbol: "artistSymbol";
15
+ artist: "artist";
16
+ }>;
17
+ export type CollectorInfoElementType = z.infer<typeof CollectorInfoElementTypeSchema>;
18
+ export declare const CollectorInfoElementSchema: z.ZodObject<{
19
+ type: z.ZodEnum<{
20
+ rarity: "rarity";
21
+ cardNumber: "cardNumber";
22
+ creatorName: "creatorName";
23
+ setCode: "setCode";
24
+ separator: "separator";
25
+ language: "language";
26
+ artistSymbol: "artistSymbol";
27
+ artist: "artist";
28
+ }>;
29
+ useManaFont: z.ZodOptional<z.ZodBoolean>;
30
+ manaSymbol: z.ZodOptional<z.ZodString>;
31
+ fontSizeMultiplier: z.ZodOptional<z.ZodNumber>;
32
+ fontSizeMultiplierDot: z.ZodOptional<z.ZodNumber>;
33
+ fontSizeMultiplierStar: z.ZodOptional<z.ZodNumber>;
34
+ yOffset: z.ZodOptional<z.ZodNumber>;
35
+ yOffsetDot: z.ZodOptional<z.ZodNumber>;
36
+ yOffsetStar: z.ZodOptional<z.ZodNumber>;
37
+ spacingAfter: z.ZodOptional<z.ZodNumber>;
38
+ letterSpacing: z.ZodOptional<z.ZodNumber>;
39
+ minXFromElement: z.ZodOptional<z.ZodEnum<{
40
+ rarity: "rarity";
41
+ cardNumber: "cardNumber";
42
+ creatorName: "creatorName";
43
+ setCode: "setCode";
44
+ separator: "separator";
45
+ language: "language";
46
+ artistSymbol: "artistSymbol";
47
+ artist: "artist";
48
+ }>>;
49
+ prefix: z.ZodOptional<z.ZodString>;
50
+ }, z.core.$strip>;
51
+ export type CollectorInfoElement = z.infer<typeof CollectorInfoElementSchema>;
52
+ /** One line of the collector box: elements drawn left to right. */
53
+ export declare const CollectorInfoLineSchema: z.ZodObject<{
54
+ elements: z.ZodReadonly<z.ZodArray<z.ZodObject<{
55
+ type: z.ZodEnum<{
56
+ rarity: "rarity";
57
+ cardNumber: "cardNumber";
58
+ creatorName: "creatorName";
59
+ setCode: "setCode";
60
+ separator: "separator";
61
+ language: "language";
62
+ artistSymbol: "artistSymbol";
63
+ artist: "artist";
64
+ }>;
65
+ useManaFont: z.ZodOptional<z.ZodBoolean>;
66
+ manaSymbol: z.ZodOptional<z.ZodString>;
67
+ fontSizeMultiplier: z.ZodOptional<z.ZodNumber>;
68
+ fontSizeMultiplierDot: z.ZodOptional<z.ZodNumber>;
69
+ fontSizeMultiplierStar: z.ZodOptional<z.ZodNumber>;
70
+ yOffset: z.ZodOptional<z.ZodNumber>;
71
+ yOffsetDot: z.ZodOptional<z.ZodNumber>;
72
+ yOffsetStar: z.ZodOptional<z.ZodNumber>;
73
+ spacingAfter: z.ZodOptional<z.ZodNumber>;
74
+ letterSpacing: z.ZodOptional<z.ZodNumber>;
75
+ minXFromElement: z.ZodOptional<z.ZodEnum<{
76
+ rarity: "rarity";
77
+ cardNumber: "cardNumber";
78
+ creatorName: "creatorName";
79
+ setCode: "setCode";
80
+ separator: "separator";
81
+ language: "language";
82
+ artistSymbol: "artistSymbol";
83
+ artist: "artist";
84
+ }>>;
85
+ prefix: z.ZodOptional<z.ZodString>;
86
+ }, z.core.$strip>>>;
87
+ spacing: z.ZodOptional<z.ZodNumber>;
88
+ align: z.ZodOptional<z.ZodEnum<{
89
+ left: "left";
90
+ center: "center";
91
+ }>>;
92
+ fontSizeMultiplier: z.ZodOptional<z.ZodNumber>;
93
+ fontFamily: z.ZodOptional<z.ZodString>;
94
+ }, z.core.$strip>;
95
+ export type CollectorInfoLine = z.infer<typeof CollectorInfoLineSchema>;
@@ -0,0 +1,80 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * A value the collector line can print. Each resolves from the card and the
4
+ * user's field settings at render time, except `separator` and `artistSymbol`,
5
+ * which are glyphs.
6
+ */
7
+ export const CollectorInfoElementTypeSchema = z.enum([
8
+ "rarity",
9
+ "cardNumber",
10
+ "creatorName",
11
+ "setCode",
12
+ /** Dot or star, per the user's separator setting (from the mana font). */
13
+ "separator",
14
+ "language",
15
+ /** The paintbrush glyph (from the mana font). */
16
+ "artistSymbol",
17
+ "artist",
18
+ ]);
19
+ export const CollectorInfoElementSchema = z.object({
20
+ type: CollectorInfoElementTypeSchema,
21
+ /** Draw in Manadings-Regular (for `separator` and `artistSymbol`). */
22
+ useManaFont: z.boolean().optional(),
23
+ /** The mana-font character to draw, e.g. `"a"` for the artist symbol. */
24
+ manaSymbol: z.string().optional(),
25
+ /** Multiplier on the box's font size. Default 1.0. */
26
+ fontSizeMultiplier: z.number().optional(),
27
+ /** `fontSizeMultiplier` for the dot separator only. */
28
+ fontSizeMultiplierDot: z.number().optional(),
29
+ /** `fontSizeMultiplier` for the star separator only. */
30
+ fontSizeMultiplierStar: z.number().optional(),
31
+ /** Vertical offset in px, positive down. */
32
+ yOffset: z.number().optional(),
33
+ /** `yOffset` for the dot separator only. */
34
+ yOffsetDot: z.number().optional(),
35
+ /** `yOffset` for the star separator only. */
36
+ yOffsetStar: z.number().optional(),
37
+ /** Space after this element in px, overriding the line's `spacing`. */
38
+ spacingAfter: z.number().optional(),
39
+ /**
40
+ * Per-element letter spacing in px, overriding the collector box's
41
+ * `letterSpacing` for this element's characters (e.g. tighten the artist
42
+ * name while the rarity/number keep the box tracking). Absolute px like
43
+ * `spacingAfter` — it does not scale with `fontSizeMultiplier`. Set `0` to
44
+ * render this element untracked while the box has tracking.
45
+ */
46
+ letterSpacing: z.number().optional(),
47
+ /**
48
+ * When set, this element's x position is never less than the x position of
49
+ * the referenced element type on another line. If the elements before this
50
+ * one on the same line already extend past that position, this element
51
+ * follows naturally. Used to align the creator name with the artist symbol.
52
+ */
53
+ minXFromElement: CollectorInfoElementTypeSchema.optional(),
54
+ /**
55
+ * Literal text prepended to the resolved value (e.g. "Illus. " before the
56
+ * artist name). Omitted entirely if the value is empty.
57
+ */
58
+ prefix: z.string().optional(),
59
+ });
60
+ /** One line of the collector box: elements drawn left to right. */
61
+ export const CollectorInfoLineSchema = z.object({
62
+ elements: z.array(CollectorInfoElementSchema).readonly(),
63
+ /** Space between elements in px. Default 10. */
64
+ spacing: z.number().optional(),
65
+ /**
66
+ * Horizontal alignment within the box's width. Defaults to "left" (the
67
+ * elements flow left-to-right from the box's left edge).
68
+ */
69
+ align: z.enum(["left", "center"]).optional(),
70
+ /**
71
+ * Multiplier applied to every element's font size on this line, stacking
72
+ * with each element's own `fontSizeMultiplier`. Default 1.0.
73
+ */
74
+ fontSizeMultiplier: z.number().optional(),
75
+ /**
76
+ * Overrides the font family for every text element on this line (the
77
+ * artist/creator-name/Gotham default otherwise used per element type).
78
+ */
79
+ fontFamily: z.string().optional(),
80
+ });
@@ -0,0 +1,67 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * The frame's outer border as the renderer is about to draw it — what a
4
+ * `RenderCondition` matches on through `border`:
5
+ *
6
+ * - `"default"`: the frame's own border art, untouched by any border setting.
7
+ * - `"light"` / `"dark"`: a user border color recolors the ring, because the
8
+ * layout ships a `border` mask (or `borderFull`, under `useFullBorder`).
9
+ * `"light"` when black text reads better on the chosen color (WCAG
10
+ * contrast), `"dark"` when white does.
11
+ * - `"none"`: "No Border" is on and the layout ships a `noBorder` mask, so the
12
+ * ring is cut away and whatever sat on it now sits over the art.
13
+ *
14
+ * Only a layout with those masks ever leaves `"default"`, so a condition on
15
+ * any other state never fires for a frame whose border cannot be recolored or
16
+ * removed.
17
+ */
18
+ export declare const BorderStateSchema: z.ZodEnum<{
19
+ default: "default";
20
+ light: "light";
21
+ dark: "dark";
22
+ none: "none";
23
+ }>;
24
+ export type BorderState = z.infer<typeof BorderStateSchema>;
25
+ /**
26
+ * What must hold for one render for something conditional to apply: a text
27
+ * box's `overrides`, a gradient or a tinted image. Every condition named must
28
+ * hold; a condition left out matches anything.
29
+ */
30
+ export declare const RenderConditionSchema: z.ZodObject<{
31
+ border: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
32
+ default: "default";
33
+ light: "light";
34
+ dark: "dark";
35
+ none: "none";
36
+ }>, z.ZodReadonly<z.ZodArray<z.ZodEnum<{
37
+ default: "default";
38
+ light: "light";
39
+ dark: "dark";
40
+ none: "none";
41
+ }>>>]>>;
42
+ settings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString, z.ZodNumber]>>>;
43
+ frameColor: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
44
+ a: "a";
45
+ w: "w";
46
+ u: "u";
47
+ b: "b";
48
+ r: "r";
49
+ g: "g";
50
+ m: "m";
51
+ c: "c";
52
+ l: "l";
53
+ v: "v";
54
+ }>, z.ZodReadonly<z.ZodArray<z.ZodEnum<{
55
+ a: "a";
56
+ w: "w";
57
+ u: "u";
58
+ b: "b";
59
+ r: "r";
60
+ g: "g";
61
+ m: "m";
62
+ c: "c";
63
+ l: "l";
64
+ v: "v";
65
+ }>>>]>>;
66
+ }, z.core.$strip>;
67
+ export type RenderCondition = z.infer<typeof RenderConditionSchema>;
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import { FrameColorEnum } from "./frameAssets.js";
3
+ /**
4
+ * The frame's outer border as the renderer is about to draw it — what a
5
+ * `RenderCondition` matches on through `border`:
6
+ *
7
+ * - `"default"`: the frame's own border art, untouched by any border setting.
8
+ * - `"light"` / `"dark"`: a user border color recolors the ring, because the
9
+ * layout ships a `border` mask (or `borderFull`, under `useFullBorder`).
10
+ * `"light"` when black text reads better on the chosen color (WCAG
11
+ * contrast), `"dark"` when white does.
12
+ * - `"none"`: "No Border" is on and the layout ships a `noBorder` mask, so the
13
+ * ring is cut away and whatever sat on it now sits over the art.
14
+ *
15
+ * Only a layout with those masks ever leaves `"default"`, so a condition on
16
+ * any other state never fires for a frame whose border cannot be recolored or
17
+ * removed.
18
+ */
19
+ export const BorderStateSchema = z.enum(["default", "light", "dark", "none"]);
20
+ /**
21
+ * What must hold for one render for something conditional to apply: a text
22
+ * box's `overrides`, a gradient or a tinted image. Every condition named must
23
+ * hold; a condition left out matches anything.
24
+ */
25
+ export const RenderConditionSchema = z.object({
26
+ /** The border state to match; an array matches any of its states. */
27
+ border: z
28
+ .union([BorderStateSchema, z.array(BorderStateSchema).readonly()])
29
+ .optional(),
30
+ /**
31
+ * Template settings that must hold, each compared with `===` against the
32
+ * value in effect for the layout — frame- and layout-level settings
33
+ * merged, defaults included. E.g. `{ useFullBorder: true }`.
34
+ */
35
+ settings: z
36
+ .record(z.string(), z.union([z.boolean(), z.string(), z.number()]))
37
+ .optional(),
38
+ /**
39
+ * The card's frame color — its background, the color its base frame is
40
+ * picked by: `w`/`u`/`b`/`r`/`g` for one color, `m` for gold and
41
+ * two-color hybrids, `a`, `c`, `l` or `v` for artifacts, colorless cards,
42
+ * lands and vehicles. An array matches any of its colors.
43
+ */
44
+ frameColor: z
45
+ .union([FrameColorEnum, z.array(FrameColorEnum).readonly()])
46
+ .optional(),
47
+ });