From eed94d378af577171e24fe78b4b159be5ca50317 Mon Sep 17 00:00:00 2001 From: Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> Date: Sun, 4 Oct 2026 23:24:51 +0900 Subject: bluebey-studio: 下まぶたと目線の左右別設定、Oの口の拡大、白目/ハート/振れ幅の整理 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 下まぶた・目線を左右べつに設定可能に。丸く開く口を顔半分ほどまで拡大。白目を消すを一般化し「ハートのとき白目を消す」を削除。ハートの大きさは瞳の大きさに統合し、目線の振れ幅のスライダーを廃止(既定1.2)。 --- public/bluebey-studio/src/panel.js | 56 ++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 33 deletions(-) (limited to 'public/bluebey-studio/src/panel.js') diff --git a/public/bluebey-studio/src/panel.js b/public/bluebey-studio/src/panel.js index b8f1d63..723d806 100644 --- a/public/bluebey-studio/src/panel.js +++ b/public/bluebey-studio/src/panel.js @@ -567,15 +567,27 @@ export function buildPanel(app, root) { label: `${label}の涙の傾き`, min: -60, max: 60, step: 1, value: 0, format: (v) => `${Math.round(v)}°`, onInput: (value) => setTear({ tearTilt: value }), }); - eyeWidgets[key] = { open, closed, closedLines, threeFlip, eyeX, tear, tearY, tearX, tearTilt }; + const lowerLidEach = slider({ + label: `${label}の下まぶた`, min: 0, max: 1, step: 0.01, value: 0, format: (v) => v.toFixed(2), + onInput: (value) => { state.face.eyes[key].lowerLid = value; app.actions.refresh('face'); }, + }); + const lookX = slider({ + label: `${label}の目線(よこ)`, min: -1, max: 1, step: 0.01, value: 0, format: (v) => v.toFixed(2), + onInput: (value) => { state.face.eyes[key].lookX = value; app.actions.refresh('face'); }, + }); + const lookY = slider({ + label: `${label}の目線(たて)`, min: -1, max: 1, step: 0.01, value: 0, format: (v) => v.toFixed(2), + onInput: (value) => { state.face.eyes[key].lookY = value; app.actions.refresh('face'); }, + }); + eyeWidgets[key] = { open, closed, closedLines, threeFlip, eyeX, tear, tearY, tearX, tearTilt, lowerLid: lowerLidEach, lookX, lookY }; if (key === 'left') faceSection.add(controlRow(null, linkedToggle.el, { wide: true })); faceSection.add(open.el); faceSection.add(closed.el); faceSection.add(closedLines.el); faceSection.add(threeFlip.el); faceSection.add(eyeX.el); - // The tears go into the こまかい設定 box later, with the other extras. - tearWidgets.push(tear.el, tearY.el, tearX.el, tearTilt.el); + // 目線 and 下まぶた (per eye) and the tears go into the こまかい設定 box later. + tearWidgets.push(lowerLidEach.el, lookX.el, lookY.el, tear.el, tearY.el, tearX.el, tearTilt.el); } // One button to put every eye setting back to the artwork's defaults. The @@ -673,46 +685,25 @@ export function buildPanel(app, root) { + '「まぶたの傾き」で、細めた目を左右反転で傾けられます。' + '「白目を消す」は、細めた目やハートのときに白目を出しません。')); - const eyeAdvanced = details(faceSection.body, 'こまかい設定(瞳・色・ハート・まぶた・涙・手描き)'); + const eyeAdvanced = details(faceSection.body, 'こまかい設定(瞳・色・まぶたの太さ・左右べつの設定・手描き)'); const irisScaleSlider = slider({ label: '瞳の大きさ', min: 0.4, max: 1.4, step: 0.01, value: 1, format: (v) => v.toFixed(2), onInput: (value) => { state.face.eyes.irisScale = value; app.actions.refresh('face'); }, }); - const heartScaleSlider = slider({ - label: 'ハートの大きさ', min: 0.4, max: 2.6, step: 0.01, value: 2, format: (v) => v.toFixed(2), - onInput: (value) => { state.face.eyes.heartScale = value; app.actions.refresh('face'); }, - }); - const heartWhiteToggle = check({ - label: 'ハートのとき白目を消す', - value: true, - onChange: (value) => { state.face.eyes.heartHideWhite = value; app.actions.refresh('face'); }, - }); const heartColorField = colorField({ label: 'ハートの色', value: '#e0344f', swatches: ['#e0344f', '#ff5f8f', '#c2185b', '#150e1b'], onChange: (v) => { state.face.eyes.heartColor = v; app.actions.refresh('face'); }, }); - const lookMaxSlider = slider({ - label: '目線の振れ幅', min: 0, max: 1.2, step: 0.01, value: 1, format: (v) => v.toFixed(2), - onInput: (value) => { state.face.eyes.lookMax = value; app.actions.refresh('face'); }, - }); const lidWidthSlider = slider({ label: 'まぶたの太さ', min: 0, max: 30, step: 1, value: 14, format: (v) => `${Math.round(v)}`, onInput: (value) => { state.face.eyes.lidWidth = value; app.actions.refresh('face'); }, }); - const lowerLidSlider = slider({ - label: '下まぶた', min: 0, max: 1, step: 0.01, value: 0, format: (v) => v.toFixed(2), - onInput: (value) => { state.face.eyes.lowerLid = value; app.actions.refresh('face'); }, - }); eyeAdvanced.add(irisScaleSlider.el); - eyeAdvanced.add(heartScaleSlider.el); - eyeAdvanced.add(controlRow(null, heartWhiteToggle.el, { wide: true })); eyeAdvanced.add(heartColorField.el); - eyeAdvanced.add(lookMaxSlider.el); eyeAdvanced.add(lidWidthSlider.el); - eyeAdvanced.add(lowerLidSlider.el); - eyeAdvanced.add(hint('「下まぶた」を上げると、下からもまぶたが持ち上がります。' - + '「まぶたの形」「目の傾き」「目を細める」は、この上の「目」にあります。')); + eyeAdvanced.add(hint('「まぶたの形」「まぶたの傾き」「目を細める」「白目を消す」は、この上の「目」にあります。' + + 'ハートの大きさは「瞳の大きさ」で変わります。')); const highlightToggle = check({ label: '瞳のハイライト', @@ -729,8 +720,8 @@ export function buildPanel(app, root) { const eyeColorBox = details(faceSection.body, '色(白目・瞳・まぶたの線)'); for (const widget of Object.values(eyeColors)) eyeColorBox.add(widget.el); - // Tears (per eye) live here with the other extras. - const tearBox = details(eyeAdvanced.body, '涙(左右べつ)'); + // 目線・下まぶた・涙 (all per eye) live here with the other extras. + const tearBox = details(eyeAdvanced.body, '目線・下まぶた・涙(左右べつ)'); for (const el of tearWidgets) tearBox.add(el); const eyeSource = selectField({ @@ -2679,18 +2670,17 @@ export function buildPanel(app, root) { eyeWidgets[key].tearX.set(state.face.eyes[key].tearX ?? 0); eyeWidgets[key].tearTilt.set(state.face.eyes[key].tearTilt ?? 0); eyeWidgets[key].eyeX.set(state.face.eyes[key].eyeX ?? 0); + eyeWidgets[key].lookX.set(state.face.eyes[key].lookX ?? 0); + eyeWidgets[key].lookY.set(state.face.eyes[key].lookY ?? 0); + eyeWidgets[key].lowerLid.set(state.face.eyes[key].lowerLid ?? state.face.eyes.lowerLid ?? 0); } irisShapeSegment.set(state.face.eyes.left.irisShape ?? 'circle'); lookPad.set({ x: state.face.eyes.left.lookX, y: state.face.eyes.left.lookY }); highlightToggle.set(state.face.eyes.highlight); irisScaleSlider.set(state.face.eyes.irisScale); - heartScaleSlider.set(state.face.eyes.heartScale ?? 0.85); - heartWhiteToggle.set(state.face.eyes.heartHideWhite === true); heartColorField.set(state.face.eyes.heartColor ?? '#e0344f'); - lookMaxSlider.set(state.face.eyes.lookMax ?? 1); lidWidthSlider.set(state.face.eyes.lidWidth ?? 14); - lowerLidSlider.set(state.face.eyes.lowerLid ?? 0); lidShapeSegment.set(state.face.eyes.lidShape ?? 'curve'); lidTiltSlider.set(state.face.eyes.lidTilt ?? 0); hideWhiteToggle.set(state.face.eyes.hideWhite === true); -- cgit v1.3.1