aboutsummaryrefslogtreecommitdiffhomepage
path: root/public
diff options
context:
space:
mode:
Diffstat (limited to 'public')
-rw-r--r--public/bluebey-studio/assets/beards/apron.pngbin0 -> 4002 bytes
-rw-r--r--public/bluebey-studio/assets/beards/kaiser.pngbin0 -> 2612 bytes
-rw-r--r--public/bluebey-studio/src/main.js2
-rw-r--r--public/bluebey-studio/src/panel.js38
-rw-r--r--public/bluebey-studio/src/presets.js9
5 files changed, 35 insertions, 14 deletions
diff --git a/public/bluebey-studio/assets/beards/apron.png b/public/bluebey-studio/assets/beards/apron.png
new file mode 100644
index 0000000..73e3537
--- /dev/null
+++ b/public/bluebey-studio/assets/beards/apron.png
Binary files differ
diff --git a/public/bluebey-studio/assets/beards/kaiser.png b/public/bluebey-studio/assets/beards/kaiser.png
new file mode 100644
index 0000000..617fde5
--- /dev/null
+++ b/public/bluebey-studio/assets/beards/kaiser.png
Binary files differ
diff --git a/public/bluebey-studio/src/main.js b/public/bluebey-studio/src/main.js
index b94fca0..f90dfc8 100644
--- a/public/bluebey-studio/src/main.js
+++ b/public/bluebey-studio/src/main.js
@@ -395,7 +395,7 @@ async function init() {
void (async () => {
// Only the kinds that actually ship a drawing. Add a name here when its file is
// added to assets/beards/, so no 404s are logged for the ones without one.
- const kinds = ['scotch'];
+ const kinds = ['scotch', 'kaiser', 'apron'];
const loaded = {};
await Promise.all(kinds.map(async (kind) => {
try {
diff --git a/public/bluebey-studio/src/panel.js b/public/bluebey-studio/src/panel.js
index 3312e9c..3f63eb6 100644
--- a/public/bluebey-studio/src/panel.js
+++ b/public/bluebey-studio/src/panel.js
@@ -4,7 +4,7 @@ import {
} from './ui.js';
import {
FACE_PRESETS, POSE_PRESETS, THEMES, BUBBLE_STYLES, CAPTION_PRESETS,
- defaultState, applyPatch,
+ defaultState, applyPatch, BEARD_KIND_DEFAULTS,
} from './presets.js';
import { STYLE_DEFS } from './styles.js';
import { EYE_VARIANTS } from './model.js';
@@ -161,13 +161,15 @@ export function buildPanel(app, root) {
lookX: +rnd(-0.35, 0.35).toFixed(2),
lookY: +rnd(-0.25, 0.25).toFixed(2),
});
- const randomFacePatch = () => ({
- eyes: {
- left: randomEye(),
- right: randomEye(),
- cheeks: { enabled: Math.random() < 0.5 },
- beard: { shape: pick(['off', 'scotch', 'kaiser', 'apron', 'cat']) },
- headMark: { shape: pick(['off', 'cap', 'fringe', 'fringe-up', 'wave', 'side']) },
+ const randomFacePatch = () => {
+ const beardShape = pick(['off', 'scotch', 'kaiser', 'apron', 'cat']);
+ return {
+ eyes: {
+ left: randomEye(),
+ right: randomEye(),
+ cheeks: { enabled: Math.random() < 0.5 },
+ beard: { shape: beardShape, ...(BEARD_KIND_DEFAULTS[beardShape] ?? { size: 1, offsetY: 0 }) },
+ headMark: { shape: pick(['off', 'cap', 'fringe', 'fringe-up', 'wave', 'side']) },
brow: {
enabled: true,
angle: Math.round(rnd(-30, 40)),
@@ -187,7 +189,8 @@ export function buildPanel(app, root) {
tilt: Math.round(rnd(-12, 12)),
offsetY: Math.round(rnd(-16, 16)),
},
- });
+ };
+ };
const randomFace = () => replace({ face: randomFacePatch() }, 'face');
const randomAll = () => {
// 後ろを向く(180°)や大きく傾くポーズは避ける。見える顔が変わる範囲だけ。
@@ -1122,11 +1125,20 @@ export function buildPanel(app, root) {
{ value: 'off', label: 'なし' },
{ value: 'scotch', label: 'ちょびひげ' },
{ value: 'kaiser', label: 'ダリ' },
- { value: 'apron', label: 'ルパン' },
+ { value: 'apron', label: 'ペンシル' },
{ value: 'cat', label: 'ねこ' },
],
value: 'off',
- onChange: (value) => { state.face.eyes.beard.shape = value; app.actions.refresh('face'); },
+ onChange: (value) => {
+ const beard = state.face.eyes.beard;
+ beard.shape = value;
+ // Each kind starts at its own size and height (a textured kind is drawn at a
+ // different scale from the built-in strokes). A kind with no entry resets to
+ // the neutral values, so switching kinds cannot leave a stray size behind.
+ Object.assign(beard, BEARD_KIND_DEFAULTS[value] ?? { size: 1, offsetY: 0 });
+ app.actions.refresh('face');
+ sync();
+ },
});
faceSection.add(beardShape.el);
const beardSliders = {
@@ -1163,8 +1175,8 @@ export function buildPanel(app, root) {
onChange: (v) => { state.face.eyes.beard.color = v; app.actions.refresh('face'); },
});
beardBox.add(beardColor.el);
- beardBox.add(hint('鼻の下に、ちょびひげ・ダリ・ルパン・ねこ、の髭を描きます。'
- + '「左右の間隔」「ひげの長さ」「線の間隔」は「ねこ」で使います。'));
+ beardBox.add(hint('鼻の下に、ちょびひげ・ダリ・ペンシル・ねこ、の瓢を描きます。'
+ + '「左右の間隔」「瓢の長さ」「線の間隔」は「ねこ」で使います。'));
// --- mouth
faceSection = section(tabFace, '口');
diff --git a/public/bluebey-studio/src/presets.js b/public/bluebey-studio/src/presets.js
index 5492307..2214cb1 100644
--- a/public/bluebey-studio/src/presets.js
+++ b/public/bluebey-studio/src/presets.js
@@ -41,6 +41,15 @@ function captionDefaults() {
}
/**
+ * Per-kind starting size and height for ひげ, applied when a kind is picked. The
+ * textured kinds are drawings, so they are drawn at a different scale from the
+ * built-in strokes; a kind with no entry resets to the neutral values.
+ */
+export const BEARD_KIND_DEFAULTS = {
+ scotch: { size: 0.46, offsetY: 74 },
+};
+
+/**
* 見えない壁 (the invisible wall) settings. The studio offers two, so a corner (or
* two opposite cuts) can be made. A wall's position is kept *relative to the
* character*, so moving ぶるべー carries its walls along (see src/clip.js).