danoniplus 47.2.0 → 47.3.2

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/04/22
7
+ * Revised : 2026/04/25
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 47.2.0`;
12
- const g_revisedDate = `2026/04/22`;
11
+ const g_version = `Ver 47.3.2`;
12
+ const g_revisedDate = `2026/04/25`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -3451,7 +3451,11 @@ const createSplitCanvases = (_width, _totalHeight, _dpr) => {
3451
3451
 
3452
3452
  /**
3453
3453
  * 描画対象のCanvasを判定して描画を実行する
3454
- * @param {HTMLCanvasElement[]} _canvases
3454
+ * @param {object[]} _canvases
3455
+ * @param {HTMLCanvasElement} _canvases[].canvas 分割されたCanvas要素
3456
+ * @param {CanvasRenderingContext2D} _canvases[].ctx Canvasの描画コンテキスト
3457
+ * @param {number} _canvases[].offsetTop Canvasの論理上のオフセット位置
3458
+ * @param {number} _canvases[].logicalHeight Canvasの論理上の高さ
3455
3459
  * @param {number} _y
3456
3460
  * @param {number} _h
3457
3461
  * @param {number} _dpr
@@ -7286,6 +7290,7 @@ const drawSpeedGraph = _scoreId => {
7286
7290
  speed: { frame: [0], speed: [1], cnt: 0, strokeColor: g_graphColorObj.speed },
7287
7291
  boost: { frame: [0], speed: [1], cnt: 0, strokeColor: g_graphColorObj.boost }
7288
7292
  };
7293
+ const dpr = window.devicePixelRatio || 1;
7289
7294
 
7290
7295
  const tmpSpeedPoint = [0];
7291
7296
  Object.keys(speedObj).forEach(speedType => {
@@ -7890,7 +7895,7 @@ const drawMinimap = (_scoreId, { _initFlg = false, _fadeinFlg = false } = {}) =>
7890
7895
 
7891
7896
  // --- ヘッダー部分 ---
7892
7897
  const detailMiniMapHeader = createEmptySprite(detailMiniMap, `detailMiniMapHeader`, g_windowObj.detailMiniMapHeader);
7893
- $id(`detailMiniMapHeader`).top = (g_stateObj.miniMapRevFlg ? 230 : 0) + `px`;
7898
+ $id(`detailMiniMapHeader`).top = (g_stateObj.miniMapRevFlg ? 230 + g_sHeight - 500 : 0) + `px`;
7894
7899
  detailMiniMapHeader.appendChild(g_detailObj.scoreMinimapHeader[_scoreId]);
7895
7900
 
7896
7901
  // --- メイン(譜面)部分 ---
@@ -8229,13 +8234,18 @@ const createOptionWindow = _sprite => {
8229
8234
  const bkColor = window.getComputedStyle(textBaseObj, ``).backgroundColor;
8230
8235
 
8231
8236
  graphObj.id = `graph${_name}${j > 0 ? j + 1 : ``}`;
8232
- graphObj.width = g_limitObj.graphWidth;
8233
- graphObj.height = g_limitObj.graphHeight;
8237
+ const dpr = window.devicePixelRatio || 1;
8238
+ graphObj.width = g_limitObj.graphWidth * dpr;
8239
+ graphObj.height = g_limitObj.graphHeight * dpr;
8240
+ graphObj.style.width = wUnit(g_limitObj.graphWidth);
8241
+ graphObj.style.height = wUnit(g_limitObj.graphHeight);
8234
8242
  graphObj.style.left = wUnit(125);
8235
8243
  graphObj.style.top = wUnit(0);
8236
8244
  graphObj.style.position = `absolute`;
8237
8245
  graphObj.style.background = j === 0 ? bkColor : `#ffffff00`;
8238
8246
  graphObj.style.border = `dotted ${wUnit(2)}`;
8247
+ const ctx = graphObj.getContext(`2d`);
8248
+ ctx.scale(dpr, dpr);
8239
8249
 
8240
8250
  detailObj.appendChild(graphObj);
8241
8251
  }
