mochi-avatar 1.0.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 (96) hide show
  1. package/BRAND.md +85 -0
  2. package/LICENSE.md +104 -0
  3. package/README.md +135 -0
  4. package/dist/canvas2d/avatar.d.ts +264 -0
  5. package/dist/canvas2d/avatar.d.ts.map +1 -0
  6. package/dist/canvas2d/avatar.js +811 -0
  7. package/dist/canvas2d/avatar.js.map +1 -0
  8. package/dist/canvas2d/face.d.ts +74 -0
  9. package/dist/canvas2d/face.d.ts.map +1 -0
  10. package/dist/canvas2d/face.js +298 -0
  11. package/dist/canvas2d/face.js.map +1 -0
  12. package/dist/canvas2d/paths.d.ts +13 -0
  13. package/dist/canvas2d/paths.d.ts.map +1 -0
  14. package/dist/canvas2d/paths.js +24 -0
  15. package/dist/canvas2d/paths.js.map +1 -0
  16. package/dist/characters/colourways.d.ts +78 -0
  17. package/dist/characters/colourways.d.ts.map +1 -0
  18. package/dist/characters/colourways.js +76 -0
  19. package/dist/characters/colourways.js.map +1 -0
  20. package/dist/characters/index.d.ts +8 -0
  21. package/dist/characters/index.d.ts.map +1 -0
  22. package/dist/characters/index.js +8 -0
  23. package/dist/characters/index.js.map +1 -0
  24. package/dist/characters/mochi.d.ts +19 -0
  25. package/dist/characters/mochi.d.ts.map +1 -0
  26. package/dist/characters/mochi.js +66 -0
  27. package/dist/characters/mochi.js.map +1 -0
  28. package/dist/core/colour.d.ts +25 -0
  29. package/dist/core/colour.d.ts.map +1 -0
  30. package/dist/core/colour.js +37 -0
  31. package/dist/core/colour.js.map +1 -0
  32. package/dist/core/envelope.d.ts +153 -0
  33. package/dist/core/envelope.d.ts.map +1 -0
  34. package/dist/core/envelope.js +141 -0
  35. package/dist/core/envelope.js.map +1 -0
  36. package/dist/core/geometry.d.ts +106 -0
  37. package/dist/core/geometry.d.ts.map +1 -0
  38. package/dist/core/geometry.js +157 -0
  39. package/dist/core/geometry.js.map +1 -0
  40. package/dist/core/idle.d.ts +163 -0
  41. package/dist/core/idle.d.ts.map +1 -0
  42. package/dist/core/idle.js +262 -0
  43. package/dist/core/idle.js.map +1 -0
  44. package/dist/core/layout.d.ts +142 -0
  45. package/dist/core/layout.d.ts.map +1 -0
  46. package/dist/core/layout.js +172 -0
  47. package/dist/core/layout.js.map +1 -0
  48. package/dist/core/lens.d.ts +47 -0
  49. package/dist/core/lens.d.ts.map +1 -0
  50. package/dist/core/lens.js +67 -0
  51. package/dist/core/lens.js.map +1 -0
  52. package/dist/core/looks.d.ts +77 -0
  53. package/dist/core/looks.d.ts.map +1 -0
  54. package/dist/core/looks.js +168 -0
  55. package/dist/core/looks.js.map +1 -0
  56. package/dist/core/motion.d.ts +168 -0
  57. package/dist/core/motion.d.ts.map +1 -0
  58. package/dist/core/motion.js +527 -0
  59. package/dist/core/motion.js.map +1 -0
  60. package/dist/core/mouth.d.ts +93 -0
  61. package/dist/core/mouth.d.ts.map +1 -0
  62. package/dist/core/mouth.js +92 -0
  63. package/dist/core/mouth.js.map +1 -0
  64. package/dist/core/plain.d.ts +23 -0
  65. package/dist/core/plain.d.ts.map +1 -0
  66. package/dist/core/plain.js +63 -0
  67. package/dist/core/plain.js.map +1 -0
  68. package/dist/core/spec.d.ts +156 -0
  69. package/dist/core/spec.d.ts.map +1 -0
  70. package/dist/core/spec.js +236 -0
  71. package/dist/core/spec.js.map +1 -0
  72. package/dist/core/spring.d.ts +53 -0
  73. package/dist/core/spring.d.ts.map +1 -0
  74. package/dist/core/spring.js +68 -0
  75. package/dist/core/spring.js.map +1 -0
  76. package/dist/core/vocabulary.d.ts +182 -0
  77. package/dist/core/vocabulary.d.ts.map +1 -0
  78. package/dist/core/vocabulary.js +66 -0
  79. package/dist/core/vocabulary.js.map +1 -0
  80. package/dist/element/dough-avatar.d.ts +34 -0
  81. package/dist/element/dough-avatar.d.ts.map +1 -0
  82. package/dist/element/dough-avatar.js +189 -0
  83. package/dist/element/dough-avatar.js.map +1 -0
  84. package/dist/element/index.d.ts +3 -0
  85. package/dist/element/index.d.ts.map +1 -0
  86. package/dist/element/index.js +35 -0
  87. package/dist/element/index.js.map +1 -0
  88. package/dist/index.d.ts +38 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +42 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/svg/silhouette.d.ts +97 -0
  93. package/dist/svg/silhouette.d.ts.map +1 -0
  94. package/dist/svg/silhouette.js +143 -0
  95. package/dist/svg/silhouette.js.map +1 -0
  96. package/package.json +90 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar.js","sourceRoot":"","sources":["../../src/canvas2d/avatar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Her face: cheeks, eyes, the catchlight, and the mouth.
