danoniplus 48.3.0 → 48.4.1

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.
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/31
7
+ * Revised : 2026/06/05
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 48.3.0`;
12
- const g_revisedDate = `2026/05/31`;
11
+ const g_version = `Ver 48.4.1`;
12
+ const g_revisedDate = `2026/06/05`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -9171,7 +9171,7 @@ const openDisplayPreview = () => {
9171
9171
  // オーバーレイ本体
9172
9172
  // ============================================================
9173
9173
  const overlay = createEmptySprite(divRoot, `displayPreviewOverlay`, {
9174
- w: g_sWidth, h: g_sHeight, background: g_headerObj.baseBrightFlg ? `#eeeeeedd` : `#111111dd`, pointerEvents: C_DIS_AUTO,
9174
+ w: g_sWidth, h: g_sHeight, background: g_headerObj.baseBrightFlg ? `#eeeeeeee` : `#111111dd`, pointerEvents: C_DIS_AUTO,
9175
9175
  });
9176
9176
  g_previewRoot = overlay;
9177
9177
  multiAppend(overlay,
@@ -9209,7 +9209,7 @@ const openDisplayPreview = () => {
9209
9209
 
9210
9210
  const frame = createEmptySprite(overlay, `previewFrame`, {
9211
9211
  x: frameX, y: frameY, w: playW, h: playH,
9212
- background: `#111111`,
9212
+ background: g_headerObj.baseBrightFlg ? `#eeeeee` : `#111111`,
9213
9213
  border: `1px solid #444444`,
9214
9214
  boxSizing: `border-box`,
9215
9215
  transform: `scale(${rate})`,
@@ -9266,6 +9266,13 @@ const buildPreviewUI = (_frame, _playW, _playH) => {
9266
9266
  // ============================================================
9267
9267
  const stepY = g_posObj.stepY ?? C_STEP_Y;
9268
9268
  const revStepY = g_posObj.reverseStepY;
9269
+ const hitPos = g_stateObj.hitPosition ?? 0;
9270
+
9271
+ // 簡易ステップゾーン(7レーン分)
9272
+ const laneCount = 7;
9273
+ const laneW = 50;
9274
+ const totalW = laneCount * laneW;
9275
+ const startX = Math.round((_playW - totalW) / 2);
9269
9276
 
9270
9277
  if (d.stepzone === C_FLG_OFF) {
9271
9278
  multiAppend(_frame,
@@ -9273,12 +9280,6 @@ const buildPreviewUI = (_frame, _playW, _playH) => {
9273
9280
  disableBox(`StepZone_Rev`, { x: Math.round(_playW / 2 - 200), y: C_STEP_Y + revStepY, w: 400, h: 50 }),
9274
9281
  );
9275
9282
  } else {
9276
- // 簡易ステップゾーン(7レーン分)
9277
- const laneCount = 7;
9278
- const laneW = 50;
9279
- const totalW = laneCount * laneW;
9280
- const startX = Math.round((_playW - totalW) / 2);
9281
-
9282
9283
  for (let j = 0; j < laneCount; j++) {
9283
9284
  createEmptySprite(_frame, `previewStep${j}`, {
9284
9285
  x: startX + j * laneW + 2, y: stepY + 2, w: laneW - 4, h: laneW - 4,
@@ -9293,6 +9294,45 @@ const buildPreviewUI = (_frame, _playW, _playH) => {
9293
9294
  }
9294
9295
  }
9295
9296
 
9297
+ // ============================================================
9298
+ // HitPosition を視覚化する判定基準ライン
9299
+ // ============================================================
9300
+ // 通常譜面用の判定ライン(赤または目立つ色で、レーン幅全体をカバー)
9301
+ // 上から下に流れる場合、hitPosがプラスなら「ステップゾーンより下」にラインが来る
9302
+ const lineNormal = createEmptySprite(_frame, `previewHitPosLine`, {
9303
+ x: startX,
9304
+ y: stepY + Math.round(laneW / 2) + hitPos, // ステップゾーンの中心 + hitPos
9305
+ w: totalW,
9306
+ h: 2, // 2pxの横線
9307
+ background: `#33aaff`,
9308
+ boxShadow: `0 0 4px #33aaff`, // ネオンっぽく光らせて目立たせる
9309
+ });
9310
+
9311
+ // 青いラインの右端(totalW から10pxほど外側)に数値を表示
9312
+ multiAppend(
9313
+ lineNormal,
9314
+ createDivCss2Label(`previewHitPosTitle`, `Hit`, {
9315
+ ...g_lblPosObj.previewHitPosText, x: -60, y: -14, align: C_ALIGN_RIGHT,
9316
+ }),
9317
+ createDivCss2Label(`previewHitPosTitle2`, `Position`, {
9318
+ ...g_lblPosObj.previewHitPosText, x: -60, y: -2, align: C_ALIGN_RIGHT,
9319
+ }),
9320
+ createDivCss2Label(`previewHitPosText`, `${hitPos > 0 ? '+' : ''}${hitPos}px↑↓`, {
9321
+ ...g_lblPosObj.previewHitPosText, x: totalW + 5, y: -8, align: C_ALIGN_LEFT,
9322
+ }),
9323
+ );
9324
+
9325
+ // リバース譜面用の判定ライン
9326
+ // 下から上に流れる場合、hitPosがプラスなら「ステップゾーンより上(座標としてはマイナス)」に来る
9327
+ createEmptySprite(_frame, `previewHitPosLineRev`, {
9328
+ x: startX,
9329
+ y: (C_STEP_Y + revStepY) + Math.round(laneW / 2) - hitPos, // ステップゾーンの中心 - hitPos
9330
+ w: totalW,
9331
+ h: 2,
9332
+ background: `#ffaa00`,
9333
+ boxShadow: `0 0 4px #ffaa00`,
9334
+ });
9335
+
9296
9336
  // ============================================================
9297
9337
  // 判定エリア(ドラッグ可能)
9298
9338
  // ============================================================
@@ -9301,30 +9341,67 @@ const buildPreviewUI = (_frame, _playW, _playH) => {
9301
9341
  x: Math.round(_playW / 2 - 220), y: Math.round((_playH + (g_posObj?.stepYR ?? 0)) / 2 - 60), w: 440, h: 120,
9302
9342
  }));
9303
9343
  } else {
9304
- const jX0 = Math.round(_playW / 2 - 220) + (g_diffObj.arrowJdgX ?? 0);
9305
- const jY0 = Math.round((_playH + (g_posObj?.stepYR ?? 0)) / 2 - 60) + (g_diffObj.arrowJdgY ?? 0);
9306
- const fX0 = Math.round(_playW / 2 - 120) + (g_diffObj.frzJdgX ?? 0);
9307
- const fY0 = Math.round((_playH + (g_posObj?.stepYR ?? 0)) / 2 + 10) + (g_diffObj.frzJdgY ?? 0);
9308
-
9309
- const jdgInitX = g_previewPos.arrowJdg.x ?? jX0;
9310
- const jdgInitY = g_previewPos.arrowJdg.y ?? jY0;
9311
- const jdgFInitX = g_previewPos.frzJdg.x ?? fX0;
9312
- const jdgFInitY = g_previewPos.frzJdg.y ?? fY0;
9313
-
9314
- // 通常判定グループ
9315
- buildDraggableJudgGroup(_frame, `arrowJdg`, jdgInitX, jdgInitY, _playW, _playH, {
9316
- charaText: d.judgment === C_FLG_ON ? g_lblNameObj.j_ii : ``,
9317
- comboText: d.judgment === C_FLG_ON ? `5 Combo!!` : ``,
9318
- diffText: `Fast 3 Frames`,
9319
- charaColor: `#66ffff`,
9320
- });
9344
+ const opacity = g_stateObj.opacity / 100;
9345
+ const jdgCenterY = Math.round((_playH + (g_posObj?.stepYR ?? 0)) / 2);
9346
+ const groupW = 370;
9347
+ const groupH = 51;
9321
9348
 
9322
- // フリーズ判定グループ
9323
- buildDraggableJudgGroup(_frame, `frzJdg`, jdgFInitX, jdgFInitY, _playW, _playH, {
9324
- charaText: d.judgment === C_FLG_ON ? g_lblNameObj.j_kita : ``,
9325
- comboText: d.judgment === C_FLG_ON ? `5 Combo!!` : ``,
9326
- diffText: `Fast 2 Frames`,
9327
- charaColor: `#ffff99`,
9349
+ const jdgSettings = [
9350
+ {
9351
+ key: `arrowJdg`,
9352
+ stdYOffset: -60,
9353
+ offsetX: g_diffObj.arrowJdgX ?? 0,
9354
+ offsetY: g_diffObj.arrowJdgY ?? 0,
9355
+ chara: d.judgment === C_FLG_ON ? g_lblNameObj.j_ii : ``,
9356
+ css: [g_cssObj.common_ii, g_cssObj.common_kita], // [chara, combo]
9357
+ toast: g_lblNameObj.arrowJdgUpdate,
9358
+ },
9359
+ {
9360
+ key: `frzJdg`,
9361
+ stdYOffset: 10,
9362
+ offsetX: g_diffObj.frzJdgX ?? 0,
9363
+ offsetY: g_diffObj.frzJdgY ?? 0,
9364
+ chara: d.judgment === C_FLG_ON ? g_lblNameObj.j_kita : ``,
9365
+ css: [g_cssObj.common_kita, g_cssObj.common_ii],
9366
+ toast: g_lblNameObj.frzJdgUpdate,
9367
+ }
9368
+ ];
9369
+
9370
+ jdgSettings.forEach(item => {
9371
+
9372
+ const stdX = Math.round(_playW / 2 - (item.key === `arrowJdg` ? 220 : 120));
9373
+ const initX = g_previewPos[item.key].x ?? (stdX + item.offsetX);
9374
+ const initY = g_previewPos[item.key].y ?? (jdgCenterY + item.offsetY + item.stdYOffset);
9375
+
9376
+ // グループコンテナの生成
9377
+ const group = createEmptySprite(_frame, `previewGrp_${item.key}`, {
9378
+ x: initX, y: initY, w: groupW, h: groupH, pointerEvents: C_DIS_AUTO,
9379
+ });
9380
+
9381
+ // ラベル類の配置
9382
+ multiAppend(group,
9383
+ createDivCss2Label(`previewChara_${item.key}`, item.chara, {
9384
+ x: 0, y: 0, w: g_limitObj.jdgCharaWidth, h: g_limitObj.jdgCharaHeight,
9385
+ siz: g_limitObj.jdgCharaSiz, opacity,
9386
+ }, item.css[0]),
9387
+ createDivCss2Label(`previewCombo_${item.key}`, d.judgment === C_FLG_ON ? `5 Combo!!` : ``, {
9388
+ x: 170, y: 0, w: g_limitObj.jdgCharaWidth, h: g_limitObj.jdgCharaHeight,
9389
+ siz: g_limitObj.jdgCharaSiz, opacity,
9390
+ }, item.css[1]),
9391
+ createDivCss2Label(`previewDiff_${item.key}`, `Fast 3 Frames`, {
9392
+ x: 170, y: 25, w: g_limitObj.jdgCharaWidth, h: g_limitObj.jdgCharaHeight,
9393
+ siz: g_limitObj.mainSiz, color: `#ff9966`, opacity,
9394
+ }, g_cssObj.common_fast),
9395
+ );
9396
+
9397
+ // ドラッグ機能を付与
9398
+ makeElementDraggable(group, item.key, _playW, _playH, { w: groupW, h: groupH }, {
9399
+ toastTitle: item.toast,
9400
+ getStdPos: () => ({
9401
+ x: stdX,
9402
+ y: Math.round(jdgCenterY + item.stdYOffset),
9403
+ }),
9404
+ });
9328
9405
  });
9329
9406
  }
9330
9407
 
@@ -9335,9 +9412,9 @@ const buildPreviewUI = (_frame, _playW, _playH) => {
9335
9412
  _frame.appendChild(disableBox(`LifeGauge`, g_lblPosObj.previewLifeDisabled));
9336
9413
  } else {
9337
9414
  multiAppend(_frame,
9338
- createDivCss2Label(`previewLifeBack`, ``, g_lblPosObj.previewLifeBack),
9339
- createDivCss2Label(`previewLifeBar`, ``, g_lblPosObj.previewLifeBar),
9340
- createDivCss2Label(`previewLifeNum`, `700`, g_lblPosObj.previewLifeNum),
9415
+ createDivCss2Label(`previewLifeBack`, ``, g_lblPosObj.previewLifeBack, g_cssObj.life_Background),
9416
+ createDivCss2Label(`previewLifeBar`, ``, g_lblPosObj.previewLifeBar, g_cssObj.life_Cleared),
9417
+ createDivCss2Label(`previewLifeNum`, `700`, g_lblPosObj.previewLifeNum, g_cssObj.life_Cleared),
9341
9418
  );
9342
9419
  }
9343
9420
 
@@ -9352,31 +9429,31 @@ const buildPreviewUI = (_frame, _playW, _playH) => {
9352
9429
  }
9353
9430
  } else {
9354
9431
  const scoreItems = [
9355
- { color: `#66ffff`, cnt: `5` },
9356
- { color: `#99ff99`, cnt: `0` },
9357
- { color: `#ffcc66`, cnt: `0` },
9358
- { color: `#cc99ff`, cnt: `0` },
9359
- { color: `#ff9999`, cnt: `0` },
9360
- { color: `#ffffff`, cnt: `5` },
9432
+ { name: `ii`, cnt: `5` },
9433
+ { name: `shakin`, cnt: `0` },
9434
+ { name: `matari`, cnt: `0` },
9435
+ { name: `shobon`, cnt: `0` },
9436
+ { name: `uwan`, cnt: `0` },
9437
+ { name: `combo`, cnt: `5` },
9361
9438
  {},
9362
- { color: `#ffff99`, cnt: `5` },
9363
- { color: `#99ff66`, cnt: `0` },
9364
- { color: `#ffffff`, cnt: `5` },
9439
+ { name: `kita`, cnt: `5` },
9440
+ { name: `iknai`, cnt: `0` },
9441
+ { name: `combo`, cnt: `5` },
9365
9442
  ];
9366
9443
  const sx = _playW - 110 + g_headerObj.scAreaWidth;
9367
9444
  scoreItems.forEach((item, i) => {
9368
9445
  _frame.appendChild(
9369
9446
  createDivCss2Label(`previewScore${i}`, item.cnt || ``, {
9370
9447
  x: sx + 50, y: 20 * (i + 1), w: 50, h: 20,
9371
- siz: 16, color: item.color, align: `right`,
9372
- }),
9448
+ siz: 16, align: `right`,
9449
+ }, g_cssObj[`common_${item.name}`]),
9373
9450
  );
9374
9451
  });
9375
9452
 
9376
9453
  // FrzReturn用ゲージ
9377
9454
  if (g_stateObj.frzReturn !== C_FLG_OFF) {
9378
9455
  multiAppend(_frame,
9379
- createDivCss2Label(`previewFrzLifeBack`, ``, g_lblPosObj.previewFrzLifeBack),
9456
+ createDivCss2Label(`previewFrzLifeBack`, ``, g_lblPosObj.previewFrzLifeBack, g_cssObj.life_Background),
9380
9457
  createDivCss2Label(`previewFrzLifeBar`, ``, g_lblPosObj.previewFrzLifeBar, g_cssObj.life_frzNormal),
9381
9458
  );
9382
9459
  }
@@ -9427,8 +9504,10 @@ const buildPreviewUI = (_frame, _playW, _playH) => {
9427
9504
  );
9428
9505
  const scConfig = {
9429
9506
  toastTitle: g_lblNameObj.shortcutUpdate,
9430
- getStdX: (pw) => g_sWidth + g_headerObj.scAreaWidth - 85,
9431
- getStdY: (ph, syr) => _playH - 65,
9507
+ getStdPos: () => ({
9508
+ x: g_sWidth + g_headerObj.scAreaWidth - 85,
9509
+ y: _playH - 65
9510
+ }),
9432
9511
  };
9433
9512
  makeElementDraggable(scGroup, `shortcut`, _playW, _playH, { w: 80, h: 65 }, scConfig);
9434
9513
 
@@ -9436,6 +9515,41 @@ const buildPreviewUI = (_frame, _playW, _playH) => {
9436
9515
  safeExecuteCustomHooks(`g_customJsObj.displayPreview`, g_customJsObj.displayPreview, _frame, _playW, _playH);
9437
9516
  };
9438
9517
 
9518
+ /**
9519
+ * プレビューが表示されたまま、HitPositionのラインだけを動かす
9520
+ * @param {number} _newHitPos 新しい g_stateObj.hitPosition の値
9521
+ */
9522
+ const updatePreviewHitPositionLine = (_newHitPos) => {
9523
+
9524
+ // 表示用の文字列を作成(例: "+15px", "-8px", "0px")
9525
+ const sign = _newHitPos > 0 ? `+` : ``;
9526
+ const textValue = `${sign}${_newHitPos}px↑↓`;
9527
+
9528
+ // 1. 各種基準座標を再取得(buildPreviewUI 内の計算ロジックと同期)
9529
+ const stepY = g_posObj.stepY ?? C_STEP_Y;
9530
+ const revStepY = g_posObj.reverseStepY;
9531
+ const laneW = 50;
9532
+
9533
+ // 2. DOM要素を直接取得
9534
+ const lineNormal = document.getElementById(`previewHitPosLine`);
9535
+ const lineReverse = document.getElementById(`previewHitPosLineRev`);
9536
+ const textNormal = document.getElementById(`previewHitPosText`);
9537
+
9538
+ // 3. プレビューが表示されている場合のみ、style.top を直接書き換える
9539
+ if (lineNormal) {
9540
+ const newY = stepY + Math.round(laneW / 2) + _newHitPos;
9541
+ lineNormal.style.top = wUnit(newY);
9542
+ }
9543
+ if (textNormal) {
9544
+ textNormal.textContent = textValue;
9545
+ }
9546
+
9547
+ if (lineReverse) {
9548
+ const newY = (C_STEP_Y + revStepY) + Math.round(laneW / 2) - _newHitPos;
9549
+ lineReverse.style.top = wUnit(newY);
9550
+ }
9551
+ };
9552
+
9439
9553
  /**
9440
9554
  * 要素をドラッグ可能にする(汎用ユーティリティ)
9441
9555
  * @param {HTMLElement} _target ドラッグ対象の要素
@@ -9458,11 +9572,12 @@ const makeElementDraggable = (_target, _key, _playW, _playH, _bounds, _config) =
9458
9572
  const handleId = _target.id ? `handle_${_target.id}` : `dragHandle_${Math.random().toString(36).slice(2, 9)}`;
9459
9573
  _target.style.cursor = `grab`;
9460
9574
 
9575
+ const bgColor = g_headerObj.baseBrightFlg ? `0,0,0` : `255,255,255`;
9461
9576
  createEmptySprite(_target, handleId, {
9462
9577
  x: 0, y: 0, w: boundsW, h: boundsH,
9463
- border: `1px dashed rgba(255,255,255,0.3)`,
9578
+ border: `1px dashed rgba(${bgColor},0.3)`,
9464
9579
  boxSizing: `border-box`, borderRadius: `2px`,
9465
- background: `rgba(255,255,255,0.04)`,
9580
+ background: `rgba(${bgColor},0.04)`,
9466
9581
  });
9467
9582
 
9468
9583
  const keyDown = addPreviewListener(_target, `pointerdown`, _evt => {
@@ -9526,64 +9641,6 @@ const makeElementDraggable = (_target, _key, _playW, _playH, _bounds, _config) =
9526
9641
  _target.setAttribute(`lsnrkeyTE`, keyUp);
9527
9642
  };
9528
9643
 
9529
- /**
9530
- * ドラッグ可能な判定グループを生成する
9531
- * @param {HTMLElement} _parent 親要素
9532
- * @param {string} _groupId `arrowJdg` または `frzJdg`
9533
- * @param {number} _initX 初期X座標(frame相対)
9534
- * @param {number} _initY 初期Y座標(frame相対)
9535
- * @param {number} _playW プレイ幅
9536
- * @param {number} _playH プレイ高さ
9537
- * @param {object} _opts 表示テキスト・色オプション
9538
- */
9539
- const buildDraggableJudgGroup = (_parent, _groupId, _initX, _initY, _playW, _playH, _opts) => {
9540
- const groupW = 370;
9541
- const groupH = 51;
9542
-
9543
- const group = createEmptySprite(_parent, `previewGrp_${_groupId}`, {
9544
- x: _initX, y: _initY, w: groupW, h: groupH, pointerEvents: C_DIS_AUTO,
9545
- });
9546
-
9547
- // 内包要素の生成 (省略:元のコードの multiAppend 部分と同一)
9548
- multiAppend(
9549
- group,
9550
- // キャラクタ
9551
- createDivCss2Label(`previewChara_${_groupId}`, _opts.charaText, {
9552
- x: 0, y: 0, w: g_limitObj.jdgCharaWidth, h: g_limitObj.jdgCharaHeight,
9553
- siz: g_limitObj.jdgCharaSiz, color: _opts.charaColor,
9554
- }),
9555
- // コンボ
9556
- createDivCss2Label(`previewCombo_${_groupId}`, _opts.comboText, {
9557
- x: 170, y: 0, w: g_limitObj.jdgCharaWidth, h: g_limitObj.jdgCharaHeight,
9558
- siz: g_limitObj.jdgCharaSiz, color: `#ffffff`,
9559
- }),
9560
- // Fast/Slow
9561
- createDivCss2Label(`previewDiff_${_groupId}`, _opts.diffText, {
9562
- x: 170, y: 25, w: g_limitObj.jdgCharaWidth, h: g_limitObj.jdgCharaHeight,
9563
- siz: g_limitObj.mainSiz, color: `#ff9966`,
9564
- }),
9565
- );
9566
-
9567
- // ============================================================
9568
- // 判定グループ固有の「座標反映ルール」を定義
9569
- // ============================================================
9570
- const configMap = {
9571
- arrowJdg: {
9572
- toastTitle: g_lblNameObj.arrowJdgUpdate,
9573
- getStdX: (pw) => Math.round(pw / 2 - 220),
9574
- getStdY: (ph, syr) => Math.round((ph + syr) / 2 - 60),
9575
- },
9576
- frzJdg: {
9577
- toastTitle: g_lblNameObj.frzJdgUpdate,
9578
- getStdX: (pw) => Math.round(pw / 2 - 120),
9579
- getStdY: (ph, syr) => Math.round((ph + syr) / 2 + 10),
9580
- }
9581
- };
9582
-
9583
- // 汎用ドラッグ及びドラッグ枠作成、差分適用処理
9584
- makeElementDraggable(group, _groupId, _playW, _playH, { w: groupW, h: groupH }, configMap[_groupId]);
9585
- };
9586
-
9587
9644
  /**
9588
9645
  * ドラッグ結果の座標をゲーム本体の設定に汎用的に反映する
9589
9646
  * @param {number} _x 確定したframe相対X
@@ -9592,17 +9649,13 @@ const buildDraggableJudgGroup = (_parent, _groupId, _initX, _initY, _playW, _pla
9592
9649
  * @param {string} _key 保存用キー(g_diffObjのプロパティ名の接頭辞)
9593
9650
  */
9594
9651
  const applyElementPositionToGame = (_x, _y, _config, _key) => {
9595
- const playW = g_headerObj.playingWidth || g_sWidth;
9596
- const playH = g_headerObj.playingHeight || g_sHeight;
9597
- const stepYR = g_posObj?.stepYR ?? 0;
9598
9652
 
9599
9653
  // 1. 各要素固有の「標準座標(基準点)」を計算
9600
- const stdX = _config.getStdX(playW);
9601
- const stdY = _config.getStdY(playH, stepYR);
9654
+ const std = _config.getStdPos();
9602
9655
 
9603
9656
  // 2. オフセット(差分)を計算
9604
- const diffX = _x - stdX;
9605
- const diffY = _y - stdY;
9657
+ const diffX = _x - std.x;
9658
+ const diffY = _y - std.y;
9606
9659
 
9607
9660
  // 3. 指定された保存先にオフセットを格納
9608
9661
  g_diffObj[`${_key}X`] = diffX;
@@ -9739,7 +9792,7 @@ const createSettingsDisplayWindow = _sprite => {
9739
9792
 
9740
9793
  // ---------------------------------------------------
9741
9794
  // 矢印の見え方 (Appearance)
9742
- // 縦位置: 7.4
9795
+ // 縦位置: 5.8
9743
9796
  createGeneralSetting(spriteList.appearance, `appearance`, {
9744
9797
  addRFunc: () => dispAppearanceSlider(),
9745
9798
  });
@@ -9779,17 +9832,18 @@ const createSettingsDisplayWindow = _sprite => {
9779
9832
 
9780
9833
  // ---------------------------------------------------
9781
9834
  // 判定表示系の不透明度 (Opacity)
9782
- // 縦位置: 9
9835
+ // 縦位置: 7.4
9783
9836
  g_headerObj.opacityUse = g_headerObj.judgmentUse || g_headerObj.judgmentSet === C_FLG_ON;
9784
9837
 
9785
9838
  createGeneralSetting(spriteList.opacity, `opacity`, { unitName: g_lblNameObj.percent });
9786
9839
 
9787
9840
  // ---------------------------------------------------
9788
9841
  // タイミング調整 (HitPosition)
9789
- // 縦位置: 10
9842
+ // 縦位置: 8.4
9790
9843
  createGeneralSetting(spriteList.hitPosition, `hitPosition`, {
9791
9844
  skipTerms: g_settings.hitPositionTerms, scLabel: g_lblNameObj.sc_hitPosition, roundNum: 5,
9792
9845
  unitName: g_lblNameObj.pixel,
9846
+ addRFunc: () => updatePreviewHitPositionLine(g_stateObj.hitPosition),
9793
9847
  });
9794
9848
  };
9795
9849
 
@@ -11005,13 +11059,6 @@ const keyconfigKeyboardPreview = (() => {
11005
11059
  legendText: `#cccccc`, // 凡例テキスト
11006
11060
  };
11007
11061
 
11008
- // ボタン配置
11009
- // X・W は init() 内で動的計算(g_btnWidth() 依存)
11010
- // Y: KeyConfig テキスト上の余白に収まるよう小さく設定
11011
- const BTN_H = 18; // ボタン高さ
11012
- const BTN_Y = 3; // divRoot 内 Y 座標
11013
- const BTN_FS = 11; // ボタンのフォントサイズ(px)
11014
-
11015
11062
  // プレビューエリア
11016
11063
  // X: canvas を divRoot 内で水平センタリング(init で動的計算)
11017
11064
  // Y: g_sHeight に対して垂直センタリング(init で動的計算)
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2026/05/31 (v48.3.0)
8
+ * Revised : 2026/06/02 (v48.4.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -569,23 +569,25 @@ const updateWindowSiz = () => {
569
569
  },
570
570
  previewLifeBack: {
571
571
  x: 5, y: 50, w: 15, h: g_headerObj.playingHeight - 100,
572
- background: `#333333`, border: `1px solid #555555`,
573
572
  },
574
573
  previewLifeBar: {
575
574
  x: 5, y: 50 + (g_headerObj.playingHeight - 100) * 0.3,
576
- w: 15, h: (g_headerObj.playingHeight - 100) * 0.7, background: `#006666`,
575
+ w: 15, h: (g_headerObj.playingHeight - 100) * 0.7,
577
576
  },
578
577
  previewLifeNum: {
579
578
  x: 0, y: 30, w: 70, h: 20,
580
- siz: g_limitObj.jdgCntsSiz, color: `#ffffff`, background: `#006666`, align: C_ALIGN_CENTER,
579
+ siz: g_limitObj.jdgCntsSiz, align: C_ALIGN_CENTER,
581
580
  },
582
581
  previewFrzLifeBack: {
583
- x: 0, y: 50, w: 5, h: g_headerObj.playingHeight - 100,
584
- background: `#333333`, border: `1px solid #555555`,
582
+ x: 0, y: 50, w: 4, h: g_headerObj.playingHeight - 100,
585
583
  },
586
584
  previewFrzLifeBar: {
587
585
  x: 0, y: 50 + (g_headerObj.playingHeight - 100) * 0.7,
588
- w: 5, h: (g_headerObj.playingHeight - 100) * 0.3,
586
+ w: 4, h: (g_headerObj.playingHeight - 100) * 0.3,
587
+ },
588
+ previewHitPosText: {
589
+ w: 60, h: 16, siz: 14, color: `#33aaff`,
590
+ fontFamily: `monospace`, fontWeight: `bold`,
589
591
  },
590
592
 
591
593
  /** キーコンフィグ画面 */
@@ -3001,6 +3003,13 @@ const g_shortcutObj = {
3001
3003
  displayPreview: {
3002
3004
  KeyP: { id: `btnDisplayPreview2` },
3003
3005
  KeyR: { id: `btnDisplayReset` },
3006
+ ShiftLeft_ArrowDown: { id: `lnkHitPositionR` },
3007
+ ShiftRight_ArrowDown: { id: `lnkHitPositionR` },
3008
+ ArrowDown: { id: `lnkHitPositionRR` },
3009
+ ShiftLeft_ArrowUp: { id: `lnkHitPositionL` },
3010
+ ShiftRight_ArrowUp: { id: `lnkHitPositionL` },
3011
+ ArrowUp: { id: `lnkHitPositionLL` },
3012
+
3004
3013
  Escape: { id: `btnBack` },
3005
3014
  Space: { id: `btnKeyConfig` },
3006
3015
  Enter: { id: `btnPlay` },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "48.3.0",
3
+ "version": "48.4.1",
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",