aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/bluebey-studio/src/faceArt.js
diff options
context:
space:
mode:
authorYasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com>2026-10-04 23:10:56 +0900
committerYasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com>2026-10-04 23:10:56 +0900
commitbbefd07f238dd0cecb82fa75d36ffcffe9613ef8 (patch)
tree63721d3e787e096695d826db06a6f9a461db8476 /public/bluebey-studio/src/faceArt.js
parentadc9bc266ca9795cd153c8425bf8f31f6ad31ac7 (diff)
bluebey-studio: まえがみ・わけめ・白目の調整と目/口メニュー整理など
まえがみを大きさ0でもM字に保つよう調整。わけめの切り込みを浅くした。白目の表示/非表示を線まぶたでも選べるように。目の涙と手描きパーツをこまかい設定へ、口の幅をこまかい設定へ移動し口のパーツ選択を削除。Undo/?!バーを固定表示に。プリセットに「てれ」「じと目」を追加し、ねぼけに鼻ちょうちんを表示。
Diffstat (limited to 'public/bluebey-studio/src/faceArt.js')
-rw-r--r--public/bluebey-studio/src/faceArt.js40
1 files changed, 25 insertions, 15 deletions
diff --git a/public/bluebey-studio/src/faceArt.js b/public/bluebey-studio/src/faceArt.js
index fab975a..48ffd67 100644
--- a/public/bluebey-studio/src/faceArt.js
+++ b/public/bluebey-studio/src/faceArt.js
@@ -962,9 +962,16 @@ export function drawHeadCoverWrap(ctx, spec, layout) {
// centre (the peak) and at the temples, with the corners between receded -
// the three peaks and two valleys of an "M". `t` is -1..1 across the front.
if (shape === 'fringe') {
- const m = (1 + Math.cos(2 * Math.PI * t)) / 2; // peaks at t = 0, +-1
- const peak = Math.max(0, 1 - Math.abs(t) * 3); // sharper central point
- return base + 0.26 * m + 0.12 * peak;
+ const m = (1 + Math.cos(2 * Math.PI * t)) / 2; // wide peaks at t = 0, +-1
+ const peak = Math.max(0, 1 - Math.abs(t) * 1.6); // the central point
+ const shape01 = 0.55 * m + 0.45 * peak; // 0..1 across the M
+ // The recessed corners keep a hairline, and the peaks scale with `size`, so
+ // a small まえがみ stays an M instead of collapsing into a spindle.
+ const valley = Math.max(base, 0.10);
+ // The peaks deepen with `size`, so a small まえがみ is a small M rather
+ // than a tall spike on a thin band.
+ const amp = 0.36 * (0.55 + 0.45 * Math.min(clamp(size, 0.05, 3), 1));
+ return valley + amp * shape01;
}
// はちわれ: the same V upside down - a widow's peak.
if (shape === 'fringe-up') return base - 0.18 * Math.max(0, 1 - Math.abs(t) * 1.5);
@@ -995,17 +1002,20 @@ export function drawHeadCoverWrap(ctx, spec, layout) {
ctx.fill();
if (shape === 'side') {
- // The parting: a thin wedge cut out at 30% (a 7:3 split), running from the
- // top of the head down to the hairline.
+ // The parting: a shallow notch cut up from the hairline at 30% (a 7:3 split).
+ // Cutting all the way to the top of the head made it look bald, so only the
+ // lower part of the covering is cut.
const partX = span * 0.4;
- const gw = Math.max(8, span * 0.016) * (0.6 + size);
+ const gw = Math.max(6, span * 0.012) * (0.6 + size);
+ const bY = clamp(vBound(partX), 0, 1) * H;
+ const top = Math.max(0, bY - Math.min(110, bY * 0.6));
ctx.save();
ctx.globalCompositeOperation = 'destination-out';
ctx.beginPath();
- ctx.moveTo(partX - gw * 0.5, 0);
- ctx.lineTo(partX + gw * 0.5, 0);
- ctx.lineTo(partX + gw * 1.2, clamp(vBound(partX), 0, 1) * H + 2);
- ctx.lineTo(partX - gw * 1.2, clamp(vBound(partX), 0, 1) * H + 2);
+ ctx.moveTo(partX - gw * 0.35, top);
+ ctx.lineTo(partX + gw * 0.35, top);
+ ctx.lineTo(partX + gw * 1.1, bY + 2);
+ ctx.lineTo(partX - gw * 1.1, bY + 2);
ctx.closePath();
ctx.fill();
ctx.restore();
@@ -1437,11 +1447,11 @@ export function drawEyes(ctx, p) {
dy = (dy / dist) * eyeTravel;
}
- // The eyeball's white is only painted in the shaded styles: in line art the
- // paper behind shows through, which is what a line drawing wants. (The SVG
- // export traces the alpha mask, so a white fill would close the eye up
- // completely.)
- if (!line && !(isHeart && style.heartHideWhite)) fillCircle(ctx, eye.cx, eye.cy, eye.r, white);
+ // The eyeball's white can be hidden: for a heart it stops the white showing
+ // round the lobes, and `hideWhite` does the same for any style (e.g. a line
+ // squint) when the user asks for it.
+ const hideWhite = style.hideWhite === true || (isHeart && style.heartHideWhite);
+ if (!line && !hideWhite) fillCircle(ctx, eye.cx, eye.cy, eye.r, white);
const irisX = eye.cx + dx;
const irisY = eye.cy + dy;
if (isHeart) {