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.
- package/BRAND.md +85 -0
- package/LICENSE.md +104 -0
- package/README.md +135 -0
- package/dist/canvas2d/avatar.d.ts +264 -0
- package/dist/canvas2d/avatar.d.ts.map +1 -0
- package/dist/canvas2d/avatar.js +811 -0
- package/dist/canvas2d/avatar.js.map +1 -0
- package/dist/canvas2d/face.d.ts +74 -0
- package/dist/canvas2d/face.d.ts.map +1 -0
- package/dist/canvas2d/face.js +298 -0
- package/dist/canvas2d/face.js.map +1 -0
- package/dist/canvas2d/paths.d.ts +13 -0
- package/dist/canvas2d/paths.d.ts.map +1 -0
- package/dist/canvas2d/paths.js +24 -0
- package/dist/canvas2d/paths.js.map +1 -0
- package/dist/characters/colourways.d.ts +78 -0
- package/dist/characters/colourways.d.ts.map +1 -0
- package/dist/characters/colourways.js +76 -0
- package/dist/characters/colourways.js.map +1 -0
- package/dist/characters/index.d.ts +8 -0
- package/dist/characters/index.d.ts.map +1 -0
- package/dist/characters/index.js +8 -0
- package/dist/characters/index.js.map +1 -0
- package/dist/characters/mochi.d.ts +19 -0
- package/dist/characters/mochi.d.ts.map +1 -0
- package/dist/characters/mochi.js +66 -0
- package/dist/characters/mochi.js.map +1 -0
- package/dist/core/colour.d.ts +25 -0
- package/dist/core/colour.d.ts.map +1 -0
- package/dist/core/colour.js +37 -0
- package/dist/core/colour.js.map +1 -0
- package/dist/core/envelope.d.ts +153 -0
- package/dist/core/envelope.d.ts.map +1 -0
- package/dist/core/envelope.js +141 -0
- package/dist/core/envelope.js.map +1 -0
- package/dist/core/geometry.d.ts +106 -0
- package/dist/core/geometry.d.ts.map +1 -0
- package/dist/core/geometry.js +157 -0
- package/dist/core/geometry.js.map +1 -0
- package/dist/core/idle.d.ts +163 -0
- package/dist/core/idle.d.ts.map +1 -0
- package/dist/core/idle.js +262 -0
- package/dist/core/idle.js.map +1 -0
- package/dist/core/layout.d.ts +142 -0
- package/dist/core/layout.d.ts.map +1 -0
- package/dist/core/layout.js +172 -0
- package/dist/core/layout.js.map +1 -0
- package/dist/core/lens.d.ts +47 -0
- package/dist/core/lens.d.ts.map +1 -0
- package/dist/core/lens.js +67 -0
- package/dist/core/lens.js.map +1 -0
- package/dist/core/looks.d.ts +77 -0
- package/dist/core/looks.d.ts.map +1 -0
- package/dist/core/looks.js +168 -0
- package/dist/core/looks.js.map +1 -0
- package/dist/core/motion.d.ts +168 -0
- package/dist/core/motion.d.ts.map +1 -0
- package/dist/core/motion.js +527 -0
- package/dist/core/motion.js.map +1 -0
- package/dist/core/mouth.d.ts +93 -0
- package/dist/core/mouth.d.ts.map +1 -0
- package/dist/core/mouth.js +92 -0
- package/dist/core/mouth.js.map +1 -0
- package/dist/core/plain.d.ts +23 -0
- package/dist/core/plain.d.ts.map +1 -0
- package/dist/core/plain.js +63 -0
- package/dist/core/plain.js.map +1 -0
- package/dist/core/spec.d.ts +156 -0
- package/dist/core/spec.d.ts.map +1 -0
- package/dist/core/spec.js +236 -0
- package/dist/core/spec.js.map +1 -0
- package/dist/core/spring.d.ts +53 -0
- package/dist/core/spring.d.ts.map +1 -0
- package/dist/core/spring.js +68 -0
- package/dist/core/spring.js.map +1 -0
- package/dist/core/vocabulary.d.ts +182 -0
- package/dist/core/vocabulary.d.ts.map +1 -0
- package/dist/core/vocabulary.js +66 -0
- package/dist/core/vocabulary.js.map +1 -0
- package/dist/element/dough-avatar.d.ts +34 -0
- package/dist/element/dough-avatar.d.ts.map +1 -0
- package/dist/element/dough-avatar.js +189 -0
- package/dist/element/dough-avatar.js.map +1 -0
- package/dist/element/index.d.ts +3 -0
- package/dist/element/index.d.ts.map +1 -0
- package/dist/element/index.js +35 -0
- package/dist/element/index.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/svg/silhouette.d.ts +97 -0
- package/dist/svg/silhouette.d.ts.map +1 -0
- package/dist/svg/silhouette.js +143 -0
- package/dist/svg/silhouette.js.map +1 -0
- 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"}
|