From 15208ff5e4a7ddd818f504f07a0f83a394239104 Mon Sep 17 00:00:00 2001 From: tickle Date: Mon, 22 Jun 2026 20:49:14 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E8=AD=9C=E9=9D=A2=E5=90=8D?= =?UTF-8?q?=E3=81=AE=E8=A4=87=E6=95=B0=E8=A1=8C=E5=AF=BE=E5=BF=9C=E3=80=81?= =?UTF-8?q?=E3=83=98=E3=83=AB=E3=83=97=E3=83=9C=E3=82=BF=E3=83=B3=E3=81=AB?= =?UTF-8?q?=E3=82=88=E3=82=8B=E8=AD=9C=E9=9D=A2=E5=90=8D=E3=81=AE=E5=B9=85?= =?UTF-8?q?=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/danoni_main.js | 99 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 24 deletions(-) diff --git a/js/danoni_main.js b/js/danoni_main.js index c1cb8f78..e03cfd18 100644 --- a/js/danoni_main.js +++ b/js/danoni_main.js @@ -1492,6 +1492,53 @@ const getEmojiForCanvas = _str => { return result; }; +/** + * 複数行に跨る可能性のある文字列を、改行タグ付きの文字列とフォントサイズに変換 + * @param {string} _targetStr + * @param {number} _maxWidth + * @param {object} object + * @param {string} [object.font=getBasicFont()] + * @param {number} [object.maxSiz=14] + * @param {number} [object.minSiz=5] + * @param {number} [object.maxSizMulti=maxSiz] + * @param {string} [object.prefix=''] + * @param {number} [object.len=30] + * @param {string} [object.delim=' '] + * @returns {[string, number]} + */ +const getFontSizeMulti = (_targetStr, _maxWidth, { font = getBasicFont(), + maxSiz = 14, minSiz = 5, maxSizMulti = maxSiz, prefix = ``, len = 30, delim = ` ` } = {}) => { + + // _targetStr が長い場合のみ、その中身を 2つ に分解する + if (_targetStr.length > len) { + let breakNum = -1; + const halfIndex = Math.floor(_targetStr.length / 2); + + // 文字列の中央から前に向かってスペースを探す + for (let j = halfIndex; j > 0; j--) { + if (_targetStr[j] === ' ') { + breakNum = j; + break; + } + } + // スペースがなければ、中央(よりやや左)で強制分割 + if (breakNum === -1) { + breakNum = halfIndex; + } + const isSpace = _targetStr[breakNum] === ' '; + const firstPart = _targetStr.slice(0, breakNum); + const secondPart = _targetStr.slice(isSpace ? breakNum + 1 : breakNum); + + // 難易度名の中に
を仕込む + _targetStr = `${firstPart}
${secondPart}`; + } + + // 3. 最終的な文字列を結合(prefix と難易度名の1つ目の塊が1行目になる) + const fullStr = `${prefix}${_targetStr}`; + + return [fullStr, getFontSize2(fullStr, _maxWidth, { font, maxSiz: _targetStr.includes(`
`) ? maxSizMulti : maxSiz, minSiz })]; +}; + /** * 指定した横幅に合ったフォントサイズを取得 * @param {string} _str @@ -1502,8 +1549,16 @@ const getEmojiForCanvas = _str => { * @returns {number} */ const getFontSize2 = (_str, _maxWidth, { font = getBasicFont(), maxSiz = 14, minSiz = 5 } = {}) => { + // 文字列を改行で分割(null/undefined 対策も含む) + const lines = _str ? _str.split('
') : []; + if (lines.length === 0) return maxSiz; + + // 大きいサイズから順に試す for (let siz = maxSiz; siz >= minSiz; siz--) { - if (_maxWidth >= getStrWidth(getLongestStr(_str?.split(`
`)), siz, font)) { + // すべての行が _maxWidth 以内に収まるかチェック + const isFitAllLines = lines.every(line => _maxWidth >= getStrWidth(line, siz, font)); + + if (isFitAllLines) { return siz; } } @@ -8134,12 +8189,17 @@ const setDifficulty = (_initFlg) => { // 3. 名称の設定 // 譜面名設定 (Difficulty) - const difWidth = parseFloat(lnkDifficulty.style.width); + const difWidth = parseFloat(lnkDifficulty.style.width) - 20; const transKeyName = getTransKeyName(); const keyUnitName = getStgDetailName(getKeyUnitName(g_keyObj.currentKey)); - const difNames = [`${getKeyName(g_keyObj.currentKey)}${transKeyName} ${keyUnitName} / ${g_headerObj.difLabels[g_stateObj.scoreId]}`]; - lnkDifficulty.style.fontSize = wUnit(getFontSize2(difNames[0], difWidth, { maxSiz: g_limitObj.setLblSiz })); + const prefix = `${getKeyName(g_keyObj.currentKey)}${transKeyName} ${keyUnitName} / `; + let difLabel = `${g_headerObj.difLabels[g_stateObj.scoreId]}`; + + const [difName, difSiz] = getFontSizeMulti(difLabel, difWidth, { maxSiz: g_limitObj.setLblSiz, prefix }); + lnkDifficulty.style.fontSize = wUnit(difSiz); + + const difNames = [difName]; if (g_headerObj.makerView) { difNames.push(`(${g_headerObj.creatorNames[g_stateObj.scoreId]})`); difNames.forEach((difName, j) => { @@ -16786,7 +16846,8 @@ const resultInit = () => { makeCssResultPlayData(`lblMusicData`, dataRX, g_cssObj.result_style, 0, mTitleForView[0]), makeCssResultPlayData(`lblMusicData2`, dataRX, g_cssObj.result_style, 1, mTitleForView[1]), makeCssResultPlayData(`lblDifficulty`, lblRX, g_cssObj.result_lbl, 2, g_lblNameObj.rt_Difficulty, C_ALIGN_LEFT), - makeCssResultPlayData(`lblDifData`, dataRX, g_cssObj.result_style, 2, settingData.difData), + makeCssResultPlayData(`lblDifData`, dataRX, g_cssObj.result_style, 2, settingData.difData, C_ALIGN_CENTER, + { siz: getFontSize2(settingData.difData, 350) }), makeCssResultPlayData(`lblStyle`, lblRX, g_cssObj.result_lbl, 3, g_lblNameObj.rt_Style, C_ALIGN_LEFT), makeCssResultPlayData(`lblStyleData`, dataRX, g_cssObj.result_style, 3, settingData.playStyleData), makeCssResultPlayData(`lblDisplay`, lblRX, g_cssObj.result_lbl, 4, g_lblNameObj.rt_Display, C_ALIGN_LEFT), @@ -16795,21 +16856,9 @@ const resultInit = () => { ); // 設定項目が多い場合に2行に分解して表示する処理 - let playStyleBreakNum = lblStyleData.textContent.length; - if (lblStyleData.textContent.length > 60) { - for (let j = Math.floor(lblStyleData.textContent.length / 2); j > 0; j--) { - if (lblStyleData.textContent[j] === `,`) { - playStyleBreakNum = j + 2; - break; - } - } - lblStyleData.style.top = `${parseFloat(lblStyleData.style.top) - 3}px`; - lblStyleData.innerHTML = `${lblStyleData.textContent.slice(0, playStyleBreakNum)}
` + - `${lblStyleData.textContent.slice(playStyleBreakNum)}`; - lblStyleData.style.fontSize = `${getFontSize2(lblStyleData.textContent.slice(0, playStyleBreakNum), 350, { maxSiz: 10 })}px`; - } else { - lblStyleData.style.fontSize = `${getFontSize2(lblStyleData.textContent, 350)}px`; - } + const [styleStr, styleSiz] = getFontSizeMulti(settingData.playStyleData, 350, { maxSizMulti: 10, len: 60 }); + lblStyleData.innerHTML = styleStr; + lblStyleData.style.fontSize = wUnit(styleSiz); /** * キャラクタ、スコア描画のID共通部、色CSS名、スコア変数名 @@ -17243,6 +17292,7 @@ const resultInit = () => { const artistName = g_headerObj.artistNames[g_headerObj.musicNos[g_stateObj.scoreId]] || g_headerObj.artistName; const logicalWidth = 400; const logicalHeight = g_sHeight - 90; + const flapWidth = 370; canvas.id = `resultImage`; canvas.width = logicalWidth * g_dpr; @@ -17271,13 +17321,14 @@ const resultInit = () => { drawText(unEscapeHtml(mTitleForView[1]), { hy: 2 }); drawText(`${getEmojiForCanvas(g_emojiObj.memo)} ${unEscapeHtml(g_headerObj.tuning)} / ${getEmojiForCanvas(g_emojiObj.musical)} ${unEscapeHtml(artistName)}`, { hy: mTitleForView[1] !== `` ? 3 : 2, siz: 12 }); - drawText(unEscapeHtml(settingData.difDataForImage), { hy: 4 }); + drawText(unEscapeHtml(settingData.difDataForImage), { hy: 4, siz: getFontSize2(settingData.difDataForImage, flapWidth) }); if (settingData.playStyleData.length > 60) { - drawText(settingData.playStyleData.slice(0, playStyleBreakNum), { hy: 5, siz: getFontSize2(settingData.playStyleData.slice(0, playStyleBreakNum), 370) }); - drawText(settingData.playStyleData.slice(playStyleBreakNum), { hy: 6, siz: getFontSize2(settingData.playStyleData.slice(playStyleBreakNum), 370) }); + const strs = styleStr.split(`
`); + drawText(strs[0], { hy: 5, siz: getFontSize2(strs[0], flapWidth) }); + drawText(strs[1], { hy: 6, siz: getFontSize2(strs[1], flapWidth) }); } else { - drawText(settingData.playStyleData, { hy: 5, siz: getFontSize2(settingData.playStyleData, 370, { maxSiz: 15 }) }); + drawText(settingData.playStyleData, { hy: 5, siz: getFontSize2(settingData.playStyleData, flapWidth, { maxSiz: 15 }) }); } Object.keys(jdgScoreObj).forEach(score => { drawText(g_lblNameObj[`j_${score}`], { hy: 7 + jdgScoreObj[score].pos, color: jdgScoreObj[score].dfColor }); From 9830f923d70273f9ba23358802f86193f0d60f65 Mon Sep 17 00:00:00 2001 From: tickle Date: Mon, 22 Jun 2026 21:05:53 +0900 Subject: [PATCH 2/4] =?UTF-8?q?refactor:=20=E3=83=AC=E3=83=93=E3=83=A5?= =?UTF-8?q?=E3=83=BC=E5=86=85=E5=AE=B9=E3=82=92=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/danoni_main.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/danoni_main.js b/js/danoni_main.js index e03cfd18..bccf06f0 100644 --- a/js/danoni_main.js +++ b/js/danoni_main.js @@ -1516,7 +1516,7 @@ const getFontSizeMulti = (_targetStr, _maxWidth, { font = getBasicFont(), // 文字列の中央から前に向かってスペースを探す for (let j = halfIndex; j > 0; j--) { - if (_targetStr[j] === ' ') { + if (_targetStr[j] === delim) { breakNum = j; break; } @@ -1525,9 +1525,9 @@ const getFontSizeMulti = (_targetStr, _maxWidth, { font = getBasicFont(), if (breakNum === -1) { breakNum = halfIndex; } - const isSpace = _targetStr[breakNum] === ' '; + const isSpace = _targetStr[breakNum] === delim; const firstPart = _targetStr.slice(0, breakNum); - const secondPart = _targetStr.slice(isSpace ? breakNum + 1 : breakNum); + const secondPart = _targetStr.slice(isSpace ? breakNum + delim.length : breakNum); // 難易度名の中に
を仕込む _targetStr = `${firstPart}
${secondPart}`; From 685d1b9124db392de72fa885495b18d77fe1ec44 Mon Sep 17 00:00:00 2001 From: tickle Date: Mon, 22 Jun 2026 21:50:05 +0900 Subject: [PATCH 3/4] =?UTF-8?q?change:=20=E8=AD=9C=E9=9D=A2=E9=81=B8?= =?UTF-8?q?=E6=8A=9E=E3=83=AA=E3=82=B9=E3=83=88=E3=81=A7=E8=AD=9C=E9=9D=A2?= =?UTF-8?q?=E5=90=8D=E3=81=8C=E9=95=B7=E3=81=84=E5=A0=B4=E5=90=88=E3=81=B8?= =?UTF-8?q?=E3=81=AE=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/danoni_main.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/js/danoni_main.js b/js/danoni_main.js index bccf06f0..7b207ab4 100644 --- a/js/danoni_main.js +++ b/js/danoni_main.js @@ -7235,12 +7235,21 @@ const makeDifList = (_difList, _targetKey = ``) => { g_headerObj.viewLists.forEach(j => { const keyLabel = g_headerObj.keyLabels[j]; if (_targetKey === `` || keyLabel === _targetKey) { - let text = `${getKeyName(keyLabel)} / ${g_headerObj.difLabels[j]}`; + + // 譜面名の表示 + const prefix = `${getKeyName(keyLabel)} / `; + let text = `${g_headerObj.difLabels[j]}`; if (g_headerObj.makerView) { text += ` (${g_headerObj.creatorNames[j]})`; } - _difList.appendChild(makeDifLblCssButton(`dif${k}`, text, k, () => nextDifficulty(j - g_stateObj.scoreId), - { btnStyle: (j === g_stateObj.scoreId ? `Setting` : `Default`) })); + // キー種と譜面名に分割し、譜面名が長すぎる場合は二段に分割して表示 + const [difText, difSiz] = getFontSizeMulti(text, g_limitObj.difSelectorWidth, { + maxSiz: g_limitObj.difSelectorSiz, maxSizMulti: 9, prefix, + }) + _difList.appendChild(makeDifLblCssButton(`dif${k}`, difText, k, () => nextDifficulty(j - g_stateObj.scoreId), { + btnStyle: (j === g_stateObj.scoreId ? `Setting` : `Default`), siz: difSiz, + })); + document.getElementById(`dif${k}`).style.lineHeight = `9px`; if (j === g_stateObj.scoreId) { pos = k + 6.5 * (g_sHeight - 239) / 261; curk = k; From f3f182537c6ed2999765f1e0d1b1bf1808960e51 Mon Sep 17 00:00:00 2001 From: tickle Date: Mon, 22 Jun 2026 22:04:46 +0900 Subject: [PATCH 4/4] =?UTF-8?q?change:=20=E6=8A=98=E3=82=8A=E8=BF=94?= =?UTF-8?q?=E3=81=97=E6=96=87=E5=AD=97=E3=81=AE=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/danoni_main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/danoni_main.js b/js/danoni_main.js index 7b207ab4..d5274671 100644 --- a/js/danoni_main.js +++ b/js/danoni_main.js @@ -1507,7 +1507,7 @@ const getEmojiForCanvas = _str => { * @returns {[string, number]} */ const getFontSizeMulti = (_targetStr, _maxWidth, { font = getBasicFont(), - maxSiz = 14, minSiz = 5, maxSizMulti = maxSiz, prefix = ``, len = 30, delim = ` ` } = {}) => { + maxSiz = 14, minSiz = 5, maxSizMulti = maxSiz, prefix = ``, len = 20, delim = ` ` } = {}) => { // _targetStr が長い場合のみ、その中身を 2つ に分解する if (_targetStr.length > len) { @@ -7244,7 +7244,7 @@ const makeDifList = (_difList, _targetKey = ``) => { } // キー種と譜面名に分割し、譜面名が長すぎる場合は二段に分割して表示 const [difText, difSiz] = getFontSizeMulti(text, g_limitObj.difSelectorWidth, { - maxSiz: g_limitObj.difSelectorSiz, maxSizMulti: 9, prefix, + maxSiz: g_limitObj.difSelectorSiz, maxSizMulti: 9, prefix, len: 30, }) _difList.appendChild(makeDifLblCssButton(`dif${k}`, difText, k, () => nextDifficulty(j - g_stateObj.scoreId), { btnStyle: (j === g_stateObj.scoreId ? `Setting` : `Default`), siz: difSiz,