danoniplus 47.6.1 → 47.6.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 +53 -52
- 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/
|
|
7
|
+
* Revised : 2026/05/14
|
|
8
8
|
*
|
|
9
9
|
* https://github.com/cwtickle/danoniplus
|
|
10
10
|
*/
|
|
11
|
-
const g_version = `Ver 47.6.
|
|
12
|
-
const g_revisedDate = `2026/05/
|
|
11
|
+
const g_version = `Ver 47.6.2`;
|
|
12
|
+
const g_revisedDate = `2026/05/14`;
|
|
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 *
|
|
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
|
|
3408
|
+
const createSplitCanvases = (_width, _totalHeight) => {
|
|
3410
3409
|
// バックバッファ(実際のピクセル数)の最大値を 8000 に設定(iOS Safari 8192px 対策)
|
|
3411
3410
|
const BACKING_STORE_LIMIT = 8000;
|
|
3412
3411
|
|
|
3413
3412
|
// 論理上の最大高さ(CSSピクセル)を計算
|
|
3414
|
-
//
|
|
3415
|
-
const maxLogicalHeight = Math.max(1, Math.floor(BACKING_STORE_LIMIT /
|
|
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 *
|
|
3430
|
-
cvs.height = logicalH *
|
|
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(
|
|
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 {
|
|
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 *
|
|
3494
|
-
canvas.height = headerHeight *
|
|
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(
|
|
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,
|
|
3536
|
+
const { scale, timeMargin, laneWidth, logicalWidth, mmMarginY } = config;
|
|
3540
3537
|
|
|
3541
3538
|
const mmHeightTotal = _playingFrame * scale + mmMarginY * 2;
|
|
3542
|
-
const canvases = createSplitCanvases(logicalWidth, mmHeightTotal
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
8243
|
-
graphObj.
|
|
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(
|
|
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: `#
|
|
10399
|
+
legendText: `#cccccc`, // 凡例テキスト
|
|
10404
10400
|
};
|
|
10405
10401
|
|
|
10406
10402
|
// ボタン配置
|
|
@@ -10469,7 +10465,7 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
10469
10465
|
{ kc: 55 }, { kc: 56 }, { kc: 57 },
|
|
10470
10466
|
{ kc: 48 }, { kc: 189 }, { kc: 222 },
|
|
10471
10467
|
...(isJa
|
|
10472
|
-
? [{ kc: 220, w: 0.75 }, { kc: 8 }] // JIS: intlYen + BS
|
|
10468
|
+
? [{ kc: 220, w: 0.75 }, { kc: 8, label: `Back\nSpace` }] // JIS: intlYen + BS
|
|
10473
10469
|
: [{ kc: 8, w: 1.7 }] // US : BS のみ(広い)
|
|
10474
10470
|
),
|
|
10475
10471
|
],
|
|
@@ -10669,7 +10665,7 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
10669
10665
|
if (forcedLabel !== undefined) return [forcedLabel, ``];
|
|
10670
10666
|
|
|
10671
10667
|
const raw = g_kCd[kc];
|
|
10672
|
-
if (raw && raw !==
|
|
10668
|
+
if (raw && raw !== g_kCd[0] && raw !== g_kCd[1]) {
|
|
10673
10669
|
const parts = raw.split(` `);
|
|
10674
10670
|
return [parts[0] || ``, parts[1] || ``];
|
|
10675
10671
|
}
|
|
@@ -10701,22 +10697,31 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
10701
10697
|
};
|
|
10702
10698
|
|
|
10703
10699
|
const drawKeyLabel = (ctx, x, y, keyW, keyH, primary, sub, textColor, subColor) => {
|
|
10704
|
-
const fs =
|
|
10705
|
-
? Math.max(6, Math.floor(
|
|
10700
|
+
const fs = (_textLen) => _textLen >= 5 * keyW / BASE_KEY_W
|
|
10701
|
+
? Math.max(6, Math.floor(9 * _state.scale))
|
|
10706
10702
|
: Math.max(7, Math.floor(11 * _state.scale));
|
|
10707
10703
|
|
|
10708
10704
|
if (sub) {
|
|
10709
10705
|
ctx.fillStyle = subColor;
|
|
10710
|
-
ctx.font = `bold ${Math.max(6, Math.floor(
|
|
10706
|
+
ctx.font = `bold ${Math.max(6, Math.floor(9 * _state.scale))}px monospace`;
|
|
10711
10707
|
ctx.textAlign = `right`;
|
|
10712
10708
|
ctx.textBaseline = `top`;
|
|
10713
10709
|
ctx.fillText(sub, x + keyW - 2, y + 2);
|
|
10714
10710
|
}
|
|
10711
|
+
const [primary1, primary2] = primary.split(`\n`);
|
|
10715
10712
|
ctx.fillStyle = textColor;
|
|
10716
|
-
ctx.font = `bold ${fs}px monospace`;
|
|
10717
10713
|
ctx.textAlign = `center`;
|
|
10718
10714
|
ctx.textBaseline = `middle`;
|
|
10719
|
-
|
|
10715
|
+
const subDiff = sub ? 2 : 0;
|
|
10716
|
+
if (primary2) {
|
|
10717
|
+
const siz = fs(Math.max(primary1.length, primary2.length));
|
|
10718
|
+
ctx.font = `bold ${siz}px monospace`;
|
|
10719
|
+
ctx.fillText(primary1, x + keyW / 2, y + keyH / 2 - siz / 2 + subDiff);
|
|
10720
|
+
ctx.fillText(primary2, x + keyW / 2, y + keyH / 2 + siz / 2 + subDiff);
|
|
10721
|
+
} else {
|
|
10722
|
+
ctx.font = `bold ${fs(primary.length)}px monospace`;
|
|
10723
|
+
ctx.fillText(primary, x + keyW / 2, y + keyH / 2 + subDiff);
|
|
10724
|
+
}
|
|
10720
10725
|
};
|
|
10721
10726
|
|
|
10722
10727
|
const drawOneKey = (ctx, x, y, keyW, keyH, fill, stroke, lw, primary, sub, textColor, subColor) => {
|
|
@@ -10787,15 +10792,14 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
10787
10792
|
const canvas = _state.canvasBase;
|
|
10788
10793
|
if (!canvas) return;
|
|
10789
10794
|
|
|
10790
|
-
const dpr = window.devicePixelRatio || 1;
|
|
10791
10795
|
canvas.style.top = wUnit(40);
|
|
10792
|
-
canvas.width = _state.cvsW *
|
|
10793
|
-
canvas.height = _state.cvsH *
|
|
10796
|
+
canvas.width = _state.cvsW * g_dpr;
|
|
10797
|
+
canvas.height = _state.cvsH * g_dpr;
|
|
10794
10798
|
canvas.style.width = wUnit(_state.cvsW);
|
|
10795
10799
|
canvas.style.height = wUnit(_state.cvsH);
|
|
10796
10800
|
|
|
10797
10801
|
const ctx = canvas.getContext(`2d`);
|
|
10798
|
-
ctx.scale(
|
|
10802
|
+
ctx.scale(g_dpr, g_dpr);
|
|
10799
10803
|
ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
|
|
10800
10804
|
ctx.fillStyle = C_COLOR.bgFill;
|
|
10801
10805
|
ctx.fillRect(0, 0, _state.cvsW, _state.cvsH);
|
|
@@ -10822,7 +10826,7 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
10822
10826
|
|
|
10823
10827
|
// 凡例
|
|
10824
10828
|
const ly = _state.cvsH - 10;
|
|
10825
|
-
const fnt = `${Math.max(9, Math.floor(
|
|
10829
|
+
const fnt = `${Math.max(9, Math.floor(12 * _state.scale))}px ${getBasicFont()}`;
|
|
10826
10830
|
ctx.font = fnt;
|
|
10827
10831
|
ctx.textAlign = `left`;
|
|
10828
10832
|
ctx.textBaseline = `middle`;
|
|
@@ -10852,15 +10856,14 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
10852
10856
|
const canvas = _state.canvasMap;
|
|
10853
10857
|
if (!canvas) return;
|
|
10854
10858
|
|
|
10855
|
-
const dpr = window.devicePixelRatio || 1;
|
|
10856
10859
|
canvas.style.top = wUnit(40);
|
|
10857
|
-
canvas.width = _state.cvsW *
|
|
10858
|
-
canvas.height = _state.cvsH *
|
|
10860
|
+
canvas.width = _state.cvsW * g_dpr;
|
|
10861
|
+
canvas.height = _state.cvsH * g_dpr;
|
|
10859
10862
|
canvas.style.width = wUnit(_state.cvsW);
|
|
10860
10863
|
canvas.style.height = wUnit(_state.cvsH);
|
|
10861
10864
|
|
|
10862
10865
|
const ctx = canvas.getContext(`2d`);
|
|
10863
|
-
ctx.scale(
|
|
10866
|
+
ctx.scale(g_dpr, g_dpr);
|
|
10864
10867
|
ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
|
|
10865
10868
|
|
|
10866
10869
|
// 優先度: ショートカット > メイン > 代替(後から描くほど優先)
|
|
@@ -16147,12 +16150,11 @@ const resultInit = () => {
|
|
|
16147
16150
|
for (let j = 0; j < 2; j++) {
|
|
16148
16151
|
const canvas = document.createElement(`canvas`);
|
|
16149
16152
|
canvas.id = `graphGaugeTransition${j > 0 ? j + 1 : ``}`;
|
|
16150
|
-
|
|
16151
|
-
canvas.
|
|
16152
|
-
canvas.height = g_limitObj.gaugeTransitionHeight * dpr;
|
|
16153
|
+
canvas.width = g_limitObj.gaugeTransitionWidth * g_dpr;
|
|
16154
|
+
canvas.height = g_limitObj.gaugeTransitionHeight * g_dpr;
|
|
16153
16155
|
canvas.style.width = wUnit(g_limitObj.gaugeTransitionWidth);
|
|
16154
16156
|
canvas.style.height = wUnit(g_limitObj.gaugeTransitionHeight);
|
|
16155
|
-
canvas.getContext(`2d`).scale(
|
|
16157
|
+
canvas.getContext(`2d`).scale(g_dpr, g_dpr);
|
|
16156
16158
|
canvas.style.left = wUnit(0);
|
|
16157
16159
|
canvas.style.top = wUnit(0);
|
|
16158
16160
|
canvas.style.position = `absolute`;
|
|
@@ -16463,13 +16465,12 @@ const resultInit = () => {
|
|
|
16463
16465
|
tmpDiv.style.background = `#000000cc`;
|
|
16464
16466
|
const canvas = document.createElement(`canvas`);
|
|
16465
16467
|
const artistName = g_headerObj.artistNames[g_headerObj.musicNos[g_stateObj.scoreId]] || g_headerObj.artistName;
|
|
16466
|
-
const dpr = window.devicePixelRatio || 1;
|
|
16467
16468
|
const logicalWidth = 400;
|
|
16468
16469
|
const logicalHeight = g_sHeight - 90;
|
|
16469
16470
|
|
|
16470
16471
|
canvas.id = `resultImage`;
|
|
16471
|
-
canvas.width = logicalWidth *
|
|
16472
|
-
canvas.height = logicalHeight *
|
|
16472
|
+
canvas.width = logicalWidth * g_dpr;
|
|
16473
|
+
canvas.height = logicalHeight * g_dpr;
|
|
16473
16474
|
canvas.style.width = wUnit(logicalWidth);
|
|
16474
16475
|
canvas.style.height = wUnit(logicalHeight);
|
|
16475
16476
|
canvas.style.left = wUnit((g_sWidth - parseFloat(canvas.style.width)) / 2);
|
|
@@ -16477,7 +16478,7 @@ const resultInit = () => {
|
|
|
16477
16478
|
canvas.style.position = `absolute`;
|
|
16478
16479
|
|
|
16479
16480
|
const context = canvas.getContext(`2d`);
|
|
16480
|
-
context.scale(
|
|
16481
|
+
context.scale(g_dpr, g_dpr);
|
|
16481
16482
|
const drawText = (_text, { x = 30, dy = 0, hy, siz = 15, color = `#cccccc`, align = C_ALIGN_LEFT, font } = {}) => {
|
|
16482
16483
|
context.font = `${wUnit(siz)} ${getBasicFont(font)}`;
|
|
16483
16484
|
context.fillStyle = color;
|