danoniplus 47.1.1 → 47.2.0

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 +63 -23
  2. package/package.json +1 -1
package/js/danoni_main.js CHANGED
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 47.1.1`;
11
+ const g_version = `Ver 47.2.0`;
12
12
  const g_revisedDate = `2026/04/22`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
@@ -7837,18 +7837,40 @@ const makeHighScore = _scoreId => {
7837
7837
  }
7838
7838
  };
7839
7839
 
7840
- const drawMinimap = (_scoreId, _initFlg = false) => {
7840
+ /**
7841
+ * 譜面ミニマップを描画し、適切なスクロール位置へ調整する。
7842
+ * デフォルトはスクロール反転で、現在位置を保つように上下反転する。
7843
+ * @param {string} _scoreId - 描画対象の譜面ID
7844
+ * @param {object} [_options={}] - オプションパラメータ
7845
+ * @param {boolean} [_options._initFlg=false] - 譜面切替モード
7846
+ * - 前の譜面での演奏進行度(時間軸の比率)を算出し、新しい譜面でも同じ進行位置を表示する。
7847
+ * 位置記憶がない場合はフェードイン設定に基づく初期位置を表示。
7848
+ * @param {boolean} [_options._fadeinFlg=false] - フェードインモード。フェードイン設定値を優先して移動する。
7849
+ */
7850
+ const drawMinimap = (_scoreId, { _initFlg = false, _fadeinFlg = false } = {}) => {
7841
7851
  const detailMiniMap = document.getElementById(`detailMiniMap`);
7842
7852
  if (detailMiniMap === null) return; // scoreDetailUse=false 等で未生成の場合は何もしない
7843
7853
 
7844
- const currentScrollTop = document.getElementById(`detailMiniMapSub`)
7845
- ? document.getElementById(`detailMiniMapSub`).scrollTop : 0;
7854
+ const isRev = g_stateObj.miniMapRevFlg;
7855
+ const subEl = document.getElementById(`detailMiniMapSub`);
7856
+ const currentScrollTop = subEl ? subEl.scrollTop : 0;
7857
+
7858
+ // 前の譜面でスクロール可能な状態だったかを判定
7859
+ const hasPreviousScrollRange = subEl && subEl.scrollHeight > subEl.clientHeight;
7860
+
7861
+ // 前の譜面での「スクロール位置の比率」を計算
7862
+ // 完全に一番上のときは 0、一番下のときは 1 となる比率
7863
+ let progressRatio = 0;
7864
+ if (hasPreviousScrollRange) {
7865
+ const rawRatio = currentScrollTop / (subEl.scrollHeight - subEl.clientHeight);
7866
+ // リバース時は「上が終点」なので、進行度としては反転させる
7867
+ progressRatio = isRev ? (1.0 - rawRatio) : rawRatio;
7868
+ }
7846
7869
 
7847
7870
  // 再描画のため一度クリア
7848
7871
  deleteChildspriteAll(`detailMiniMap`);
7849
7872
 
7850
- // drawMinimap 内の Canvas 追加部分
7851
- const isRev = g_stateObj.miniMapRevFlg;
7873
+ // --- ミニマップ生成/取得 (Lazy Generation) ---
7852
7874
  let savedCanvases = isRev
7853
7875
  ? g_detailObj.scoreMinimapReverse[_scoreId]
7854
7876
  : g_detailObj.scoreMinimap[_scoreId];
@@ -7875,20 +7897,18 @@ const drawMinimap = (_scoreId, _initFlg = false) => {
7875
7897
  const detailMiniMapSub = createEmptySprite(detailMiniMap, `detailMiniMapSub`, g_windowObj.detailMiniMapSub);
7876
7898
  $id(`detailMiniMapSub`).top = (g_stateObj.miniMapRevFlg ? 0 : 15) + `px`;
7877
7899
 
7878
- detailMiniMapSub.style.overflowX = 'hidden';
7879
- detailMiniMapSub.style.overflowY = 'auto';
7880
- detailMiniMapSub.style.pointerEvents = 'auto';
7881
- detailMiniMapSub.style.display = 'block';
7882
- detailMiniMapSub.style.textAlign = 'left';
7900
+ Object.assign(detailMiniMapSub.style, {
7901
+ overflowX: 'hidden',
7902
+ overflowY: 'auto',
7903
+ pointerEvents: 'auto',
7904
+ display: 'block',
7905
+ textAlign: 'left',
7906
+ });
7883
7907
 
7884
7908
  if (savedCanvases && Array.isArray(savedCanvases)) {
7885
7909
  // 退避したCanvasそのものをDOMに追加(再描画不要で高速)
7886
- detailMiniMapSub.style.overflow = C_DIS_AUTO;
7887
- detailMiniMapSub.style.pointerEvents = C_DIS_AUTO;
7888
7910
  savedCanvases.forEach(canvas => {
7889
- canvas.style.position = 'static';
7890
- canvas.style.display = 'block';
7891
- canvas.style.height = 'auto';
7911
+ Object.assign(canvas.style, { position: 'static', display: 'block', height: 'auto' });
7892
7912
  detailMiniMapSub.appendChild(canvas);
7893
7913
  });
7894
7914
  }
@@ -7901,16 +7921,36 @@ const drawMinimap = (_scoreId, _initFlg = false) => {
7901
7921
  getStartFrame(lastFrame, g_stateObj.fadein, _scoreId) - firstArrowFrame
7902
7922
  ));
7903
7923
  const fadeinScrollTop = scrollHeight * fadeinFrameOffset / playingFrame;
7904
- detailMiniMapSub.scrollTop = g_stateObj.miniMapRevFlg
7905
- ? (_initFlg ? scrollHeight - currentScrollTop : scrollHeight - fadeinScrollTop)
7906
- : (_initFlg ? scrollHeight - currentScrollTop : fadeinScrollTop);
7924
+ const visualFadeinPos = isRev ? scrollHeight - fadeinScrollTop : fadeinScrollTop;
7925
+
7926
+ // --- スクロール位置の決定ロジック
7927
+ let targetScrollTop = 0;
7928
+
7929
+ if (_fadeinFlg) {
7930
+ // 【最優先】フェードイン操作時:設定値を強制適用
7931
+ targetScrollTop = visualFadeinPos;
7932
+ } else if (_initFlg) {
7933
+ // 【譜面切替時】
7934
+ if (hasPreviousScrollRange) {
7935
+ // 以前の進行度を継承
7936
+ const visualRatio = isRev ? (1.0 - progressRatio) : progressRatio;
7937
+ targetScrollTop = scrollHeight * visualRatio;
7938
+ } else {
7939
+ // 初回はフェードイン位置
7940
+ targetScrollTop = visualFadeinPos;
7941
+ }
7942
+ } else {
7943
+ // 【リバース切替時】物理反転
7944
+ targetScrollTop = scrollHeight - currentScrollTop;
7945
+ }
7946
+ detailMiniMapSub.scrollTop = targetScrollTop;
7907
7947
 
7908
7948
  if (document.getElementById(`lnkMiniMapRev`) === null) {
7909
7949
  scoreDetail.appendChild(
7910
7950
  makeDifLblCssButton(`lnkMiniMapRev`, g_lblNameObj.s_rev + `${g_stateObj.miniMapRevFlg ? `↑` : `↓`}`, 8, () => {
7911
7951
  g_stateObj.miniMapRevFlg = !g_stateObj.miniMapRevFlg;
7912
7952
  lnkMiniMapRev.textContent = g_lblNameObj.s_rev + `${g_stateObj.miniMapRevFlg ? `↑` : `↓`}`;
7913
- drawMinimap(g_stateObj.scoreId, true);
7953
+ drawMinimap(g_stateObj.scoreId);
7914
7954
  createScText(lnkMiniMapRev, `MiniMapRev`, { targetLabel: `lnkMiniMapRev`, x: -12 });
7915
7955
  }, g_lblPosObj.lnkMiniMapRev)
7916
7956
  );
@@ -8106,7 +8146,7 @@ const setDifficulty = (_initFlg) => {
8106
8146
  drawDensityGraph(g_stateObj.scoreId);
8107
8147
  makeDifInfo(g_stateObj.scoreId);
8108
8148
  makeHighScore(g_stateObj.scoreId);
8109
- drawMinimap(g_stateObj.scoreId);
8149
+ drawMinimap(g_stateObj.scoreId, { _initFlg: true });
8110
8150
  }
8111
8151
 
8112
8152
  // 楽曲データの表示
@@ -8404,7 +8444,7 @@ const createOptionWindow = _sprite => {
8404
8444
  fadeinSlider.value = g_stateObj.fadein;
8405
8445
  lnkFadein.textContent = `${g_stateObj.fadein}${g_lblNameObj.percent}`;
8406
8446
  updateSettingSummary();
8407
- drawMinimap(g_stateObj.scoreId);
8447
+ drawMinimap(g_stateObj.scoreId, { _fadeinFlg: true });
8408
8448
  };
8409
8449
 
8410
8450
  multiAppend(spriteList.fadein,
@@ -8423,7 +8463,7 @@ const createOptionWindow = _sprite => {
8423
8463
  fadeinSlider.addEventListener(`input`, () => {
8424
8464
  g_stateObj.fadein = inputSlider(fadeinSlider, lnkFadein, `fadein`);
8425
8465
  updateSettingSummary();
8426
- drawMinimap(g_stateObj.scoreId);
8466
+ drawMinimap(g_stateObj.scoreId, { _fadeinFlg: true });
8427
8467
  }, false);
8428
8468
 
8429
8469
  // ---------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "47.1.1",
3
+ "version": "47.2.0",
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",