danoniplus 47.6.1 → 47.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/js/danoni_main.js +88 -116
  2. package/package.json +1 -1
package/js/danoni_main.js CHANGED
@@ -4,12 +4,12 @@
4
4
  *
5
5
  * Source by tickle
6
6
  * Created : 2018/10/08
7
- * Revised : 2026/05/13
7
+ * Revised : 2026/05/15
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 47.6.1`;
12
- const g_revisedDate = `2026/05/13`;
11
+ const g_version = `Ver 47.6.3`;
12
+ const g_revisedDate = `2026/05/15`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -88,6 +88,7 @@ const g_remoteDomain = detectDomain(g_rootPath);
88
88
 
89
89
  const g_randTime = Date.now();
90
90
  const g_versionForUrl = g_version.slice(4); // URL用に先頭の"Ver "を削除
91
+ const g_dpr = window.devicePixelRatio || 1;
91
92
 
92
93
  const g_isFile = location.href.match(/^file/);
93
94
  const g_isLocal = location.href.match(/^file/) || location.href.indexOf(`localhost`) !== -1;
@@ -3380,7 +3381,6 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
3380
3381
  _keyCtrlPtn,
3381
3382
  config: {
3382
3383
  scale: 1.5,
3383
- dpr: window.devicePixelRatio || 1,
3384
3384
  timeMargin: 35,
3385
3385
  mmWidthBase: (g_sWidth - 500) / 2 + 290,
3386
3386
  mmMarginY: 2,
@@ -3389,7 +3389,7 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
3389
3389
  },
3390
3390
  get logicalWidth() {
3391
3391
  const logicalWidth = this.timeMargin + (this.laneWidth * keyNum);
3392
- return Math.ceil(logicalWidth * this.dpr) / this.dpr;
3392
+ return Math.ceil(logicalWidth * g_dpr) / g_dpr;
3393
3393
  }
3394
3394
  },
3395
3395
  };
@@ -3403,16 +3403,15 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
3403
3403
  * 指定された高さに基づいて分割されたCanvasリストを生成する
3404
3404
  * @param {number} _width
3405
3405
  * @param {number} _totalHeight
3406
- * @param {number} _dpr
3407
3406
  * @return {object[]} 分割されたCanvasとそのコンテキスト、オフセット情報を含むリスト
3408
3407
  */
3409
- const createSplitCanvases = (_width, _totalHeight, _dpr) => {
3408
+ const createSplitCanvases = (_width, _totalHeight) => {
3410
3409
  // バックバッファ(実際のピクセル数)の最大値を 8000 に設定(iOS Safari 8192px 対策)
3411
3410
  const BACKING_STORE_LIMIT = 8000;
3412
3411
 
3413
3412
  // 論理上の最大高さ(CSSピクセル)を計算
3414
- // dpr=2なら4000px、dpr=3なら2666px が1枚の限界になる
3415
- const maxLogicalHeight = Math.max(1, Math.floor(BACKING_STORE_LIMIT / _dpr));
3413
+ // g_dpr=2なら4000px、g_dpr=3なら2666px が1枚の限界になる
3414
+ const maxLogicalHeight = Math.max(1, Math.floor(BACKING_STORE_LIMIT / g_dpr));
3416
3415
  if (_totalHeight <= 0) return [];
3417
3416
 
3418
3417
  const count = Math.ceil(_totalHeight / maxLogicalHeight);
@@ -3426,8 +3425,8 @@ const createSplitCanvases = (_width, _totalHeight, _dpr) => {
3426
3425
  : maxLogicalHeight;
3427
3426
 
3428
3427
  // 実際の描画解像度をセット
3429
- cvs.width = _width * _dpr;
3430
- cvs.height = logicalH * _dpr;
3428
+ cvs.width = _width * g_dpr;
3429
+ cvs.height = logicalH * g_dpr;
3431
3430
 
3432
3431
  // ブラウザ上の表示サイズをセット
3433
3432
  cvs.style.width = `${_width}px`;
@@ -3435,7 +3434,7 @@ const createSplitCanvases = (_width, _totalHeight, _dpr) => {
3435
3434
  cvs.style.display = 'block';
3436
3435
 
3437
3436
  const ctx = cvs.getContext('2d');
3438
- ctx.scale(_dpr, _dpr);
3437
+ ctx.scale(g_dpr, g_dpr);
3439
3438
 
3440
3439
  list.push({
3441
3440
  canvas: cvs,
@@ -3474,7 +3473,6 @@ const distributeDrawing = (_canvases, _y, _h, _dpr, _drawFunc) => {
3474
3473
  /**
3475
3474
  * 譜面ミニマップ:キー名を表示するヘッダーキャンバスを作成する
3476
3475
  * @param {object} _config ミニマップの基本設定
3477
- * @param {number} _config.dpr デバイスピクセル比
3478
3476
  * @param {number} _config.timeMargin 時間軸のマージン
3479
3477
  * @param {number} _config.laneWidth レーンの幅
3480
3478
  * @param {number} _config.logicalWidth キャンバスの論理幅
@@ -3483,20 +3481,20 @@ const distributeDrawing = (_canvases, _y, _h, _dpr, _drawFunc) => {
3483
3481
  * @return {HTMLCanvasElement} ヘッダー用のキャンバス要素
3484
3482
  */
3485
3483
  const createMinimapHeader = (_config, _keyCtrlPtn, _keyNum) => {
3486
- const { dpr, timeMargin, laneWidth, logicalWidth } = _config;
3484
+ const { timeMargin, laneWidth, logicalWidth } = _config;
3487
3485
  const headerHeight = 15; // ヘッダーの固定高
3488
3486
 
3489
3487
  const canvas = document.createElement('canvas');
3490
3488
  const ctx = canvas.getContext('2d');
3491
3489
 
3492
3490
  // 解像度と表示サイズの設定
3493
- canvas.width = logicalWidth * dpr;
3494
- canvas.height = headerHeight * dpr;
3491
+ canvas.width = logicalWidth * g_dpr;
3492
+ canvas.height = headerHeight * g_dpr;
3495
3493
  canvas.style.width = `${logicalWidth}px`;
3496
3494
  canvas.style.height = `${headerHeight}px`;
3497
3495
  canvas.style.display = 'block';
3498
3496
 
3499
- ctx.scale(dpr, dpr);
3497
+ ctx.scale(g_dpr, g_dpr);
3500
3498
 
3501
3499
  // テキストのスタイル設定
3502
3500
  ctx.fillStyle = '#999';
@@ -3526,7 +3524,6 @@ const createMinimapHeader = (_config, _keyCtrlPtn, _keyNum) => {
3526
3524
  * @param {string} _params._keyCtrlPtn キーコントロールパターン
3527
3525
  * @param {object} _params.config ミニマップの基本設定
3528
3526
  * @param {number} _params.config.scale ミニマップの時間軸のスケール
3529
- * @param {number} _params.config.dpr デバイスピクセル比
3530
3527
  * @param {number} _params.config.timeMargin 時間軸のマージン
3531
3528
  * @param {number} _params.config.laneWidth レーンの幅
3532
3529
  * @param {number} _params.config.logicalWidth キャンバスの論理幅
@@ -3536,10 +3533,10 @@ const createMinimapHeader = (_config, _keyCtrlPtn, _keyNum) => {
3536
3533
  */
3537
3534
  const generateMinimapData = (_params, _isReverse) => {
3538
3535
  const { _scoreObj, _keyNum, _playingFrame, _firstArrowFrame, _keyCtrlPtn, config } = _params;
3539
- const { scale, dpr, timeMargin, laneWidth, logicalWidth, mmMarginY } = config;
3536
+ const { scale, timeMargin, laneWidth, logicalWidth, mmMarginY } = config;
3540
3537
 
3541
3538
  const mmHeightTotal = _playingFrame * scale + mmMarginY * 2;
3542
- const canvases = createSplitCanvases(logicalWidth, mmHeightTotal, dpr);
3539
+ const canvases = createSplitCanvases(logicalWidth, mmHeightTotal);
3543
3540
 
3544
3541
  const getY = (frame) => {
3545
3542
  const relativeFrame = frame - _firstArrowFrame;
@@ -3554,7 +3551,7 @@ const generateMinimapData = (_params, _isReverse) => {
3554
3551
  const interval = g_fps;
3555
3552
  for (let f = Math.ceil(_firstArrowFrame / interval) * interval; f <= _firstArrowFrame + _playingFrame; f += interval) {
3556
3553
  const y = getY(f);
3557
- distributeDrawing(canvases, y - 5, 10, dpr, (ctx) => {
3554
+ distributeDrawing(canvases, y - 5, 10, g_dpr, (ctx) => {
3558
3555
  ctx.strokeStyle = '#444';
3559
3556
  ctx.fillStyle = '#999';
3560
3557
  ctx.font = `10px ${getBasicFont()}`;
@@ -3583,7 +3580,7 @@ const generateMinimapData = (_params, _isReverse) => {
3583
3580
  const top = Math.min(y1, y2);
3584
3581
  const h = Math.abs(y2 - y1);
3585
3582
  const x = timeMargin + j * laneWidth;
3586
- distributeDrawing(canvases, top, h, dpr, (ctx) => {
3583
+ distributeDrawing(canvases, top, h, g_dpr, (ctx) => {
3587
3584
  ctx.fillStyle = 'rgba(0, 200, 255, 0.4)';
3588
3585
  ctx.fillRect(x + 2, top, laneWidth - 3, h);
3589
3586
  ctx.strokeStyle = 'rgba(0, 200, 255, 0.8)';
@@ -3597,7 +3594,7 @@ const generateMinimapData = (_params, _isReverse) => {
3597
3594
  const color = g_dfColorObj.setColorType2[g_keyObj[`color${_keyCtrlPtn}_0`][j]] || '#ffffff';
3598
3595
  _scoreObj.arrowData[j].forEach(note => {
3599
3596
  const y = getY(parseFloat(note));
3600
- distributeDrawing(canvases, y - 1.5, 3, dpr, (ctx) => {
3597
+ distributeDrawing(canvases, y - 1.5, 3, g_dpr, (ctx) => {
3601
3598
  ctx.fillStyle = color;
3602
3599
  ctx.fillRect(timeMargin + j * laneWidth + 1, y - 1.5, laneWidth - 1, 3);
3603
3600
  });
@@ -8239,9 +8236,8 @@ const createOptionWindow = _sprite => {
8239
8236
  const bkColor = window.getComputedStyle(textBaseObj, ``).backgroundColor;
8240
8237
 
8241
8238
  graphObj.id = `graph${_name}${j > 0 ? j + 1 : ``}`;
8242
- const dpr = window.devicePixelRatio || 1;
8243
- graphObj.width = g_limitObj.graphWidth * dpr;
8244
- graphObj.height = g_limitObj.graphHeight * dpr;
8239
+ graphObj.width = g_limitObj.graphWidth * g_dpr;
8240
+ graphObj.height = g_limitObj.graphHeight * g_dpr;
8245
8241
  graphObj.style.width = wUnit(g_limitObj.graphWidth);
8246
8242
  graphObj.style.height = wUnit(g_limitObj.graphHeight);
8247
8243
  graphObj.style.left = wUnit(125);
@@ -8249,7 +8245,7 @@ const createOptionWindow = _sprite => {
8249
8245
  graphObj.style.position = `absolute`;
8250
8246
  graphObj.style.background = j === 0 ? bkColor : `#ffffff00`;