3
+ *
4
+ * Split out of `mochi.ts` so the composition root stays readable, and split at
5
+ * THIS seam on purpose. The layer ORDER is an architectural rule -- idle, then
6
+ * expression, then the mouth, always last -- and an order
7
+ * can only be read off the place the calls are written. So the ordering stays
8
+ * in `paint()` where it is visible in four consecutive lines, and only the
9
+ * implementations moved here.
10
+ *
11
+ * Free functions taking an explicit context rather than methods on a class:
12
+ * none of these hold state, and passing `ctx` in makes it obvious that they
13
+ * paint wherever they are told rather than into somewhere they own.
14
+ */
15
+ import type { FaceSpec } from '../core/spec.js';
16
+ import type { Look } from '../core/looks.js';
17
+ import type { Point } from '../core/geometry.js';
18
+ /** Where a feature sits, in canvas space. Supplied by the caller's body frame. */
19
+ export type Place = (normalisedX: number, normalisedY: number) => Point;
20
+ export declare function paintCheeks(ctx: CanvasRenderingContext2D, face: FaceSpec, look: Look, place: Place, scale: number): void;
21
+ /**
22
+ * How far one lid is open, given the expression and the blink.
23
+ *
24
+ * ## The floor is on the PRODUCT, and that is the whole of this function
25
+ *
26
+ * It used to be on the blink alone -- `Math.max(0.04, 1 - blink)` -- which
27
+ * holds only while the expression leaves the eye at full height. `sleepy` does
28
+ * not: it takes the arcs to `0.16` before the blink is applied, so a held
29
+ * blink produced `0.16 x 0.04`, six thousandths of an eye, and she slept with
30
+ * no eyes at all rather than with shut ones.
31
+ *
32
+ * That was reachable the day `sleepy` became the rest pose and not before,
33
+ * which is exactly why the guarantee belongs on the number that is drawn
34
+ * rather than on one of its factors. Any expression, any blink: the lid is
35
+ * never thinner than `MIN_LID`.
36
+ */
37
+ export declare function lidScale(look: number, blink: number): number;
38
+ /**
39
+ * The two lid extents, with the minimum enforced on what is actually DRAWN.
40
+ *
41
+ * `lidScale` floors each lid on its own, and that is not enough. The eye's
42
+ * rendered height is the SUM of the two — `lower` is signed, and a crescent's
43
+ * negative lower bows the bottom edge up toward the top one — so both lids can
44
+ * sit exactly on the floor with opposite signs and cancel to nothing. A happy
45
+ * face late in a blink did precisely that: two lids at the minimum, an eye of
46
+ * zero height, which is the one outcome `MIN_LID` exists to prevent.
47
+ *
48
+ * Two things about the floor are easy to get wrong, and the first attempt got
49
+ * both:
50
+ *
51
+ * It is a fraction of the eye's own RESTING SPAN — `eyeUpper + eyeLower` — and
52
+ * not of the sum of the two magnitudes. Those are the same number for an eye
53
+ * whose lids both bulge outward, and wildly different for a crescent, where the
54
+ * lids nearly cancel by design. Measured against magnitudes, a face drawn with
55
+ * `eyeUpper: 4, eyeLower: -3.8` had a floor larger than its entire open eye, so
56
+ * it was flattened at rest, at blink zero, in the neutral pose.
57
+ *
58
+ * And when the span is short, only the BOTTOM edge moves: the top arc is left
59
+ * exactly where the expression put it. Collapsing to an evenly split hairline
60
+ * instead made the eye jump — a crescent one frame, a flat sliver the next, its
61
+ * midpoint snapping across the eye. Lifting the lower edge to meet the floor is
62
+ * continuous through the moment it crosses the baseline, so the eye passes from
63
+ * crescent to flat to ordinary lens without a visible step.
64
+ *
65
+ * A face with both extents at zero is left alone. That is a designer asking for
66
+ * no eye at all, the same way `eyeGlint: 0` asks for no catchlight.
67
+ */
68
+ export declare function lidPair(face: FaceSpec, look: Look, blink: number, scale: number): {
69
+ upper: number;
70
+ lower: number;
71
+ };
72
+ export declare function paintEyes(ctx: CanvasRenderingContext2D, face: FaceSpec, look: Look, blink: number, gaze: Point, place: Place, scale: number): void;
73
+ export declare function paintMouth(ctx: CanvasRenderingContext2D, face: FaceSpec, look: Look, mouthOpen: number, place: Place, scale: number): void;
74
+ //# sourceMappingURL=face.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"face.d.ts","sourceRoot":"","sources":["../../src/canvas2d/face.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAGhD,kFAAkF;AAClF,MAAM,MAAM,KAAK,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,KAAK,CAAA;AAwBvE,wBAAgB,WAAW,CACzB,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,GACZ,IAAI,CA6BN;AAUD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAwC5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAYlC;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,GACZ,IAAI,CAoBN;AA2FD,wBAAgB,UAAU,CACxB,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,GACZ,IAAI,CA8BN"}
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Her face: cheeks, eyes, the catchlight, and the mouth.
3
+ *
4
+ * Split out of `mochi.ts` so the composition root stays readable, and split at
5
+ * THIS seam on purpose. The layer ORDER is an architectural rule -- idle, then
6
+ * expression, then the mouth, always last -- and an order
7
+ * can only be read off the place the calls are written. So the ordering stays
8
+ * in `paint()` where it is visible in four consecutive lines, and only the
9
+ * implementations moved here.
10
+ *
11
+ * Free functions taking an explicit context rather than methods on a class:
12
+ * none of these hold state, and passing `ctx` in makes it obvious that they
13
+ * paint wherever they are told rather than into somewhere they own.
14
+ */
15
+ import { clamp01 } from '../core/vocabulary.js';
16
+ import { parseHexRgb } from '../core/colour.js';
17
+ import { lensOutline, lensHeight } from '../core/lens.js';
18
+ import { outlinePath } from './paths.js';
19
+ /** How far from the eye's centre the catchlight sits, as a fraction of the eye. */
20
+ const GLINT_TRAVEL = 0.45;
21
+ /** Most of an eye's half-extent the catchlight may take up, in either axis. */
22
+ const GLINT_MAX_FILL = 0.55;
23
+ /** Above 2 the superellipse squares off — which is what makes it read as a block. */
24
+ const GLINT_ROUNDNESS = 3.2;
25
+ /**
26
+ * The same colour at zero alpha, whatever hex form it arrived in.
27
+ *
28
+ * `parseHexRgb` already understands every form the avatar format accepts, so this
29
+ * reuses it rather than adding a fifth place that knows about hex. Falls back
30
+ * to fully transparent black: a cheek that fades to nothing is a cheek nobody
31
+ * notices, which is a better failure than a throw inside the paint loop.
32
+ */
33
+ function transparentOf(hex) {
34
+ const rgb = parseHexRgb(hex);
35
+ return rgb === null ? 'rgba(0, 0, 0, 0)' : `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0)`;
36
+ }
37
+ export function paintCheeks(ctx, face, look, place, scale) {
38
+ const alpha = Math.min(1, face.cheekAlpha + look.cheek * 0.5);
39
+ if (alpha <= 0.01)
40
+ return;
41
+ // Saved and restored, like the mouth and the glint beside it. Resetting
42
+ // `globalAlpha` to 1 by hand restores a value the caller never set, and
43
+ // leaves `fillStyle` holding this gradient afterwards. It happens to be
44
+ // harmless today only because the one caller wraps the whole face in its own
45
+ // save/restore -- which makes this function's safety a property of somebody
46
+ // else's code, and the exported signature promises otherwise.
47
+ ctx.save();
48
+ for (const side of [-1, 1]) {
49
+ const at = place(side * face.cheekX, face.cheekY);
50
+ const radius = face.cheekR * scale * (1 + look.cheek * 0.18);
51
+ const gradient = ctx.createRadialGradient(at.x, at.y, 0, at.x, at.y, radius);
52
+ gradient.addColorStop(0, face.colCheek);
53
+ // PARSED, not string-concatenated. `${hex}00` only yields a valid colour
54
+ // when the hex happens to be six digits, and `parseFaceSpec` accepts four
55
+ // forms: `#rgb` and `#rgba` become five- and seven-digit strings that
56
+ // `addColorStop` rejects by throwing, and `#rrggbbaa` silently becomes a
57
+ // different, opaque colour. A user avatar with `#f88` cheeks would have
58
+ // taken the whole render down.
59
+ gradient.addColorStop(1, transparentOf(face.colCheek));
60
+ ctx.globalAlpha = alpha;
61
+ ctx.fillStyle = gradient;
62
+ ctx.beginPath();
63
+ ctx.ellipse(at.x, at.y, radius, radius * 0.72, 0, 0, Math.PI * 2);
64
+ ctx.fill();
65
+ }
66
+ ctx.restore();
67
+ }
68
+ /**
69
+ * The smallest a lid may get. A shut eye is a HAIRLINE, never nothing.
70
+ *
71
+ * An eye that vanishes entirely reads as a dropped frame rather than as a
72
+ * closed eye, which is the one thing the sleeping pose must not look like.
73
+ */
74
+ const MIN_LID = 0.04;
75
+ /**
76
+ * How far one lid is open, given the expression and the blink.
77
+ *
78
+ * ## The floor is on the PRODUCT, and that is the whole of this function
79
+ *
80
+ * It used to be on the blink alone -- `Math.max(0.04, 1 - blink)` -- which
81
+ * holds only while the expression leaves the eye at full height. `sleepy` does
82
+ * not: it takes the arcs to `0.16` before the blink is applied, so a held
83
+ * blink produced `0.16 x 0.04`, six thousandths of an eye, and she slept with
84
+ * no eyes at all rather than with shut ones.
85
+ *
86
+ * That was reachable the day `sleepy` became the rest pose and not before,
87
+ * which is exactly why the guarantee belongs on the number that is drawn
88
+ * rather than on one of its factors. Any expression, any blink: the lid is
89
+ * never thinner than `MIN_LID`.
90
+ */
91
+ export function lidScale(look, blink) {
92
+ // Normalised before the arithmetic, not after. `Math.max(MIN_LID, ...)` and
93
+ // `Math.abs` both pass NaN straight through, so a non-finite look or blink
94
+ // escaped the floor entirely: `lidScale(NaN, 0)` was NaN and
95
+ // `lidScale(1, -Infinity)` was Infinity — neither of which is a lid.
96
+ if (!Number.isFinite(look))
97
+ return MIN_LID;
98
+ const shut = Number.isFinite(blink) ? clamp01(blink) : 1;
99
+ const open = look * (1 - shut);
100
+ /*
101
+ The floor is on the MAGNITUDE, and the sign survives it.
102
+
103
+ `Math.max(MIN_LID, open)` silently discards a NEGATIVE look, and
104
+ `looks.ts` leans on exactly that sign: `happy` sets `eyeLower` to -0.62 and
105
+ `shy` to -0.28 to bow the lower edge above the baseline and make the
106
+ crescent `^ ^` eye. Clamped to +0.04, both were drawn with a flat lower lid,
107
+ so the one expression a child reads fastest never reached the canvas.
108
+
109
+ Both halves were right and tested -- `lens.test.ts` proves a negative lower
110
+ makes a crescent, `looks.test.ts` proves the table carries one. Only the
111
+ connector between them was wrong, and the test that would have caught it
112
+ checked `eyeUpper`, which is positive for every emotion.
113
+
114
+ A fully shut eye is a POSITIVE hairline whatever the look was: at `blink` 1
115
+ the excursion is zero, and the eye is closed rather than bowed.
116
+ */
117
+ /*
118
+ Sign-preserving at full blink too, and that is the whole of this line.
119
+
120
+ Returning a POSITIVE hairline for a negative look made the function jump at
121
+ exactly `blink === 1`: approached from below the value tends to -MIN_LID,
122
+ and at the endpoint it flipped to +MIN_LID. On a narrow crescent that is a
123
+ step of twice the floor, landing on whichever frame happens to sample the
124
+ peak of a blink.
125
+
126
+ What a CLOSED eye looks like is not this function's decision. It reports how
127
+ far one lid is open; `lidPair` owns the shape the two of them make, and it
128
+ is the thing that can see both.
129
+ */
130
+ if (open === 0)
131
+ return look < 0 ? -MIN_LID : MIN_LID;
132
+ return Math.sign(open) * Math.max(MIN_LID, Math.abs(open));
133
+ }
134
+ /**
135
+ * The two lid extents, with the minimum enforced on what is actually DRAWN.
136
+ *
137
+ * `lidScale` floors each lid on its own, and that is not enough. The eye's
138
+ * rendered height is the SUM of the two — `lower` is signed, and a crescent's
139
+ * negative lower bows the bottom edge up toward the top one — so both lids can
140
+ * sit exactly on the floor with opposite signs and cancel to nothing. A happy
141
+ * face late in a blink did precisely that: two lids at the minimum, an eye of
142
+ * zero height, which is the one outcome `MIN_LID` exists to prevent.
143
+ *
144
+ * Two things about the floor are easy to get wrong, and the first attempt got
145
+ * both:
146
+ *
147
+ * It is a fraction of the eye's own RESTING SPAN — `eyeUpper + eyeLower` — and
148
+ * not of the sum of the two magnitudes. Those are the same number for an eye
149
+ * whose lids both bulge outward, and wildly different for a crescent, where the
150
+ * lids nearly cancel by design. Measured against magnitudes, a face drawn with
151
+ * `eyeUpper: 4, eyeLower: -3.8` had a floor larger than its entire open eye, so
152
+ * it was flattened at rest, at blink zero, in the neutral pose.
153
+ *
154
+ * And when the span is short, only the BOTTOM edge moves: the top arc is left
155
+ * exactly where the expression put it. Collapsing to an evenly split hairline
156
+ * instead made the eye jump — a crescent one frame, a flat sliver the next, its
157
+ * midpoint snapping across the eye. Lifting the lower edge to meet the floor is
158
+ * continuous through the moment it crosses the baseline, so the eye passes from
159
+ * crescent to flat to ordinary lens without a visible step.
160
+ *
161
+ * A face with both extents at zero is left alone. That is a designer asking for
162
+ * no eye at all, the same way `eyeGlint: 0` asks for no catchlight.
163
+ */
164
+ export function lidPair(face, look, blink, scale) {
165
+ const upper = face.eyeUpper * scale * lidScale(look.eyeUpper, blink);
166
+ const lower = face.eyeLower * scale * lidScale(look.eyeLower, blink);
167
+ // Measured against the LARGER extent, not against the span and not against
168
+ // the sum of magnitudes. The span goes to zero for a face drawn with
169
+ // `eyeUpper === -eyeLower`, which left a floor of zero and rendered an eye of
170
+ // literally no pixels; the sum of magnitudes is enormous for any crescent and
171
+ // flattened faces that were never in trouble. The larger extent is a measure
172
+ // of how big the eye IS, which is what a minimum should be a fraction of.
173
+ const floor = Math.max(Math.abs(face.eyeUpper), Math.abs(face.eyeLower)) * scale * MIN_LID;
174
+ if (upper + lower >= floor)
175
+ return { upper, lower };
176
+ return { upper, lower: floor - upper };
177
+ }
178
+ export function paintEyes(ctx, face, look, blink, gaze, place, scale) {
179
+ const halfWidth = face.eyeHw * scale * look.eyeWidth;
180
+ const lids = lidPair(face, look, blink, scale);
181
+ const lens = {
182
+ halfWidth,
183
+ upper: lids.upper,
184
+ lower: lids.lower,
185
+ tilt: 0,
186
+ roundness: face.eyeRound,
187
+ };
188
+ for (const side of [-1, 1]) {
189
+ const at = place(side * face.eyeX, face.eyeY);
190
+ const dx = gaze.x * halfWidth * face.gazeTravel;
191
+ const dy = gaze.y * Math.max(lensHeight(lens), 2) * face.gazeTravel;
192
+ const shape = { ...lens, tilt: (face.eyeTilt + look.eyeTilt) * side };
193
+ const eye = outlinePath(lensOutline(shape), at.x + dx, at.y + dy);
194
+ ctx.fillStyle = face.colInk;
195
+ ctx.fill(eye);
196
+ paintGlint(ctx, face, look, shape, eye, at.x + dx, at.y + dy, scale);
197
+ }
198
+ }
199
+ /**
200
+ * The catchlight: the white block that makes her eyes look lit up.
201
+ *
202
+ * CLIPPED to the eye it belongs to rather than sized to stay inside it. The
203
+ * eye is a lens whose height collapses to a hairline during a blink and whose
204
+ * width follows the expression, so a highlight sized from the open eye sits
205
+ * outside the shut one -- a white speck floating on her cheek for 130ms,
206
+ * which is long enough to see and short enough to never catch in a still.
207
+ * Clipping makes that unrepresentable instead of a sum of two numbers that
208
+ * have to agree.
209
+ *
210
+ * Placed TOWARD THE LIGHT, not at a tuned corner. `shadowX`/`shadowY` already
211
+ * displace the lit copy of her body, so that vector is where the light is;
212
+ * reading it here means a designer who moves the light gets a highlight that
213
+ * moves with it, rather than one that contradicts their own shading.
214
+ */
215
+ function paintGlint(ctx, face, look, eye, clip, x, y, scale) {
216
+ const alpha = clamp01(look.sparkle);
217
+ if (alpha <= 0.01 || face.eyeGlint <= 0)
218
+ return;
219
+ // The eye occupies [-lower, +upper] about its baseline, and its baseline is
220
+ // NOT its middle -- for a crescent, where `lower` is negative, the whole
221
+ // shape sits above the origin the lens is drawn around. `happy` spans 4.0 to
222
+ // 7.1 with an origin at 0, so a highlight offset from the origin landed
223
+ // almost entirely outside the ink on exactly the face that most needs to
224
+ // look lit. Measured from the eye's own centre, it cannot.
225
+ const centre = (eye.upper - eye.lower) / 2;
226
+ const halfSpan = (eye.upper + eye.lower) / 2;
227
+ if (halfSpan <= 0)
228
+ return;
229
+ // Sized to FIT the eye, then clipped as the backstop -- both, because they
230
+ // do different jobs. The cap is what keeps a crescent's highlight a gleam
231
+ // rather than a white sliver filling the little of the eye that is visible;
232
+ // the clip is what holds the guarantee when the lid comes down and the eye
233
+ // becomes a hairline the cap was not computed against.
234
+ const radius = Math.min(face.eyeGlint * scale, halfSpan * GLINT_MAX_FILL, eye.halfWidth * GLINT_MAX_FILL);
235
+ if (radius <= 0)
236
+ return;
237
+ // Normalised so the offset is a DIRECTION. The shadow displacement is a few
238
+ // percent of her body, and used raw it would place the highlight a fraction
239
+ // of a pixel from centre.
240
+ const length = Math.hypot(face.shadowX, face.shadowY);
241
+ const ux = length === 0 ? 0 : face.shadowX / length;
242
+ const uy = length === 0 ? 1 : face.shadowY / length;
243
+ // `- radius` so the block's own body stays inside even before the clip. A
244
+ // guarantee that only holds because something downstream trims it is one
245
+ // nobody can read off this function.
246
+ const localX = ux * Math.max(0, eye.halfWidth - radius) * GLINT_TRAVEL;
247
+ const localY = centre + uy * Math.max(0, halfSpan - radius) * GLINT_TRAVEL;
248
+ // The eye is rotated about its baseline by `tilt`, so the offset has to
249
+ // turn with it or the highlight slides out of a tilted eye.
250
+ const sin = Math.sin(eye.tilt);
251
+ const cos = Math.cos(eye.tilt);
252
+ ctx.save();
253
+ ctx.clip(clip);
254
+ ctx.globalAlpha = alpha;
255
+ ctx.fillStyle = face.colGlint;
256
+ ctx.fill(outlinePath(lensOutline({
257
+ halfWidth: radius,
258
+ upper: radius,
259
+ lower: radius,
260
+ tilt: eye.tilt,
261
+ roundness: GLINT_ROUNDNESS,
262
+ }), x + (localX * cos - localY * sin),
263
+ // Canvas y grows downward, so local +y-up is subtracted.
264
+ y - (localX * sin + localY * cos)));
265
+ ctx.restore();
266
+ }
267
+ export function paintMouth(ctx, face, look, mouthOpen, place, scale) {
268
+ const at = place(0, face.mouthY);
269
+ const open = mouthOpen;
270
+ // The LOUDER of the two, never the expression alone. `sleepy` sets
271
+ // `mouthAlpha` to 0 so a resting mochi has no mouth at all -- but AGENTS.md
272
+ // rule 8 forbids any layer above the mouth from overwriting it, and the
273
+ // reason is concrete: a look holding her jaw shut while audio played would
274
+ // read as broken rather than as asleep. Asleep she is not speaking by
275
+ // definition, and "by definition" is exactly the assumption that stops being
276
+ // true one refactor later, so anything driving the mouth outranks the look.
277
+ const alpha = Math.max(clamp01(look.mouthAlpha), open > 0 ? 1 : 0);
278
+ if (alpha <= 0.01)
279
+ return;
280
+ const shape = {
281
+ // A mouth widens slightly as it opens; holding the width fixed reads as a
282
+ // letterbox rather than a jaw.
283
+ halfWidth: face.mouthHw * scale * look.mouthWidth * (1 + open * 0.22),
284
+ upper: face.mouthUpper * scale * look.mouthUpper,
285
+ lower: face.mouthLower * scale * look.mouthLower + open * face.mouthOpenGain * scale,
286
+ tilt: 0,
287
+ roundness: face.mouthRound,
288
+ };
289
+ // Saved and restored rather than reset by hand: this runs inside the
290
+ // caller's clip, and leaking a globalAlpha out of here would tint whatever
291
+ // the next frame draws first.
292
+ ctx.save();
293
+ ctx.globalAlpha = alpha;
294
+ ctx.fillStyle = face.colInk;
295
+ ctx.fill(outlinePath(lensOutline(shape), at.x, at.y));
296
+ ctx.restore();
297
+ }
298
+ //# sourceMappingURL=face.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"face.js","sourceRoot":"","sources":["../../src/canvas2d/face.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Points to a Path2D.
3
+ *
4
+ * Shared because a feature that can be FILLED can also be CLIPPED to, and that
5
+ * is how the catchlight is kept inside the eye. An earlier version drew
6
+ * straight onto the context and left no object to clip against.
7
+ */
8
+ import type { Point } from '../core/geometry.js';
9
+ /** Local +y-up has already been flipped by the caller. */
10
+ export declare function toPath(points: readonly Point[]): Path2D;
11
+ /** An outline given in +y-up local space, as a canvas-space Path2D at `x, y`. */
12
+ export declare function outlinePath(points: readonly Point[], x: number, y: number): Path2D;
13
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/canvas2d/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAEhD,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAQvD;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAElF"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Points to a Path2D.
3
+ *
4
+ * Shared because a feature that can be FILLED can also be CLIPPED to, and that
5
+ * is how the catchlight is kept inside the eye. An earlier version drew
6
+ * straight onto the context and left no object to clip against.
7
+ */
8
+ /** Local +y-up has already been flipped by the caller. */
9
+ export function toPath(points) {
10
+ const path = new Path2D();
11
+ points.forEach((point, index) => {
12
+ if (index === 0)
13
+ path.moveTo(point.x, point.y);
14
+ else
15
+ path.lineTo(point.x, point.y);
16
+ });
17
+ path.closePath();
18
+ return path;
19
+ }
20
+ /** An outline given in +y-up local space, as a canvas-space Path2D at `x, y`. */
21
+ export function outlinePath(points, x, y) {
22
+ return toPath(points.map((point) => ({ x: x + point.x, y: y - point.y })));
23
+ }
24
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/canvas2d/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,0DAA0D;AAC1D,MAAM,UAAU,MAAM,CAAC,MAAwB;IAC7C,MAAM,IAAI,GAAG,IAAI,MAAM,EAAE,CAAA;IACzB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC9B,IAAI,KAAK,KAAK,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;;YACzC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;IACF,IAAI,CAAC,SAAS,EAAE,CAAA;IAChB,OAAO,IAAI,CAAA;AACb,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,MAAwB,EAAE,CAAS,EAAE,CAAS;IACxE,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAC5E,CAAC"}
@@ -0,0 +1,78 @@
1
+ import type { FaceSpec } from '../core/spec.js';
2
+ /** The five colour fields of a face, and nothing else. */
3
+ export type Colourway = Pick<FaceSpec, 'colBody' | 'colShadow' | 'colInk' | 'colCheek' | 'colGlint'>;
4
+ /**
5
+ * Mochi in six flavours.
6
+ *
7
+ * Derived rather than picked: the relationships were measured off her own
8
+ * palette and then applied to new hues, which is why `matcha` reproduces
9
+ * `#8ec8a8`, `#7dbd99` and `#24463a` exactly. That round-trip is the check that
10
+ * the rules describe her rather than approximate her.
11
+ *
12
+ * - `colShadow` is the body hue at 5.5 points less lightness — a darker tone of
13
+ * the same colour, not a blend toward black.
14
+ * - `colInk` is the body hue rotated 11.9 degrees and taken right down. Her ink
15
+ * is never black.
16
+ * - `colCheek` is a fixed warm blush, because a blush is warm whatever she is
17
+ * made of — EXCEPT on a warm body, where it has no hue contrast left and
18
+ * disappears. Within 60 degrees of the blush hue it goes darker than the body
19
+ * instead and contrasts by lightness. Sakura, kinako and yuzu take that path;
20
+ * the other three are untouched. Contrast is the requirement, and hue was
21
+ * only ever how it was being met.
22
+ *
23
+ * Same licence as `mochi.ts`: these are her, in another colour.
24
+ */
25
+ export declare const COLOURWAYS: {
26
+ /** Green tea. The original. */
27
+ readonly matcha: {
28
+ readonly colBody: '#8ec8a8';
29
+ readonly colShadow: '#7dbd99';
30
+ readonly colInk: '#24463a';
31
+ readonly colCheek: '#ef8f86';
32
+ readonly colGlint: '#ffffff';
33
+ };
34
+ /** Cherry blossom. Blush deepened. */
35
+ readonly sakura: {
36
+ readonly colBody: '#c88e9d';
37
+ readonly colShadow: '#bd7d8e';
38
+ readonly colInk: '#462426';
39
+ readonly colCheek: '#e44435';
40
+ readonly colGlint: '#ffffff';
41
+ };
42
+ /** Roasted soybean flour. Blush deepened. */
43
+ readonly kinako: {
44
+ readonly colBody: '#c8b08e';
45
+ readonly colShadow: '#bda27d';
46
+ readonly colInk: '#463f24';
47
+ readonly colCheek: '#e44435';
48
+ readonly colGlint: '#ffffff';
49
+ };
50
+ /** Citrus. Blush deepened. */
51
+ readonly yuzu: {
52
+ readonly colBody: '#c8c38e';
53
+ readonly colShadow: '#bdb77d';
54
+ readonly colInk: '#424624';
55
+ readonly colCheek: '#e44435';
56
+ readonly colGlint: '#ffffff';
57
+ };
58
+ /** Soda. The only cool one. */
59
+ readonly ramune: {
60
+ readonly colBody: '#8eb3c8';
61
+ readonly colShadow: '#7da6bd';
62
+ readonly colInk: '#243346';
63
+ readonly colCheek: '#ef8f86';
64
+ readonly colGlint: '#ffffff';
65
+ };
66
+ /** Grape. The deepest hue at the same lightness. */
67
+ readonly budo: {
68
+ readonly colBody: '#b38ec8';
69
+ readonly colShadow: '#a57dbd';
70
+ readonly colInk: '#402446';
71
+ readonly colCheek: '#ef8f86';
72
+ readonly colGlint: '#ffffff';
73
+ };
74
+ };
75
+ export type ColourwayName = keyof typeof COLOURWAYS;
76
+ /** Mochi wearing one of her colourways. Geometry untouched; five fields swapped. */
77
+ export declare function mochiIn(name: ColourwayName, base: FaceSpec): FaceSpec;
78
+ //# sourceMappingURL=colourways.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colourways.d.ts","sourceRoot":"","sources":["../../src/characters/colourways.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE/C,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC,CAAA;AAEpG;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,UAAU;IACrB,+BAA+B;;iBAE7B,OAAO,EAAE,SAAS;iBAClB,SAAS,EAAE,SAAS;iBACpB,MAAM,EAAE,SAAS;iBACjB,QAAQ,EAAE,SAAS;iBACnB,QAAQ,EAAE,SAAS;;IAErB,sCAAsC;;iBAEpC,OAAO,EAAE,SAAS;iBAClB,SAAS,EAAE,SAAS;iBACpB,MAAM,EAAE,SAAS;iBACjB,QAAQ,EAAE,SAAS;iBACnB,QAAQ,EAAE,SAAS;;IAErB,6CAA6C;;iBAE3C,OAAO,EAAE,SAAS;iBAClB,SAAS,EAAE,SAAS;iBACpB,MAAM,EAAE,SAAS;iBACjB,QAAQ,EAAE,SAAS;iBACnB,QAAQ,EAAE,SAAS;;IAErB,8BAA8B;;iBAE5B,OAAO,EAAE,SAAS;iBAClB,SAAS,EAAE,SAAS;iBACpB,MAAM,EAAE,SAAS;iBACjB,QAAQ,EAAE,SAAS;iBACnB,QAAQ,EAAE,SAAS;;IAErB,+BAA+B;;iBAE7B,OAAO,EAAE,SAAS;iBAClB,SAAS,EAAE,SAAS;iBACpB,MAAM,EAAE,SAAS;iBACjB,QAAQ,EAAE,SAAS;iBACnB,QAAQ,EAAE,SAAS;;IAErB,oDAAoD;;iBAElD,OAAO,EAAE,SAAS;iBAClB,SAAS,EAAE,SAAS;iBACpB,MAAM,EAAE,SAAS;iBACjB,QAAQ,EAAE,SAAS;iBACnB,QAAQ,EAAE,SAAS;;CAEuB,CAAA;AAE9C,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,UAAU,CAAA;AAEnD,oFAAoF;AACpF,wBAAgB,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAErE"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Mochi in six flavours.
3
+ *
4
+ * Derived rather than picked: the relationships were measured off her own
5
+ * palette and then applied to new hues, which is why `matcha` reproduces
6
+ * `#8ec8a8`, `#7dbd99` and `#24463a` exactly. That round-trip is the check that
7
+ * the rules describe her rather than approximate her.
8
+ *
9
+ * - `colShadow` is the body hue at 5.5 points less lightness — a darker tone of
10
+ * the same colour, not a blend toward black.
11
+ * - `colInk` is the body hue rotated 11.9 degrees and taken right down. Her ink
12
+ * is never black.
13
+ * - `colCheek` is a fixed warm blush, because a blush is warm whatever she is
14
+ * made of — EXCEPT on a warm body, where it has no hue contrast left and
15
+ * disappears. Within 60 degrees of the blush hue it goes darker than the body
16
+ * instead and contrasts by lightness. Sakura, kinako and yuzu take that path;
17
+ * the other three are untouched. Contrast is the requirement, and hue was
18
+ * only ever how it was being met.
19
+ *
20
+ * Same licence as `mochi.ts`: these are her, in another colour.
21
+ */
22
+ export const COLOURWAYS = {
23
+ /** Green tea. The original. */
24
+ matcha: {
25
+ colBody: '#8ec8a8',
26
+ colShadow: '#7dbd99',
27
+ colInk: '#24463a',
28
+ colCheek: '#ef8f86',
29
+ colGlint: '#ffffff',
30
+ },
31
+ /** Cherry blossom. Blush deepened. */
32
+ sakura: {
33
+ colBody: '#c88e9d',
34
+ colShadow: '#bd7d8e',
35
+ colInk: '#462426',
36
+ colCheek: '#e44435',
37
+ colGlint: '#ffffff',
38
+ },
39
+ /** Roasted soybean flour. Blush deepened. */
40
+ kinako: {
41
+ colBody: '#c8b08e',
42
+ colShadow: '#bda27d',
43
+ colInk: '#463f24',
44
+ colCheek: '#e44435',
45
+ colGlint: '#ffffff',
46
+ },
47
+ /** Citrus. Blush deepened. */
48
+ yuzu: {
49
+ colBody: '#c8c38e',
50
+ colShadow: '#bdb77d',
51
+ colInk: '#424624',
52
+ colCheek: '#e44435',
53
+ colGlint: '#ffffff',
54
+ },
55
+ /** Soda. The only cool one. */
56
+ ramune: {
57
+ colBody: '#8eb3c8',
58
+ colShadow: '#7da6bd',
59
+ colInk: '#243346',
60
+ colCheek: '#ef8f86',
61
+ colGlint: '#ffffff',
62
+ },
63
+ /** Grape. The deepest hue at the same lightness. */
64
+ budo: {
65
+ colBody: '#b38ec8',
66
+ colShadow: '#a57dbd',
67
+ colInk: '#402446',
68
+ colCheek: '#ef8f86',
69
+ colGlint: '#ffffff',
70
+ },
71
+ };
72
+ /** Mochi wearing one of her colourways. Geometry untouched; five fields swapped. */
73
+ export function mochiIn(name, base) {
74
+ return { ...base, ...COLOURWAYS[name] };
75
+ }
76
+ //# sourceMappingURL=colourways.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colourways.js","sourceRoot":"","sources":["../../src/characters/colourways.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,+BAA+B;IAC/B,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,SAAS;KACpB;IACD,sCAAsC;IACtC,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,SAAS;KACpB;IACD,6CAA6C;IAC7C,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,SAAS;KACpB;IACD,8BAA8B;IAC9B,IAAI,EAAE;QACJ,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,SAAS;KACpB;IACD,+BAA+B;IAC/B,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,SAAS;KACpB;IACD,oDAAoD;IACpD,IAAI,EAAE;QACJ,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,SAAS;KACpB;CAC2C,CAAA;AAI9C,oFAAoF;AACpF,MAAM,UAAU,OAAO,CAAC,IAAmB,EAAE,IAAc;IACzD,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,CAAA;AACzC,CAAC"}