@@ -11848,6 +11858,7 @@ const pushArrows = (_dataObj, _speedOnFrame, _firstArrivalFrame) => {
11848
11858
  g_workObj.arrivalFrame[frmPrev] = tmpObj.arrivalFrm;
11849
11859
  g_workObj.motionFrame[frmPrev] = tmpObj.motionFrm;
11850
11860
  g_workObj.initBoostY[frmPrev] = calcInitBoostY(frmPrev);
11861
+ let minNotesFrame = startPoint[lastk];
11851
11862
 
11852
11863
  if (_frzFlg) {
11853
11864
  g_workObj[`mk${camelHeader}Length`][_j] = [];
@@ -11896,6 +11907,41 @@ const pushArrows = (_dataObj, _speedOnFrame, _firstArrivalFrame) => {
11896
11907
  g_workObj.initBoostY[frmPrev] = calcInitBoostY(frmPrev);
11897
11908
  }
11898
11909
 
11910
+ // --- 逆転検知ロジック ---
11911
+ // 後ろからループしているため、minNotesFrameには「自分より譜面上後ろにあるノーツ」の
11912
+ // 最小生成フレーム(最も早く出現するもの)が入っている。
11913
+
11914
+ // 「自分より後ろのノーツ」の方が、「自分」よりも早く出現する場合、
11915
+ // 配列の順序と出現時間の順序が入れ替わっている(逆転)とみなす。
11916
+ // 逆転している場合は、最小生成フレームまでさらに遡って、出現フレームを再計算する。
11917
+ if (minNotesFrame < startPoint[k]) {
11918
+
11919
+ const getAdjArrowStartFrame = (_obj, _speedOnFrame, _targetFrame) => {
11920
+ while (_obj.frm > _targetFrame) {
11921
+ _obj.startY += _speedOnFrame[_obj.frm - 1];
11922
+
11923
+ if (_speedOnFrame[_obj.frm - 1] !== 0) {
11924
+ _obj.motionFrm++;
11925
+ }
11926
+ _obj.frm--;
11927
+ _obj.arrivalFrm++;
11928
+ }
11929
+ return _obj;
11930
+ };
11931
+ tmpObj = getAdjArrowStartFrame(tmpObj, _speedOnFrame, minNotesFrame);
11932
+ startPoint[k] = tmpObj.frm;
11933
+ frmPrev = tmpObj.frm;
11934
+ g_workObj.initY[frmPrev] = tmpObj.startY;
11935
+ g_workObj.arrivalFrame[frmPrev] = tmpObj.arrivalFrm;
11936
+ g_workObj.motionFrame[frmPrev] = tmpObj.motionFrm;
11937
+ g_workObj.initBoostY[frmPrev] = calcInitBoostY(frmPrev);
11938
+ }
11939
+
11940
+ // 最小値を更新
11941
+ if (startPoint[k] < minNotesFrame) {
11942
+ minNotesFrame = startPoint[k];
11943
+ }
11944
+
11899
11945
  // 出現タイミングを保存
11900
11946
  setNotes(_j, k, _data, startPoint[k], camelHeader, _frzFlg,
11901
11947
  { initY: tmpObj.startY, initBoostY: g_workObj.initBoostY[frmPrev], arrivalFrame: tmpObj.arrivalFrm, motionFrame: tmpObj.motionFrm }
@@ -15422,8 +15468,12 @@ const resultInit = () => {
15422
15468
  for (let j = 0; j < 2; j++) {
15423
15469
  const canvas = document.createElement(`canvas`);
15424
15470
  canvas.id = `graphGaugeTransition${j > 0 ? j + 1 : ``}`;
15425
- canvas.width = g_limitObj.gaugeTransitionWidth;
15426
- canvas.height = g_limitObj.gaugeTransitionHeight;
15471
+ const dpr = window.devicePixelRatio || 1;
15472
+ canvas.width = g_limitObj.gaugeTransitionWidth * dpr;
15473
+ canvas.height = g_limitObj.gaugeTransitionHeight * dpr;
15474
+ canvas.style.width = wUnit(g_limitObj.gaugeTransitionWidth);
15475
+ canvas.style.height = wUnit(g_limitObj.gaugeTransitionHeight);
15476
+ canvas.getContext(`2d`).scale(dpr, dpr);
15427
15477
  canvas.style.left = wUnit(0);
15428
15478
  canvas.style.top = wUnit(0);
15429
15479
  canvas.style.position = `absolute`;
@@ -15550,13 +15600,14 @@ const resultInit = () => {
15550
15600
 
15551
15601
  const canvas = document.getElementById(`graphGaugeTransition2`);
15552
15602
  const ctx = canvas.getContext(`2d`);
15553
- const x = cursorFrame / playingFrame * canvas.width;
15554
- ctx.clearRect(0, 0, canvas.width, canvas.height);
15603
+ const [w, h] = [parseInt(canvas.style.width), parseInt(canvas.style.height)];
15604
+ const x = cursorFrame / playingFrame * w;
15605
+ ctx.clearRect(0, 0, w, h);
15555
15606
 
15556
15607
  // 縦線
15557
15608
  ctx.beginPath();
15558
15609
  ctx.moveTo(x, 0);
15559
- ctx.lineTo(x, canvas.height);
15610
+ ctx.lineTo(x, h);
15560
15611
  ctx.strokeStyle = "#009999";
15561
15612
  ctx.lineWidth = 1.5;
15562
15613
  ctx.stroke();
@@ -15565,10 +15616,10 @@ const resultInit = () => {
15565
15616
  const timer = transFrameToTimer(cursorFrame + startFrame);
15566
15617
  ctx.font = `14px ${getBasicFont()}`;
15567
15618
  ctx.fillStyle = "#009999";
15568
- ctx.textAlign = x > canvas.width * 0.8 ? C_ALIGN_RIGHT : C_ALIGN_LEFT;
15619
+ ctx.textAlign = x > w * 0.8 ? C_ALIGN_RIGHT : C_ALIGN_LEFT;
15569
15620
  ctx.fillText(
15570
15621
  `${timer}`,
15571
- x > canvas.width * 0.8 ? x - 5 : x + 5,
15622
+ x > w * 0.8 ? x - 5 : x + 5,
15572
15623
  g_limitObj.gaugeTransitionHeight - 35
15573
15624
  );
15574
15625
  };
@@ -15733,22 +15784,28 @@ const resultInit = () => {
15733
15784
  tmpDiv.style.background = `#000000cc`;
15734
15785
  const canvas = document.createElement(`canvas`);
15735
15786
  const artistName = g_headerObj.artistNames[g_headerObj.musicNos[g_stateObj.scoreId]] || g_headerObj.artistName;
15787
+ const dpr = window.devicePixelRatio || 1;
15788
+ const logicalWidth = 400;
15789
+ const logicalHeight = g_sHeight - 90;
15736
15790
 
15737
15791
  canvas.id = `resultImage`;
15738
- canvas.width = 400;
15739
- canvas.height = g_sHeight - 90;
15740
- canvas.style.left = wUnit((g_sWidth - canvas.width) / 2);
15792
+ canvas.width = logicalWidth * dpr;
15793
+ canvas.height = logicalHeight * dpr;
15794
+ canvas.style.width = wUnit(logicalWidth);
15795
+ canvas.style.height = wUnit(logicalHeight);
15796
+ canvas.style.left = wUnit((g_sWidth - parseFloat(canvas.style.width)) / 2);
15741
15797
  canvas.style.top = wUnit(20);
15742
15798
  canvas.style.position = `absolute`;
15743
15799
 
15744
15800
  const context = canvas.getContext(`2d`);
15801
+ context.scale(dpr, dpr);
15745
15802
  const drawText = (_text, { x = 30, dy = 0, hy, siz = 15, color = `#cccccc`, align = C_ALIGN_LEFT, font } = {}) => {
15746
15803
  context.font = `${wUnit(siz)} ${getBasicFont(font)}`;
15747
15804
  context.fillStyle = color;
15748
15805
  context.textAlign = align;
15749
15806
  context.fillText(_text, x, 35 + hy * 18 + dy);
15750
15807
  };
15751
- makeBgCanvas(context, { h: canvas.height });
15808
+ makeBgCanvas(context, { w: logicalWidth, h: logicalHeight });
15752
15809
 
15753
15810
  drawText(`R`, { dy: -5, hy: 0, siz: 40, color: `#9999ff` });
15754
15811
  drawText(`ESULT`, { x: 57, dy: -5, hy: 0, siz: 25 });
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2026/04/21 (v47.1.0)
8
+ * Revised : 2026/04/25 (v47.3.2)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -212,9 +212,9 @@ const updateWindowSiz = () => {
212
212
  difCover: { x: 20, y: 60, w: 145, h: 270 + g_sHeight - 500, opacity: 0.95, pointerEvents: C_DIS_AUTO },
213
213
  difFilter: { x: 0, y: 66, w: 140, h: 204 + g_sHeight - 500, overflow: C_DIS_AUTO, pointerEvents: C_DIS_AUTO },
214
214
  displaySprite: { x: 25, y: 30, w: (g_sWidth - 450) / 2, h: g_limitObj.setLblHeight * 5 },
215
- scoreDetail: { x: 20, y: 85, w: (g_sWidth - 500) / 2 + 420, h: 245, visibility: `hidden`, pointerEvents: C_DIS_AUTO },
215
+ scoreDetail: { x: 20, y: 85, w: (g_sWidth - 500) / 2 + 420, h: 245 + g_sHeight - 500, visibility: `hidden`, pointerEvents: C_DIS_AUTO },
216
216
  detailMiniMapHeader: { x: 110, y: 0, w: (g_sWidth - 500) / 2 + 310, h: 15 },
217
- detailMiniMapSub: { x: 110, y: 15, w: (g_sWidth - 500) / 2 + 310, h: 230, overflow: C_DIS_AUTO, pointerEvents: C_DIS_AUTO },
217
+ detailMiniMapSub: { x: 110, y: 15, w: (g_sWidth - 500) / 2 + 310, h: 230 + g_sHeight - 500, overflow: C_DIS_AUTO, pointerEvents: C_DIS_AUTO },
218
218
  detailObj: { w: (g_sWidth - 500) / 2 + 420, h: 230, visibility: `hidden` },
219
219
  keyconSprite: { y: 105, h: g_sHeight - 105, overflow: C_DIS_AUTO },
220
220
  loader: { y: g_sHeight - 10, h: 10, backgroundColor: `#333333` },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "47.2.0",
3
+ "version": "47.3.2",
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",