8251
8247
  const ctx = graphObj.getContext(`2d`);
8252
- ctx.scale(dpr, dpr);
8248
+ ctx.scale(g_dpr, g_dpr);
8253
8249
 
8254
8250
  detailObj.appendChild(graphObj);
8255
8251
  }
@@ -10400,7 +10396,7 @@ const keyconfigKeyboardPreview = (() => {
10400
10396
  shortcutStroke: `#ff4466`, // ショートカットキー枠
10401
10397
  shortcutText: `#ffaacc`, // ショートカットキー文字
10402
10398
  bgFill: `#0d0d1a`, // Canvas 背景
10403
- legendText: `#888899`, // 凡例テキスト
10399
+ legendText: `#cccccc`, // 凡例テキスト
10404
10400
  };
10405
10401
 
10406
10402
  // ボタン配置
@@ -10421,8 +10417,7 @@ const keyconfigKeyboardPreview = (() => {
10421
10417
  // キーレイアウト定義
10422
10418
  //
10423
10419
  // 各行: { offsetX, keys }
10424
- // offsetX : 行左端の水平オフセット(単位: BASE_KEY_W)。全行 0 で統一し、
10425
- // L)Shift の幅で行頭位置を調整する。
10420
+ // offsetX : 行左端の水平オフセット(単位: BASE_KEY_W)。未指定時は0
10426
10421
  // keys : キー定義の配列
10427
10422
  //
10428
10423
  // 各キー: { kc, w?, h?, label? }
@@ -10446,7 +10441,6 @@ const keyconfigKeyboardPreview = (() => {
10446
10441
  return [
10447
10442
  // Row0: Fn キー行(JIS/US 共通)
10448
10443
  {
10449
- offsetX: 0,
10450
10444
  keys: [
10451
10445
  { kc: 27 }, // Esc
10452
10446
  { kc: -1, w: 0.5 }, // スペーサー
@@ -10461,16 +10455,13 @@ const keyconfigKeyboardPreview = (() => {
10461
10455
  // JIS: ..., 220(intlYen), BS
10462
10456
  // US : ..., BS
10463
10457
  {
10464
- offsetX: 0,
10465
10458
  keys: [
10466
10459
  { kc: 229 },
10467
- { kc: 49 }, { kc: 50 }, { kc: 51 },
10468
- { kc: 52 }, { kc: 53 }, { kc: 54 },
10469
- { kc: 55 }, { kc: 56 }, { kc: 57 },
10470
- { kc: 48 }, { kc: 189 }, { kc: 222 },
10460
+ { kc: 49 }, { kc: 50 }, { kc: 51 }, { kc: 52 }, { kc: 53 }, { kc: 54 },
10461
+ { kc: 55 }, { kc: 56 }, { kc: 57 }, { kc: 48 }, { kc: 189 }, { kc: 222 },
10471
10462
  ...(isJa
10472
- ? [{ kc: 220, w: 0.75 }, { kc: 8 }] // JIS: intlYen + BS
10473
- : [{ kc: 8, w: 1.7 }] // US : BS のみ(広い)
10463
+ ? [{ kc: 220, w: 0.75 }, { kc: 8, label: `Back\nSpace` }] // JIS: intlYen + BS
10464
+ : [{ kc: 8, w: 1.7 }] // US : BS のみ(広い)
10474
10465
  ),
10475
10466
  ],
10476
10467
  },
@@ -10478,13 +10469,10 @@ const keyconfigKeyboardPreview = (() => {
10478
10469
  // JIS: ..., [, Enter(13)
10479
10470
  // US : ..., [, ]
10480
10471
  {
10481
- offsetX: 0,
10482
10472
  keys: [
10483
10473
  { kc: 9, w: 1.5 },
10484
- { kc: 81 }, { kc: 87 }, { kc: 69 },
10485
- { kc: 82 }, { kc: 84 }, { kc: 89 },
10486
- { kc: 85 }, { kc: 73 }, { kc: 79 },
10487
- { kc: 80 }, { kc: 192 },
10474
+ { kc: 81 }, { kc: 87 }, { kc: 69 }, { kc: 82 }, { kc: 84 }, { kc: 89 },
10475
+ { kc: 85 }, { kc: 73 }, { kc: 79 }, { kc: 80 }, { kc: 192 },
10488
10476
  ...(isJa
10489
10477
  ? [{ kc: 219 }, { kc: 13, w: 1.25, h: 2 }] // JIS: [, Enter縦長
10490
10478
  : [{ kc: 219 }, { kc: 221, w: 1.2 }] // US : [, ]
@@ -10495,13 +10483,10 @@ const keyconfigKeyboardPreview = (() => {
10495
10483
  // JIS: ..., L, ;, ', ¥(221)
10496
10484
  // US : ..., L, ;, ', Enter(13)
10497
10485
  {
10498
- offsetX: 0,
10499
10486
  keys: [
10500
- { kc: 20, w: 1.75, label: `CapsLk` },
10501
- { kc: 65 }, { kc: 83 }, { kc: 68 },
10502
- { kc: 70 }, { kc: 71 }, { kc: 72 },
10503
- { kc: 74 }, { kc: 75 }, { kc: 76 },
10504
- { kc: 187 }, { kc: 186 },
10487
+ { kc: 20, w: 1.75, label: `Caps\nLock` },
10488
+ { kc: 65 }, { kc: 83 }, { kc: 68 }, { kc: 70 }, { kc: 71 }, { kc: 72 },
10489
+ { kc: 74 }, { kc: 75 }, { kc: 76 }, { kc: 187 }, { kc: 186 },
10505
10490
  ...(isJa
10506
10491
  ? [{ kc: 221 }] // JIS: ¥
10507
10492
  : [{ kc: 13, w: 1.9 }] // US : Enter横長
@@ -10513,16 +10498,13 @@ const keyconfigKeyboardPreview = (() => {
10513
10498
  // JIS: L)Shift, ..., intlRo(226), R)Shift
10514
10499
  // US : L)Shift, ..., R)Shift
10515
10500
  {
10516
- offsetX: 0,
10517
10501
  keys: [
10518
10502
  { kc: 16, w: 2.25 },
10519
- { kc: 90 }, { kc: 88 }, { kc: 67 },
10520
- { kc: 86 }, { kc: 66 }, { kc: 78 },
10521
- { kc: 77 }, { kc: 188 }, { kc: 190 },
10522
- { kc: 191 },
10503
+ { kc: 90 }, { kc: 88 }, { kc: 67 }, { kc: 86 }, { kc: 66 }, { kc: 78 },
10504
+ { kc: 77 }, { kc: 188 }, { kc: 190 }, { kc: 191 },
10523
10505
  ...(isJa
10524
10506
  ? [{ kc: 226 }, { kc: 256, w: 1.5 }] // JIS: intlRo + R)Shift
10525
- : [{ kc: 256, w: 2.4 }] // US : R)Shift のみ(広い)
10507
+ : [{ kc: 256, w: 2.4 }] // US : R)Shift のみ(広い)
10526
10508
  ),
10527
10509
  ],
10528
10510
  },
@@ -10530,24 +10512,15 @@ const keyconfigKeyboardPreview = (() => {
10530
10512
  // JIS: ..., NoConv(29), Space, Conv(28), カタカナひらがな(242), ...
10531
10513
  // US : ..., Space, ...
10532
10514
  {
10533
- offsetX: 0,
10534
10515
  keys: [
10535
- { kc: 17, w: 1.25 },
10536
- { kc: 91 },
10537
- { kc: 18 },
10516
+ { kc: 17, w: 1.25 }, { kc: 91 }, { kc: 18 },
10538
10517
  ...(isJa
10539
- ? [
10540
- { kc: 29 },
10541
- { kc: 32, w: 5.25 },
10542
- { kc: 28 },
10543
- { kc: 242 },
10544
- ]
10545
- : [
10546
- { kc: 32, w: 8.25 },
10547
- ]
10518
+ // JIS: NoConv + Space + Conv + カタカナひらがな
10519
+ ? [{ kc: 29 }, { kc: 32, w: 5.25 }, { kc: 28 }, { kc: 242 }]
10520
+ // US : Space のみ(広い)
10521
+ : [{ kc: 32, w: 8.25 }]
10548
10522
  ),
10549
- { kc: 258 },
10550
- { kc: 93 },
10523
+ { kc: 258 }, { kc: 93 },
10551
10524
  ...(isJa
10552
10525
  ? [{ kc: 257, w: 1.2 }]
10553
10526
  : [{ kc: 257, w: 1.05 }]
@@ -10559,12 +10532,12 @@ const keyconfigKeyboardPreview = (() => {
10559
10532
  // 編集キークラスター(PrintSc/ScrollLk/Pause/Insert/Delete/Home/End/PgUp/PgDn + 矢印キー)
10560
10533
  // MAIN_ROWS と行インデックスを揃えて配置する。空行はスキップされる。
10561
10534
  const NAV_ROWS = [
10562
- { offsetX: 0, keys: [{ kc: 44, label: `PrintSc` }, { kc: 145, label: `ScrollLk` }, { kc: 19 }] }, // PrintSc ScrollLk Pause
10563
- { offsetX: 0, keys: [{ kc: 45 }, { kc: 36 }, { kc: 33 }] }, // Insert Home PgUp
10564
- { offsetX: 0, keys: [{ kc: 46 }, { kc: 35 }, { kc: 34 }] }, // Delete End PgDn
10565
- { offsetX: 0, keys: [] }, // ASDF行:空
10566
- { offsetX: 0, keys: [{ kc: -1 }, { kc: 38 }, { kc: -1 }] }, // ↑
10567
- { offsetX: 0, keys: [{ kc: 37 }, { kc: 40 }, { kc: 39 }] }, // ← ↓ →
10535
+ { keys: [{ kc: 44, label: `Print\nScreen` }, { kc: 145, label: `Scroll\nLock` }, { kc: 19 }] },
10536
+ { keys: [{ kc: 45 }, { kc: 36 }, { kc: 33, label: `Page\nUp` }] }, // Insert Home PgUp
10537
+ { keys: [{ kc: 46 }, { kc: 35 }, { kc: 34, label: `Page\nDown` }] }, // Delete End PgDn
10538
+ { keys: [] }, // ASDF行:空
10539
+ { keys: [{ kc: -1 }, { kc: 38 }, { kc: -1 }] }, // ↑
10540
+ { keys: [{ kc: 37 }, { kc: 40 }, { kc: 39 }] }, // ← ↓ →
10568
10541
  ];
10569
10542
 
10570
10543
  // テンキー(MAIN_ROWS と行インデックスを揃えて配置。1行目は空行で Fn行に揃える)
@@ -10576,12 +10549,12 @@ const keyconfigKeyboardPreview = (() => {
10576
10549
  // [T1][T2][T3] [TEnter]
10577
10550
  // [ T0 ][T.] [TEnter] ← T0 は横2u、TEnter は縦2u
10578
10551
  const NUM_ROWS = [
10579
- { offsetX: 0, keys: [] },
10580
- { offsetX: 0, keys: [{ kc: 144 }, { kc: 111 }, { kc: 106 }, { kc: 109 }] }, // NumLk T/ T* T-
10581
- { offsetX: 0, keys: [{ kc: 103 }, { kc: 104 }, { kc: 105 }, { kc: 107, h: 2 }] }, // T7 T8 T9 T+(縦2u)
10582
- { offsetX: 0, keys: [{ kc: 100 }, { kc: 101 }, { kc: 102 }] }, // T4 T5 T6
10583
- { offsetX: 0, keys: [{ kc: 97 }, { kc: 98 }, { kc: 99 }, { kc: 108, h: 2 }] }, // T1 T2 T3 TEnter(縦2u)
10584
- { offsetX: 0, keys: [{ kc: 96, w: 2 }, { kc: 110 }] }, // T0(横2u) T.
10552
+ { keys: [] },
10553
+ { keys: [{ kc: 144, label: `Num\nLock` }, { kc: 111 }, { kc: 106 }, { kc: 109 }] }, // NumLk T/ T* T-
10554
+ { keys: [{ kc: 103 }, { kc: 104 }, { kc: 105 }, { kc: 107, h: 2 }] }, // T7 T8 T9 T+(縦2u)
10555
+ { keys: [{ kc: 100 }, { kc: 101 }, { kc: 102 }] }, // T4 T5 T6
10556
+ { keys: [{ kc: 97 }, { kc: 98 }, { kc: 99 }, { kc: 108, h: 2 }] }, // T1 T2 T3 TEnter(縦2u)
10557
+ { keys: [{ kc: 96, w: 2 }, { kc: 110 }] }, // T0(横2u) T.
10585
10558
  ];
10586
10559
 
10587
10560
  // -------------------------------------------------------------------------
@@ -10669,7 +10642,7 @@ const keyconfigKeyboardPreview = (() => {
10669
10642
  if (forcedLabel !== undefined) return [forcedLabel, ``];
10670
10643
 
10671
10644
  const raw = g_kCd[kc];
10672
- if (raw && raw !== `- - -` && raw !== `Unknown`) {
10645
+ if (raw && raw !== g_kCd[0] && raw !== g_kCd[1]) {
10673
10646
  const parts = raw.split(` `);
10674
10647
  return [parts[0] || ``, parts[1] || ``];
10675
10648
  }
@@ -10701,22 +10674,31 @@ const keyconfigKeyboardPreview = (() => {
10701
10674
  };
10702
10675
 
10703
10676
  const drawKeyLabel = (ctx, x, y, keyW, keyH, primary, sub, textColor, subColor) => {
10704
- const fs = primary.length >= 5
10705
- ? Math.max(6, Math.floor(8 * _state.scale))
10677
+ const fs = (_textLen) => _textLen >= 5 * keyW / BASE_KEY_W
10678
+ ? Math.max(6, Math.floor(9 * _state.scale))
10706
10679
  : Math.max(7, Math.floor(11 * _state.scale));
10707
10680
 
10708
10681
  if (sub) {
10709
10682
  ctx.fillStyle = subColor;
10710
- ctx.font = `bold ${Math.max(6, Math.floor(8 * _state.scale))}px monospace`;
10683
+ ctx.font = `bold ${Math.max(6, Math.floor(9 * _state.scale))}px monospace`;
10711
10684
  ctx.textAlign = `right`;
10712
10685
  ctx.textBaseline = `top`;
10713
10686
  ctx.fillText(sub, x + keyW - 2, y + 2);
10714
10687
  }
10688
+ const [primary1, primary2] = primary.split(`\n`);
10715
10689
  ctx.fillStyle = textColor;
10716
- ctx.font = `bold ${fs}px monospace`;
10717
10690
  ctx.textAlign = `center`;
10718
10691
  ctx.textBaseline = `middle`;
10719
- ctx.fillText(primary, x + keyW / 2, y + keyH / 2 + (sub ? 2 : 0));
10692
+ const subDiff = sub ? 2 : 0;
10693
+ if (primary2) {
10694
+ const siz = fs(Math.max(primary1.length, primary2.length));
10695
+ ctx.font = `bold ${siz}px monospace`;
10696
+ ctx.fillText(primary1, x + keyW / 2, y + keyH / 2 - siz / 2 + subDiff);
10697
+ ctx.fillText(primary2, x + keyW / 2, y + keyH / 2 + siz / 2 + subDiff);
10698
+ } else {
10699
+ ctx.font = `bold ${fs(primary.length)}px monospace`;
10700
+ ctx.fillText(primary, x + keyW / 2, y + keyH / 2 + subDiff);
10701
+ }
10720
10702
  };
10721
10703
 
10722
10704
  const drawOneKey = (ctx, x, y, keyW, keyH, fill, stroke, lw, primary, sub, textColor, subColor) => {
@@ -10750,7 +10732,7 @@ const keyconfigKeyboardPreview = (() => {
10750
10732
  if (rowDef.keys.length === 0) return;
10751
10733
 
10752
10734
  const rowY = originY + rowIdx * (baseKeyH + gap);
10753
- const startX = originX + Math.floor(rowDef.offsetX * BASE_KEY_W * _state.scale);
10735
+ const startX = originX + Math.floor((rowDef.offsetX || 0) * BASE_KEY_W * _state.scale);
10754
10736
  let curX = startX;
10755
10737
 
10756
10738
  rowDef.keys.forEach(keyDef => {
@@ -10787,15 +10769,14 @@ const keyconfigKeyboardPreview = (() => {
10787
10769
  const canvas = _state.canvasBase;
10788
10770
  if (!canvas) return;
10789
10771
 
10790
- const dpr = window.devicePixelRatio || 1;
10791
10772
  canvas.style.top = wUnit(40);
10792
- canvas.width = _state.cvsW * dpr;
10793
- canvas.height = _state.cvsH * dpr;
10773
+ canvas.width = _state.cvsW * g_dpr;
10774
+ canvas.height = _state.cvsH * g_dpr;
10794
10775
  canvas.style.width = wUnit(_state.cvsW);
10795
10776
  canvas.style.height = wUnit(_state.cvsH);
10796
10777
 
10797
10778
  const ctx = canvas.getContext(`2d`);
10798
- ctx.scale(dpr, dpr);
10779
+ ctx.scale(g_dpr, g_dpr);
10799
10780
  ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
10800
10781
  ctx.fillStyle = C_COLOR.bgFill;
10801
10782
  ctx.fillRect(0, 0, _state.cvsW, _state.cvsH);
@@ -10822,7 +10803,7 @@ const keyconfigKeyboardPreview = (() => {
10822
10803
 
10823
10804
  // 凡例
10824
10805
  const ly = _state.cvsH - 10;
10825
- const fnt = `${Math.max(9, Math.floor(10 * _state.scale))}px ${getBasicFont()}`;
10806
+ const fnt = `${Math.max(9, Math.floor(12 * _state.scale))}px ${getBasicFont()}`;
10826
10807
  ctx.font = fnt;
10827
10808
  ctx.textAlign = `left`;
10828
10809
  ctx.textBaseline = `middle`;
@@ -10852,15 +10833,14 @@ const keyconfigKeyboardPreview = (() => {
10852
10833
  const canvas = _state.canvasMap;
10853
10834
  if (!canvas) return;
10854
10835
 
10855
- const dpr = window.devicePixelRatio || 1;
10856
10836
  canvas.style.top = wUnit(40);
10857
- canvas.width = _state.cvsW * dpr;
10858
- canvas.height = _state.cvsH * dpr;
10837
+ canvas.width = _state.cvsW * g_dpr;
10838
+ canvas.height = _state.cvsH * g_dpr;
10859
10839
  canvas.style.width = wUnit(_state.cvsW);
10860
10840
  canvas.style.height = wUnit(_state.cvsH);
10861
10841
 
10862
10842
  const ctx = canvas.getContext(`2d`);
10863
- ctx.scale(dpr, dpr);
10843
+ ctx.scale(g_dpr, g_dpr);
10864
10844
  ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
10865
10845
 
10866
10846
  // 優先度: ショートカット > メイン > 代替(後から描くほど優先)
@@ -10907,40 +10887,34 @@ const keyconfigKeyboardPreview = (() => {
10907
10887
 
10908
10888
  // ボタン: キャンバス横幅中央に配置、小さいサイズ
10909
10889
  const btnW = 80;
10910
- const btnX = Math.floor((g_btnWidth() - btnW) / 2);
10890
+ const btnX = g_btnX() + Math.floor((g_btnWidth() - btnW) / 2);
10911
10891
 
10912
10892
  // "↓ Preview" → 展開、"↑ Preview" → 閉じる のトグルボタン
10913
10893
  const btn = createCss2Button(C_BTN_ID, `↓ Preview`, () => {
10914
10894
  togglePreview();
10915
10895
  btn.textContent = _state.visible ? `↑ Preview` : `↓ Preview`;
10916
10896
  }, {
10917
- x: btnX, y: BTN_Y, w: btnW, h: BTN_H,
10897
+ x: btnX, y: BTN_Y, w: btnW, h: BTN_H, siz: BTN_FS,
10918
10898
  title: g_msgObj.kcPreview,
10919
10899
  }, g_cssObj.button_Setting);
10920
- btn.style.fontSize = `${BTN_FS}px`;
10921
10900
  divRoot.appendChild(btn);
10922
10901
 
10923
10902
  // プレビューエリア: 水平・垂直センタリング
10924
- const areaX = Math.floor((g_btnWidth() - _state.cvsW) / 2);
10903
+ const areaX = g_btnX() + Math.floor((g_btnWidth() - _state.cvsW) / 2);
10925
10904
  const areaY = 130;
10926
10905
 
10927
10906
  const areaDiv = createEmptySprite(divRoot, C_PREVIEW_ID, {
10928
10907
  x: areaX, y: areaY - 60, w: _state.cvsW, h: _state.cvsH + 80,
10929
- pointerEvents: C_DIS_AUTO, background: `#00000080`,
10908
+ pointerEvents: C_DIS_AUTO, background: `#00000080`, display: C_DIS_NONE, overflow: `hidden`,
10930
10909
  });
10931
- areaDiv.style.display = `none`;
10932
- areaDiv.style.position = `absolute`;
10933
- areaDiv.style.overflow = `hidden`;
10934
10910
 
10935
10911
  const canvasBase = document.createElement(`canvas`);
10936
10912
  canvasBase.id = C_CANVAS_BASE_ID;
10937
- canvasBase.style.cssText = `position:absolute;left:0;top:0;`;
10938
10913
  areaDiv.appendChild(canvasBase);
10939
10914
  _state.canvasBase = canvasBase;
10940
10915
 
10941
10916
  const canvasMap = document.createElement(`canvas`);
10942
10917
  canvasMap.id = C_CANVAS_MAP_ID;
10943
- canvasMap.style.cssText = `position:absolute;left:0;top:0;`;
10944
10918
  areaDiv.appendChild(canvasMap);
10945
10919
  _state.canvasMap = canvasMap;
10946
10920
 
@@ -16147,12 +16121,11 @@ const resultInit = () => {
16147
16121
  for (let j = 0; j < 2; j++) {
16148
16122
  const canvas = document.createElement(`canvas`);
16149
16123
  canvas.id = `graphGaugeTransition${j > 0 ? j + 1 : ``}`;
16150
- const dpr = window.devicePixelRatio || 1;
16151
- canvas.width = g_limitObj.gaugeTransitionWidth * dpr;
16152
- canvas.height = g_limitObj.gaugeTransitionHeight * dpr;
16124
+ canvas.width = g_limitObj.gaugeTransitionWidth * g_dpr;
16125
+ canvas.height = g_limitObj.gaugeTransitionHeight * g_dpr;
16153
16126
  canvas.style.width = wUnit(g_limitObj.gaugeTransitionWidth);
16154
16127
  canvas.style.height = wUnit(g_limitObj.gaugeTransitionHeight);
16155
- canvas.getContext(`2d`).scale(dpr, dpr);
16128
+ canvas.getContext(`2d`).scale(g_dpr, g_dpr);
16156
16129
  canvas.style.left = wUnit(0);
16157
16130
  canvas.style.top = wUnit(0);
16158
16131
  canvas.style.position = `absolute`;
@@ -16463,13 +16436,12 @@ const resultInit = () => {
16463
16436
  tmpDiv.style.background = `#000000cc`;
16464
16437
  const canvas = document.createElement(`canvas`);
16465
16438
  const artistName = g_headerObj.artistNames[g_headerObj.musicNos[g_stateObj.scoreId]] || g_headerObj.artistName;
16466
- const dpr = window.devicePixelRatio || 1;
16467
16439
  const logicalWidth = 400;
16468
16440
  const logicalHeight = g_sHeight - 90;
16469
16441
 
16470
16442
  canvas.id = `resultImage`;
16471
- canvas.width = logicalWidth * dpr;
16472
- canvas.height = logicalHeight * dpr;
16443
+ canvas.width = logicalWidth * g_dpr;
16444
+ canvas.height = logicalHeight * g_dpr;
16473
16445
  canvas.style.width = wUnit(logicalWidth);
16474
16446
  canvas.style.height = wUnit(logicalHeight);
16475
16447
  canvas.style.left = wUnit((g_sWidth - parseFloat(canvas.style.width)) / 2);
@@ -16477,7 +16449,7 @@ const resultInit = () => {
16477
16449
  canvas.style.position = `absolute`;
16478
16450
 
16479
16451
  const context = canvas.getContext(`2d`);
16480
- context.scale(dpr, dpr);
16452
+ context.scale(g_dpr, g_dpr);
16481
16453
  const drawText = (_text, { x = 30, dy = 0, hy, siz = 15, color = `#cccccc`, align = C_ALIGN_LEFT, font } = {}) => {
16482
16454
  context.font = `${wUnit(siz)} ${getBasicFont(font)}`;
16483
16455
  context.fillStyle = color;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "47.6.1",
3
+ "version": "47.6.3",
4
4
  "description": "Dancing☆Onigiri (CW Edition) - Web-based Rhythm Game",
5
5
  "main": "./js/danoni_main.js",
6
6
  "jsdelivr": "./js/danoni_main.js",