danoniplus 50.5.0 → 50.5.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 +111 -16
- package/js/lib/keyconfig.js +35 -35
- package/js/lib/result.js +12 -30
- package/js/lib/settings.js +19 -44
- 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/09/
|
|
7
|
+
* Revised : 2026/09/15
|
|
8
8
|
*
|
|
9
9
|
* https://github.com/cwtickle/danoniplus
|
|
10
10
|
*/
|
|
11
|
-
const g_version = `Ver 50.5.
|
|
12
|
-
const g_revisedDate = `2026/09/
|
|
11
|
+
const g_version = `Ver 50.5.1`;
|
|
12
|
+
const g_revisedDate = `2026/09/15`;
|
|
13
13
|
|
|
14
14
|
// カスタム用バージョン (danoni_custom.js 等で指定可)
|
|
15
15
|
let g_localVersion = ``;
|
|
@@ -1986,6 +1986,34 @@ const getLoadingLabel = () => createDivCss2Label(`lblLoading`, g_lblNameObj.nowL
|
|
|
1986
1986
|
siz: g_limitObj.setLblSiz, align: C_ALIGN_RIGHT,
|
|
1987
1987
|
});
|
|
1988
1988
|
|
|
1989
|
+
/**
|
|
1990
|
+
* Canvasの作成 (拡張属性対応)
|
|
1991
|
+
* @param {string} _id
|
|
1992
|
+
* @param {number} [object.x=0]
|
|
1993
|
+
* @param {number} [object.y=0]
|
|
1994
|
+
* @param {number} [object.w]
|
|
1995
|
+
* @param {number} [object.h]
|
|
1996
|
+
* @param {string} [object.position='absolute']
|
|
1997
|
+
* @param {...any} [object.rest]
|
|
1998
|
+
* @returns {HTMLCanvasElement}
|
|
1999
|
+
*/
|
|
2000
|
+
const createCanvas = (_id, { x = 0, y = 0, w, h, position = `absolute`, ...rest } = {}) => {
|
|
2001
|
+
const cvs = document.createElement(`canvas`);
|
|
2002
|
+
if (_id) cvs.id = _id;
|
|
2003
|
+
cvs.style.display = `block`;
|
|
2004
|
+
|
|
2005
|
+
if (position) {
|
|
2006
|
+
cvs.style.position = position;
|
|
2007
|
+
cvs.style.left = wUnit(x);
|
|
2008
|
+
cvs.style.top = wUnit(y);
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
applyCanvasSize(cvs, w, h);
|
|
2012
|
+
Object.keys(rest).forEach(property => cvs.style[property] = rest[property]);
|
|
2013
|
+
|
|
2014
|
+
return cvs;
|
|
2015
|
+
};
|
|
2016
|
+
|
|
1989
2017
|
/**
|
|
1990
2018
|
* 指定された高さに基づいて分割されたCanvasリストを生成する
|
|
1991
2019
|
* @param {number} _width
|
|
@@ -2002,30 +2030,20 @@ const createSplitCanvases = (_width, _totalHeight) => {
|
|
|
2002
2030
|
if (_totalHeight <= 0) return [];
|
|
2003
2031
|
|
|
2004
2032
|
const count = Math.ceil(_totalHeight / maxLogicalHeight);
|
|
2033
|
+
const id = Math.random().toString(36).substring(2, 10); // ランダムなIDを生成
|
|
2005
2034
|
const list = [];
|
|
2006
2035
|
|
|
2007
2036
|
for (let i = 0; i < count; i++) {
|
|
2008
|
-
const cvs = document.createElement('canvas');
|
|
2009
2037
|
// 残りの高さを計算
|
|
2010
2038
|
const logicalH = (i === count - 1)
|
|
2011
2039
|
? _totalHeight - (maxLogicalHeight * i)
|
|
2012
2040
|
: maxLogicalHeight;
|
|
2013
2041
|
|
|
2014
|
-
|
|
2015
|
-
cvs.width = _width * g_dpr;
|
|
2016
|
-
cvs.height = logicalH * g_dpr;
|
|
2017
|
-
|
|
2018
|
-
// ブラウザ上の表示サイズをセット
|
|
2019
|
-
cvs.style.width = wUnit(_width);
|
|
2020
|
-
cvs.style.height = wUnit(logicalH);
|
|
2021
|
-
cvs.style.display = 'block';
|
|
2022
|
-
|
|
2023
|
-
const ctx = cvs.getContext('2d');
|
|
2024
|
-
ctx.scale(g_dpr, g_dpr);
|
|
2042
|
+
const cvs = createCanvas(`${id}_${i}`, { w: _width, h: logicalH, position: null });
|
|
2025
2043
|
|
|
2026
2044
|
list.push({
|
|
2027
2045
|
canvas: cvs,
|
|
2028
|
-
ctx:
|
|
2046
|
+
ctx: cvs.getContext(`2d`),
|
|
2029
2047
|
offsetTop: i * maxLogicalHeight,
|
|
2030
2048
|
logicalHeight: logicalH
|
|
2031
2049
|
});
|
|
@@ -2033,6 +2051,83 @@ const createSplitCanvases = (_width, _totalHeight) => {
|
|
|
2033
2051
|
return list;
|
|
2034
2052
|
};
|
|
2035
2053
|
|
|
2054
|
+
// ctxの任意プロパティのキャッシュ
|
|
2055
|
+
const g_ctxPropCache = {};
|
|
2056
|
+
|
|
2057
|
+
/**
|
|
2058
|
+
* ctxの任意プロパティをキャッシュ付きで設定(同一キーなら代入をスキップ)
|
|
2059
|
+
* @param {CanvasRenderingContext2D} _ctx
|
|
2060
|
+
* @param {string} _prop
|
|
2061
|
+
* @param {any} _key
|
|
2062
|
+
* @param {Function} _computeValue
|
|
2063
|
+
*/
|
|
2064
|
+
const setCtxProp = (_ctx, _prop, _key, _computeValue = () => _key) => {
|
|
2065
|
+
const cache = (g_ctxPropCache[_prop] ??= new WeakMap());
|
|
2066
|
+
if (cache.get(_ctx) !== _key) {
|
|
2067
|
+
_ctx[_prop] = _computeValue();
|
|
2068
|
+
cache.set(_ctx, _key);
|
|
2069
|
+
}
|
|
2070
|
+
};
|
|
2071
|
+
|
|
2072
|
+
/**
|
|
2073
|
+
* Canvasの実ピクセルサイズ・表示サイズを設定し、scale済みのcontextを返す
|
|
2074
|
+
* @param {HTMLCanvasElement} cvs
|
|
2075
|
+
* @param {number} w
|
|
2076
|
+
* @param {number} h
|
|
2077
|
+
* @returns {CanvasRenderingContext2D}
|
|
2078
|
+
*/
|
|
2079
|
+
const applyCanvasSize = (cvs, w, h) => {
|
|
2080
|
+
cvs.width = w * g_dpr;
|
|
2081
|
+
cvs.height = h * g_dpr;
|
|
2082
|
+
cvs.style.width = wUnit(w);
|
|
2083
|
+
cvs.style.height = wUnit(h);
|
|
2084
|
+
|
|
2085
|
+
const ctx = cvs.getContext(`2d`);
|
|
2086
|
+
// width/height代入によりctx状態がリセットされるため、setCtxPropのキャッシュも同期して破棄
|
|
2087
|
+
Object.values(g_ctxPropCache).forEach(cache => cache.delete(ctx));
|
|
2088
|
+
ctx.scale(g_dpr, g_dpr);
|
|
2089
|
+
return ctx;
|
|
2090
|
+
};
|
|
2091
|
+
|
|
2092
|
+
/**
|
|
2093
|
+
* 指定スタイルでテキストを描画する共通関数(font文字列は呼び出し側で完成させて渡す)
|
|
2094
|
+
* @param {CanvasRenderingContext2D} _ctx
|
|
2095
|
+
* @param {string} _text
|
|
2096
|
+
* @param {number} _x
|
|
2097
|
+
* @param {number} _y
|
|
2098
|
+
* @param {object} [object]
|
|
2099
|
+
* @param {string} [object.font]
|
|
2100
|
+
* @param {string} [object.color]
|
|
2101
|
+
* @param {string} [object.align=C_ALIGN_LEFT]
|
|
2102
|
+
* @param {string} [object.baseline]
|
|
2103
|
+
*/
|
|
2104
|
+
const fillCanvasTextRaw = (_ctx, _text, _x, _y, { font, color, align = C_ALIGN_LEFT, baseline } = {}) => {
|
|
2105
|
+
if (font !== undefined) setCtxProp(_ctx, `font`, font);
|
|
2106
|
+
if (color !== undefined) setCtxProp(_ctx, `fillStyle`, color);
|
|
2107
|
+
setCtxProp(_ctx, `textAlign`, align);
|
|
2108
|
+
setCtxProp(_ctx, `textBaseline`, baseline);
|
|
2109
|
+
_ctx.fillText(_text, _x, _y);
|
|
2110
|
+
};
|
|
2111
|
+
|
|
2112
|
+
/**
|
|
2113
|
+
* wUnit/getBasicFont前提のテキスト描画(既存呼び出し元向け)
|
|
2114
|
+
* @param {CanvasRenderingContext2D} _ctx
|
|
2115
|
+
* @param {string} _text
|
|
2116
|
+
* @param {number} _x
|
|
2117
|
+
* @param {number} _y
|
|
2118
|
+
* @param {object} [object]
|
|
2119
|
+
* @param {number} [object.siz=15]
|
|
2120
|
+
* @param {string} [object.font]
|
|
2121
|
+
* @param {string} [object.color]
|
|
2122
|
+
* @param {string} [object.align=C_ALIGN_LEFT]
|
|
2123
|
+
* @param {string} [object.baseline]
|
|
2124
|
+
*/
|
|
2125
|
+
const fillCanvasText = (_ctx, _text, _x, _y, { siz = 15, font, color, align = C_ALIGN_LEFT, baseline } = {}) =>
|
|
2126
|
+
fillCanvasTextRaw(_ctx, _text, _x, _y, {
|
|
2127
|
+
font: `${wUnit(siz)} ${getBasicFont(font)}`,
|
|
2128
|
+
color, align, baseline,
|
|
2129
|
+
});
|
|
2130
|
+
|
|
2036
2131
|
/**
|
|
2037
2132
|
* 画像表示
|
|
2038
2133
|
* @param {string} _id
|
package/js/lib/keyconfig.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2026/09/13
|
|
8
|
-
* Revised :
|
|
8
|
+
* Revised : 2026/09/15 (v50.5.1)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -1479,14 +1479,7 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1479
1479
|
const setupCanvasContext = (canvas) => {
|
|
1480
1480
|
if (!canvas) return null;
|
|
1481
1481
|
canvas.style.top = wUnit(40);
|
|
1482
|
-
canvas
|
|
1483
|
-
canvas.height = _state.cvsH * g_dpr;
|
|
1484
|
-
canvas.style.width = wUnit(_state.cvsW);
|
|
1485
|
-
canvas.style.height = wUnit(_state.cvsH);
|
|
1486
|
-
|
|
1487
|
-
const ctx = canvas.getContext(`2d`);
|
|
1488
|
-
ctx.scale(g_dpr, g_dpr);
|
|
1489
|
-
return ctx;
|
|
1482
|
+
return applyCanvasSize(canvas, _state.cvsW, _state.cvsH);
|
|
1490
1483
|
};
|
|
1491
1484
|
|
|
1492
1485
|
/**
|
|
@@ -1512,6 +1505,19 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1512
1505
|
ctx.closePath();
|
|
1513
1506
|
};
|
|
1514
1507
|
|
|
1508
|
+
// fill/strokeスタイルを設定して塗り・線を描く共通処理(roundRectなどと組み合わせて使う)
|
|
1509
|
+
const fillStrokeShape = (_ctx, { fill, stroke, lineWidth = 1 } = {}) => {
|
|
1510
|
+
if (fill !== undefined) {
|
|
1511
|
+
setCtxProp(_ctx, `fillStyle`, fill);
|
|
1512
|
+
_ctx.fill();
|
|
1513
|
+
}
|
|
1514
|
+
if (stroke !== undefined) {
|
|
1515
|
+
setCtxProp(_ctx, `strokeStyle`, stroke);
|
|
1516
|
+
setCtxProp(_ctx, `lineWidth`, lineWidth);
|
|
1517
|
+
_ctx.stroke();
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1520
|
+
|
|
1515
1521
|
/**
|
|
1516
1522
|
* 単一キーを描画する(枠の描画と内部テキストの書き込みを一括化)
|
|
1517
1523
|
* @param {CanvasRenderingContext2D} ctx
|
|
@@ -1524,11 +1530,7 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1524
1530
|
|
|
1525
1531
|
// 1. キーの枠線・背景を描画
|
|
1526
1532
|
roundRect(ctx, x + 0.5, y + 0.5, keyW - 1, keyH - 1, kr());
|
|
1527
|
-
ctx.
|
|
1528
|
-
ctx.strokeStyle = style.stroke;
|
|
1529
|
-
ctx.lineWidth = lw;
|
|
1530
|
-
ctx.fill();
|
|
1531
|
-
ctx.stroke();
|
|
1533
|
+
fillStrokeShape(ctx, { fill: style.fill, stroke: style.stroke, lineWidth: lw });
|
|
1532
1534
|
|
|
1533
1535
|
// 2. キー内部のテキスト(メイン・サブ)を描画
|
|
1534
1536
|
const [primary, sub] = getKeyLabels(code, label);
|
|
@@ -1539,28 +1541,27 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1539
1541
|
|
|
1540
1542
|
// サブラベル(Shift面などの表記)がある場合
|
|
1541
1543
|
if (sub) {
|
|
1542
|
-
ctx
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1544
|
+
fillCanvasTextRaw(ctx, sub, x + keyW - 2, y + 2, {
|
|
1545
|
+
font: `bold ${Math.max(6, Math.floor(9 * _state.scale))}px monospace`,
|
|
1546
|
+
color: style.subText || style.text,
|
|
1547
|
+
align: `right`, baseline: `top`,
|
|
1548
|
+
});
|
|
1547
1549
|
}
|
|
1548
1550
|
|
|
1549
1551
|
// メインラベルの描画(改行表記に対応)
|
|
1550
1552
|
const [primary1, primary2] = primary.split(`\n`);
|
|
1551
|
-
ctx.fillStyle = style.text;
|
|
1552
|
-
ctx.textAlign = `center`;
|
|
1553
|
-
ctx.textBaseline = `middle`;
|
|
1554
1553
|
const subDiff = sub ? 2 : 0;
|
|
1555
1554
|
|
|
1556
1555
|
if (primary2) {
|
|
1557
1556
|
const siz = fs(Math.max(primary1.length, primary2.length));
|
|
1558
|
-
|
|
1559
|
-
ctx
|
|
1560
|
-
ctx
|
|
1557
|
+
const opt = { font: `bold ${siz}px monospace`, color: style.text, align: `center`, baseline: `middle` };
|
|
1558
|
+
fillCanvasTextRaw(ctx, primary1, x + keyW / 2, y + keyH / 2 - siz / 2 + subDiff, opt);
|
|
1559
|
+
fillCanvasTextRaw(ctx, primary2, x + keyW / 2, y + keyH / 2 + siz / 2 + subDiff, opt);
|
|
1561
1560
|
} else {
|
|
1562
|
-
ctx
|
|
1563
|
-
|
|
1561
|
+
fillCanvasTextRaw(ctx, primary, x + keyW / 2, y + keyH / 2 + subDiff, {
|
|
1562
|
+
font: `bold ${fs(primary.length)}px monospace`,
|
|
1563
|
+
color: style.text, align: `center`, baseline: `middle`,
|
|
1564
|
+
});
|
|
1564
1565
|
}
|
|
1565
1566
|
};
|
|
1566
1567
|
|
|
@@ -1619,7 +1620,7 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1619
1620
|
if (!ctx) return;
|
|
1620
1621
|
|
|
1621
1622
|
ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
|
|
1622
|
-
ctx
|
|
1623
|
+
setCtxProp(ctx, `fillStyle`, C_COLOR.bgFill);
|
|
1623
1624
|
ctx.fillRect(0, 0, _state.cvsW, _state.cvsH);
|
|
1624
1625
|
|
|
1625
1626
|
_state.keyDataList = [];
|
|
@@ -1644,9 +1645,7 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1644
1645
|
|
|
1645
1646
|
// 凡例
|
|
1646
1647
|
const ly = _state.cvsH - 10;
|
|
1647
|
-
|
|
1648
|
-
ctx.textAlign = `left`;
|
|
1649
|
-
ctx.textBaseline = `middle`;
|
|
1648
|
+
const legendFont = `${Math.max(9, Math.floor(12 * _state.scale))}px ${getBasicFont()}`;
|
|
1650
1649
|
|
|
1651
1650
|
const legends = [
|
|
1652
1651
|
{ style: C_COLOR.normal, label: g_lblNameObj.unallocated },
|
|
@@ -1658,10 +1657,11 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1658
1657
|
let lx = 8;
|
|
1659
1658
|
legends.forEach(item => {
|
|
1660
1659
|
roundRect(ctx, lx, ly - 5, 10, 10, 2);
|
|
1661
|
-
ctx
|
|
1662
|
-
|
|
1663
|
-
ctx.
|
|
1664
|
-
|
|
1660
|
+
fillStrokeShape(ctx, { fill: item.style.fill, stroke: item.style.stroke, lineWidth: 1 });
|
|
1661
|
+
|
|
1662
|
+
fillCanvasTextRaw(ctx, item.label, lx + 14, ly, {
|
|
1663
|
+
font: legendFont, color: C_COLOR.legendText, align: `left`, baseline: `middle`,
|
|
1664
|
+
});
|
|
1665
1665
|
lx += ctx.measureText(item.label).width + 28;
|
|
1666
1666
|
});
|
|
1667
1667
|
};
|
package/js/lib/result.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2026/09/13
|
|
8
|
-
* Revised :
|
|
8
|
+
* Revised : 2026/09/15 (v50.5.1)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -263,20 +263,12 @@ const resultInit = () => {
|
|
|
263
263
|
// ゲージ推移グラフの描画
|
|
264
264
|
const gaugeTransitionWindow = createEmptySprite(divRoot, `gaugeTransitionWindow`, g_windowObj.gaugeTransition, g_cssObj.result_PlayDataWindow);
|
|
265
265
|
for (let j = 0; j < 2; j++) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
canvas.getContext(`2d`).scale(g_dpr, g_dpr);
|
|
273
|
-
canvas.style.left = wUnit(0);
|
|
274
|
-
canvas.style.top = wUnit(0);
|
|
275
|
-
canvas.style.position = `absolute`;
|
|
276
|
-
if (j > 0) {
|
|
277
|
-
canvas.style.pointerEvents = C_DIS_NONE;
|
|
278
|
-
}
|
|
279
|
-
gaugeTransitionWindow.appendChild(canvas);
|
|
266
|
+
gaugeTransitionWindow.appendChild(
|
|
267
|
+
createCanvas(`graphGaugeTransition${j > 0 ? j + 1 : ``}`, {
|
|
268
|
+
w: g_limitObj.gaugeTransitionWidth, h: g_limitObj.gaugeTransitionHeight,
|
|
269
|
+
pointerEvents: j > 0 ? C_DIS_NONE : C_DIS_AUTO,
|
|
270
|
+
})
|
|
271
|
+
);
|
|
280
272
|
}
|
|
281
273
|
|
|
282
274
|
multiAppend(divRoot,
|
|
@@ -578,28 +570,18 @@ const resultInit = () => {
|
|
|
578
570
|
const copyResultImageData = _msg => {
|
|
579
571
|
const tmpDiv = createEmptySprite(divRoot, `tmpDiv`, { x: 0, y: 0, w: g_sWidth, h: g_sHeight, pointerEvents: C_DIS_AUTO });
|
|
580
572
|
tmpDiv.style.background = `#000000cc`;
|
|
581
|
-
|
|
573
|
+
|
|
582
574
|
const artistName = g_headerObj.artistNames[g_headerObj.musicNos[g_stateObj.scoreId]] || g_headerObj.artistName;
|
|
583
575
|
const logicalWidth = 400;
|
|
584
576
|
const logicalHeight = g_sHeight - 90;
|
|
585
577
|
const flapWidth = 370;
|
|
586
578
|
|
|
587
|
-
canvas
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
canvas.style.width = wUnit(logicalWidth);
|
|
591
|
-
canvas.style.height = wUnit(logicalHeight);
|
|
592
|
-
canvas.style.left = wUnit((g_sWidth - parseFloat(canvas.style.width)) / 2);
|
|
593
|
-
canvas.style.top = wUnit(20);
|
|
594
|
-
canvas.style.position = `absolute`;
|
|
595
|
-
|
|
579
|
+
const canvas = createCanvas(`resultImage`, {
|
|
580
|
+
x: (g_sWidth - logicalWidth) / 2, y: 20, w: logicalWidth, h: logicalHeight
|
|
581
|
+
});
|
|
596
582
|
const context = canvas.getContext(`2d`);
|
|
597
|
-
context.scale(g_dpr, g_dpr);
|
|
598
583
|
const drawText = (_text, { x = 30, dy = 0, hy, siz = 15, color = `#cccccc`, align = C_ALIGN_LEFT, font } = {}) => {
|
|
599
|
-
context
|
|
600
|
-
context.fillStyle = color;
|
|
601
|
-
context.textAlign = align;
|
|
602
|
-
context.fillText(_text, x, 35 + hy * 18 + dy);
|
|
584
|
+
fillCanvasText(context, _text, x, 35 + hy * 18 + dy, { siz, font, color, align });
|
|
603
585
|
};
|
|
604
586
|
makeBgCanvas(context, { w: logicalWidth, h: logicalHeight });
|
|
605
587
|
|
package/js/lib/settings.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2026/09/13
|
|
8
|
-
* Revised :
|
|
8
|
+
* Revised : 2026/09/15 (v50.5.1)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -478,14 +478,14 @@ const drawSpeedGraph = _scoreId => {
|
|
|
478
478
|
context.moveTo(lineX[j], lineY);
|
|
479
479
|
context.lineTo(lineX[j] + 25, lineY);
|
|
480
480
|
context.stroke();
|
|
481
|
-
context
|
|
482
|
-
context.fillText(g_lblNameObj[`s_${speedType}`], lineX[j] + 30, lineY + 3);
|
|
481
|
+
fillCanvasText(context, g_lblNameObj[`s_${speedType}`], lineX[j] + 30, lineY + 3, { siz: g_limitObj.mainSiz });
|
|
483
482
|
|
|
484
483
|
const maxSpeed = Math.max(...speed);
|
|
485
484
|
const minSpeed = Math.min(...speed);
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
context
|
|
485
|
+
const speedText = `(${minSpeed.toFixed(2)}x` + (minSpeed === maxSpeed ? `` : ` -- ${Math.max(...speed).toFixed(2)}x`) + `)`;
|
|
486
|
+
const avgText = `Avg. ` + (avgX[j] === 1 ? `----` : `${(avgSubX[j]).toFixed(2)}x`);
|
|
487
|
+
fillCanvasText(context, speedText, lineX[j] + 30, lineY + 16, { siz: g_limitObj.graphMiniSiz });
|
|
488
|
+
fillCanvasText(context, avgText, lineX[j] + 30, lineY + 29, { siz: g_limitObj.graphMiniSiz });
|
|
489
489
|
updateScoreDetailLabel(`Speed`, `${speedType}S`, speedObj[speedType].cnt, j, g_lblNameObj[`s_${speedType}`]);
|
|
490
490
|
});
|
|
491
491
|
updateScoreDetailLabel(`Speed`, `avgS`, `${(avgX[0] * avgX[1]).toFixed(2)}x`, 2, g_lblNameObj.s_avg);
|
|
@@ -599,13 +599,11 @@ const drawDensityGraph = _scoreId => {
|
|
|
599
599
|
|
|
600
600
|
context.beginPath();
|
|
601
601
|
context.lineWidth = 3;
|
|
602
|
-
context.fillStyle = g_rankObj.rankColorAllPerfect;
|
|
603
602
|
context.strokeStyle = g_graphColorObj[val];
|
|
604
603
|
context.moveTo(lineX, 215);
|
|
605
604
|
context.lineTo(lineX + 20, 215);
|
|
606
605
|
context.stroke();
|
|
607
|
-
context
|
|
608
|
-
context.fillText(lineNames[j], lineX + 20, 218);
|
|
606
|
+
fillCanvasText(context, lineNames[j], lineX + 20, 218, { siz: g_limitObj.difSelectorSiz, color: g_rankObj.rankColorAllPerfect });
|
|
609
607
|
});
|
|
610
608
|
|
|
611
609
|
const obj = getScoreBaseData(_scoreId);
|
|
@@ -684,9 +682,7 @@ const drawLine = (_context, _y, _lineType, { _fixed, _mark, _a, _b } = {}) => {
|
|
|
684
682
|
const textBaseObj = document.getElementById(`lnkDifficulty`);
|
|
685
683
|
const textColor = window.getComputedStyle(textBaseObj, ``).color;
|
|
686
684
|
_context.strokeStyle = textColor;
|
|
687
|
-
_context.
|
|
688
|
-
_context.fillStyle = textColor;
|
|
689
|
-
_context.fillText(_y.toFixed(_fixed) + _mark, 2, lineY + 4);
|
|
685
|
+
fillCanvasText(_context, _y.toFixed(_fixed) + _mark, 2, lineY + 4, { siz: 12, color: textColor });
|
|
690
686
|
} else {
|
|
691
687
|
_context.strokeStyle = `#646464`;
|
|
692
688
|
}
|
|
@@ -1100,31 +1096,17 @@ const createMinimapHeader = (_config, _keyCtrlPtn, _keyNum) => {
|
|
|
1100
1096
|
const { timeMargin, laneWidth, logicalWidth } = _config;
|
|
1101
1097
|
const headerHeight = 15; // ヘッダーの固定高
|
|
1102
1098
|
|
|
1103
|
-
const canvas =
|
|
1099
|
+
const canvas = createCanvas(null, { w: logicalWidth, h: headerHeight, position: null });
|
|
1104
1100
|
const ctx = canvas.getContext('2d');
|
|
1105
1101
|
|
|
1106
|
-
// 解像度と表示サイズの設定
|
|
1107
|
-
canvas.width = logicalWidth * g_dpr;
|
|
1108
|
-
canvas.height = headerHeight * g_dpr;
|
|
1109
|
-
canvas.style.width = wUnit(logicalWidth);
|
|
1110
|
-
canvas.style.height = wUnit(headerHeight);
|
|
1111
|
-
canvas.style.display = 'block';
|
|
1112
|
-
|
|
1113
|
-
ctx.scale(g_dpr, g_dpr);
|
|
1114
|
-
|
|
1115
|
-
// テキストのスタイル設定
|
|
1116
|
-
ctx.fillStyle = '#999';
|
|
1117
|
-
ctx.font = `10px ${getBasicFont()}`;
|
|
1118
|
-
ctx.textAlign = 'center';
|
|
1119
|
-
ctx.textBaseline = 'middle';
|
|
1120
|
-
|
|
1121
1102
|
// 各レーンのキー名を描画
|
|
1122
1103
|
for (let j = 0; j < _keyNum; j++) {
|
|
1123
1104
|
// config.laneWidth を使って中央座標を計算
|
|
1124
1105
|
const x = timeMargin + j * laneWidth + laneWidth / 2;
|
|
1125
1106
|
const keyText = g_kCd[g_keyObj[`keyCtrl${_keyCtrlPtn}`][j][0]].split(` `).join(``);
|
|
1126
1107
|
|
|
1127
|
-
|
|
1108
|
+
// 視覚的な中央調整で +2px
|
|
1109
|
+
fillCanvasText(ctx, keyText, x, headerHeight / 2 + 2, { siz: 10, color: '#999', align: C_ALIGN_CENTER, baseline: `middle` });
|
|
1128
1110
|
}
|
|
1129
1111
|
|
|
1130
1112
|
return canvas;
|
|
@@ -1231,6 +1213,8 @@ const generateMinimapData = (_params, _isReverse) => {
|
|
|
1231
1213
|
* @param {number} _h
|
|
1232
1214
|
* @param {number} _dpr
|
|
1233
1215
|
* @param {Function} _drawFunc
|
|
1216
|
+
* - 描画関数。前後に ctx.save() / ctx.restore() が自動で呼ばれるためctxキャッシュを使った関数
|
|
1217
|
+
* (setCtxProp, fillCanvasText, fillCanvasRect など) は使用できない
|
|
1234
1218
|
*/
|
|
1235
1219
|
const distributeDrawing = (_canvases, _y, _h, _dpr, _drawFunc) => {
|
|
1236
1220
|
_canvases.forEach(item => {
|
|
@@ -1666,23 +1650,14 @@ const createOptionWindow = _sprite => {
|
|
|
1666
1650
|
|
|
1667
1651
|
if (_graphUseFlg) {
|
|
1668
1652
|
for (let j = 0; j < _graphNum; j++) {
|
|
1669
|
-
const graphObj = document.createElement(`canvas`);
|
|
1670
1653
|
const textBaseObj = document.getElementById(`lnkDifficulty`);
|
|
1671
1654
|
const bkColor = window.getComputedStyle(textBaseObj, ``).backgroundColor;
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
graphObj.style.left = wUnit(125);
|
|
1679
|
-
graphObj.style.top = wUnit(0);
|
|
1680
|
-
graphObj.style.position = `absolute`;
|
|
1681
|
-
graphObj.style.background = j === 0 ? bkColor : `#ffffff00`;
|
|
1682
|
-
const ctx = graphObj.getContext(`2d`);
|
|
1683
|
-
ctx.scale(g_dpr, g_dpr);
|
|
1684
|
-
|
|
1685
|
-
detailObj.appendChild(graphObj);
|
|
1655
|
+
detailObj.appendChild(
|
|
1656
|
+
createCanvas(`graph${_name}${j > 0 ? j + 1 : ``}`, {
|
|
1657
|
+
x: 125, y: 0, w: g_limitObj.graphWidth, h: g_limitObj.graphHeight,
|
|
1658
|
+
background: j === 0 ? bkColor : `#ffffff00`,
|
|
1659
|
+
})
|
|
1660
|
+
);
|
|
1686
1661
|
}
|
|
1687
1662
|
}
|
|
1688
1663
|
|