diff options
| author | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-03 19:41:34 +0900 |
|---|---|---|
| committer | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-03 19:41:34 +0900 |
| commit | 75796bb956d8aedc35e004f620f10ab137eb0216 (patch) | |
| tree | 17ea2fb125c08cf0c379dad1b3e54eb0afc0682e /public/bluebey-studio/src/panel.js | |
| parent | e530565430622f7d1e824d27b6dc26d95024eb6f (diff) | |
public/bluebey-studio: ひげをテクスチャに、舌を外に出すを削除
ひげの種類に画像(assets/beards/<kind>.png)があれば、それを使って描くようにした。まず「ちょびひげ」を追加。画像が無い種類は今までどおり描画で出す。
「舌を外に出す」「外に出す舌の位置」を削除した。
「すべてをランダムに」は、スタイル(実写・フラット・線画)と左右反転を変えないようにし、後ろを向く・大きく傾くポーズは選ばないようにした。アイコンを「?!」に変更。
Diffstat (limited to 'public/bluebey-studio/src/panel.js')
| -rw-r--r-- | public/bluebey-studio/src/panel.js | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/public/bluebey-studio/src/panel.js b/public/bluebey-studio/src/panel.js index f82d6bf..3312e9c 100644 --- a/public/bluebey-studio/src/panel.js +++ b/public/bluebey-studio/src/panel.js @@ -190,14 +190,17 @@ export function buildPanel(app, root) { }); const randomFace = () => replace({ face: randomFacePatch() }, 'face'); const randomAll = () => { - const pose = pick(POSE_PRESETS); + // 後ろを向く(180°)や大きく傾くポーズは避ける。見える顔が変わる範囲だけ。 + const poses = POSE_PRESETS.filter((preset) => { + const m = preset.pose?.bones?.master ?? [0, 0, 0]; + return Math.abs(m[0]) <= 45 && Math.abs(m[1]) <= 40 && Math.abs(m[2]) <= 40; + }); + const pose = pick(poses.length ? poses : POSE_PRESETS); const theme = pick(THEMES); app.actions.applyPosePreset?.(pose.id); app.actions.applyTheme?.(theme.id); - replace({ - face: randomFacePatch(), - render: { style: pick(STYLE_DEFS.map((style) => style.value)), mirror: Math.random() < 0.5 }, - }, 'all'); + // The viewer style (実写/フラット/線画) and 左右反転 are deliberately left alone. + replace({ face: randomFacePatch() }, 'face'); sync(); }; @@ -213,7 +216,7 @@ export function buildPanel(app, root) { topBar.append( iconButton('元に戻す', 'M4.8 11.5h9.7a5.2 5.2 0 0 1 0 10.4h-3.6M4.8 11.5 9.6 6.7M4.8 11.5 9.6 16.3', () => app.actions.undo()), iconButton('やり直す', 'M19.2 11.5h-9.7a5.2 5.2 0 0 0 0 10.4h3.6M19.2 11.5 14.4 6.7M19.2 11.5 14.4 16.3', () => app.actions.redo()), - iconButton('すべてをランダムに', 'M5 4.5h14a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-13a1 1 0 0 1 1-1ZM9 8.5h.01M15 8.5h.01M12 12h.01M9 15.5h.01M15 15.5h.01', () => randomAll()), + iconButton('すべてをランダムに', 'M7.2 9.4a2.6 2.6 0 1 1 3.9 2.3c-.9.5-1.3 1.2-1.3 2.1v.4M9.2 17.4h.01M16.8 6.8v6.1M16.8 15.6h.01', () => randomAll()), ); root.append(topBar); @@ -1188,15 +1191,13 @@ export function buildPanel(app, root) { offsetY: slider({ label: '口の高さ', min: -140, max: 140, step: 1, value: 0, format: (v) => `${Math.round(v)}`, onInput: (v) => { state.face.mouth.offsetY = v; app.actions.refresh('face'); } }), tongue: slider({ label: '舌の大きさ', min: 0, max: 1.6, step: 0.01, value: 0.96, format: (v) => v.toFixed(2), onInput: (v) => { state.face.mouth.tongue = v; app.actions.refresh('face'); } }), tonguePos: slider({ label: '舌の位置', min: 0.05, max: 0.95, step: 0.01, value: 0.84, format: (v) => v.toFixed(2), onInput: (v) => { state.face.mouth.tonguePos = v; app.actions.refresh('face'); } }), - tongueOut: slider({ label: '舌を外に出す', min: 0, max: 1, step: 0.01, value: 0, format: (v) => v.toFixed(2), onInput: (v) => { state.face.mouth.tongueOut = v; app.actions.refresh('face'); } }), - tongueOutPos: slider({ label: '外に出す舌の位置', min: 0.05, max: 0.95, step: 0.01, value: 0.5, format: (v) => v.toFixed(2), onInput: (v) => { state.face.mouth.tongueOutPos = v; app.actions.refresh('face'); } }), corners: slider({ label: '口角の長さ', min: 0, max: 1.6, step: 0.01, value: 0.71, format: (v) => v.toFixed(2), onInput: (v) => { state.face.mouth.corners = v; app.actions.refresh('face'); } }), cornerAngle: slider({ label: '口角の角度', min: -70, max: 70, step: 1, value: -8, format: (v) => `${Math.round(v)}°`, onInput: (v) => { state.face.mouth.cornerAngle = v; app.actions.refresh('face'); } }), }; const mouthVisible = ['smile', 'round', 'width', 'thickness', 'tilt', 'offsetY']; for (const key of mouthVisible) faceSection.add(mouthSliders[key].el); const mouthBox = details(faceSection.body, 'こまかい設定(開き・舌・口角)'); - for (const key of ['open', 'tongue', 'tonguePos', 'tongueOut', 'tongueOutPos', 'corners', 'cornerAngle']) mouthBox.add(mouthSliders[key].el); + for (const key of ['open', 'tongue', 'tonguePos', 'corners', 'cornerAngle']) mouthBox.add(mouthSliders[key].el); mouthBox.add(buttons({ items: [{ id: 'mouthreset', |
