danoniplus 26.6.1 → 27.1.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.
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 : 2022/03/06
7
+ * Revised : 2022/03/25
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 26.6.1`;
12
- const g_revisedDate = `2022/03/06`;
11
+ const g_version = `Ver 27.1.0`;
12
+ const g_revisedDate = `2022/03/25`;
13
13
  const g_alphaVersion = ``;
14
14
 
15
15
  // カスタム用バージョン (danoni_custom.js 等で指定可)
@@ -54,6 +54,10 @@ const g_randTime = Date.now();
54
54
  window.onload = async () => {
55
55
  g_loadObj.main = true;
56
56
  g_currentPage = `initial`;
57
+ const links = document.querySelectorAll(`link`);
58
+ if (Array.from(links).filter(elem => elem.getAttribute(`href`).indexOf(`danoni_main.css`) !== -1).length === 0) {
59
+ await importCssFile2(`${g_rootPath}../css/danoni_main.css?${g_randTime}`);
60
+ }
57
61
 
58
62
  // ロード直後に定数・初期化ファイル、旧バージョン定義関数を読込
59
63
  await loadScript2(`${g_rootPath}../js/lib/danoni_localbinary.js?${g_randTime}`, false);
@@ -240,7 +244,7 @@ const hasVal = _data => _data !== undefined && _data !== ``;
240
244
  * @param {string} _default
241
245
  * @param {string} _type
242
246
  */
243
- const setVal = (_checkStr, _default, _type) => {
247
+ const setVal = (_checkStr, _default, _type = C_TYP_STRING) => {
244
248
 
245
249
  let convertStr = _checkStr;
246
250
 
@@ -281,6 +285,22 @@ const setVal = (_checkStr, _default, _type) => {
281
285
  return convertStr;
282
286
  };
283
287
 
288
+ /**
289
+ * ブール値への変換
290
+ * @param {string} _val
291
+ * @param {boolean} _defaultVal
292
+ * @returns
293
+ */
294
+ const setBoolVal = (_val, _defaultVal = false) => setVal(_val, _defaultVal, C_TYP_BOOLEAN);
295
+
296
+ /**
297
+ * 整数値への変換
298
+ * @param {string} _val
299
+ * @param {number} _defaultVal
300
+ * @returns
301
+ */
302
+ const setIntVal = (_val, _defaultVal = 0) => setVal(_val, _defaultVal, C_TYP_NUMBER);
303
+
284
304
  /**
285
305
  * 先頭のみ大文字に変換(それ以降はそのまま)
286
306
  * @param {string} _str
@@ -366,7 +386,7 @@ const fuzzyListMatching = (_str, _headerList, _footerList) =>
366
386
  const replaceStr = (_str, _pairs) => {
367
387
  let tmpStr = _str;
368
388
  _pairs.forEach(pair => {
369
- tmpStr = tmpStr.split(pair[0]).join(pair[1]);
389
+ tmpStr = tmpStr.replaceAll(pair[0], pair[1]);
370
390
  });
371
391
  return tmpStr;
372
392
  };
@@ -415,7 +435,7 @@ const nextPos = (_basePos, _num, _length) => (_basePos + _length + _num) % _leng
415
435
  */
416
436
  const transCode = _setCode => {
417
437
  if ([`Control`, `Shift`, `Alt`].includes(_setCode.slice(0, -5))) {
418
- return _setCode.replace(`Right`, `Left`);
438
+ return _setCode.replaceAll(`Right`, `Left`);
419
439
  }
420
440
  return _setCode;
421
441
  };
@@ -590,36 +610,6 @@ const preloadFile = (_as, _href, _type = ``, _crossOrigin = `anonymous`) => {
590
610
  }
591
611
  };
592
612
 
593
- /**
594
- * 外部jsファイルの読込 (callback)
595
- * 読込可否を g_loadObj[ファイル名] で管理 (true: 読込成功, false: 読込失敗)
596
- * @deprecated v27以降非推奨予定
597
- * @param {string} _url
598
- * @param {function} _callback
599
- * @param {boolean} _requiredFlg (default : true / 読込必須)
600
- * @param {string} _charset (default : UTF-8)
601
- */
602
- function loadScript(_url, _callback, _requiredFlg = true, _charset = `UTF-8`) {
603
- const baseUrl = _url.split(`?`)[0];
604
- g_loadObj[baseUrl] = false;
605
- const script = document.createElement(`script`);
606
- script.type = `text/javascript`;
607
- script.src = _url;
608
- script.charset = _charset;
609
- script.onload = _ => {
610
- g_loadObj[baseUrl] = true;
611
- _callback();
612
- };
613
- script.onerror = _ => {
614
- if (_requiredFlg) {
615
- makeWarningWindow(g_msgInfoObj.E_0041.split(`{0}`).join(_url.split(`?`)[0]));
616
- } else {
617
- _callback();
618
- }
619
- };
620
- document.querySelector(`head`).appendChild(script);
621
- }
622
-
623
613
  /**
624
614
  * 外部jsファイルの読込 (Promise)
625
615
  * 読込可否を g_loadObj[ファイル名] で管理 (true: 読込成功, false: 読込失敗)
@@ -652,30 +642,6 @@ const loadScript2 = (_url, _requiredFlg = true, _charset = `UTF-8`) => {
652
642
  });
653
643
  };
654
644
 
655
- /**
656
- * CSSファイルの読み込み (callback)
657
- * デフォルトは danoni_skin_default.css を読み込む
658
- * @deprecated v27以降非推奨予定
659
- * @param {url} _href
660
- * @param {function} _func
661
- */
662
- function importCssFile(_href, _func) {
663
- const baseUrl = _href.split(`?`)[0];
664
- g_loadObj[baseUrl] = false;
665
- const link = document.createElement(`link`);
666
- link.rel = `stylesheet`;
667
- link.href = _href;
668
- link.onload = _ => {
669
- g_loadObj[baseUrl] = true;
670
- _func();
671
- };
672
- link.onerror = _ => {
673
- makeWarningWindow(g_msgInfoObj.E_0041.split(`{0}`).join(baseUrl), { resetFlg: `title` });
674
- _func();
675
- };
676
- document.head.appendChild(link);
677
- }
678
-
679
645
  /**
680
646
  * CSSファイルの読み込み (Promise)
681
647
  * デフォルトは danoni_skin_default.css を読み込む
@@ -701,35 +667,6 @@ const importCssFile2 = _href => {
701
667
  });
702
668
  };
703
669
 
704
- /**
705
- * js, cssファイルの連続読込 (callback)
706
- * @deprecated v27以降非推奨予定
707
- * @param {number} _j
708
- * @param {array} _fileData
709
- * @param {string} _loadType
710
- * @param {function} _afterFunc
711
- */
712
- function loadMultipleFiles(_j, _fileData, _loadType, _afterFunc = _ => true) {
713
- if (_j < _fileData.length) {
714
- const filePath = `${_fileData[_j][1]}${_fileData[_j][0]}?${new Date().getTime()}`;
715
- if (_fileData[_j][0].endsWith(`.css`)) {
716
- _loadType = `css`;
717
- }
718
-
719
- // jsファイル、cssファイルにより呼び出す関数を切替
720
- if (_loadType === `js`) {
721
- loadScript(filePath, _ =>
722
- loadMultipleFiles(_j + 1, _fileData, _loadType, _afterFunc), false);
723
- } else if (_loadType === `css`) {
724
- const cssPath = filePath.split(`.js`).join(`.css`);
725
- importCssFile(cssPath, _ =>
726
- loadMultipleFiles(_j + 1, _fileData, _loadType, _afterFunc));
727
- }
728
- } else {
729
- _afterFunc();
730
- }
731
- }
732
-
733
670
  /**
734
671
  * js, cssファイルの連続読込 (async function)
735
672
  * @param {array} _fileData
@@ -842,7 +779,7 @@ const colorToHex = (_color) => {
842
779
  const tmpColor = _color.split(`;`);
843
780
  const colorSet = tmpColor[0].split(` `);
844
781
  return colorNameToCode(colorSet[0]) +
845
- (tmpColor.length > 1 ? byteToHex(setVal(tmpColor[1], 255, C_TYP_NUMBER)) : '') +
782
+ (tmpColor.length > 1 ? byteToHex(setIntVal(tmpColor[1], 255)) : '') +
846
783
  (colorSet[1] !== undefined ? ` ${colorSet.slice(1).join(' ')}` : '');
847
784
  };
848
785
 
@@ -881,7 +818,7 @@ const makeColorGradation = (_colorStr, { _defaultColorgrd = g_headerObj.defaultC
881
818
  const tmpColorStr = _colorStr.split(`@`);
882
819
  const colorArray = tmpColorStr[0].split(`:`);
883
820
  for (let j = 0; j < colorArray.length; j++) {
884
- colorArray[j] = colorCdPadding(_colorCdPaddingUse, colorToHex(colorArray[j].replace(/0x/g, `#`)));
821
+ colorArray[j] = colorCdPadding(_colorCdPaddingUse, colorToHex(colorArray[j].replaceAll(`0x`, `#`)));
885
822
  if (isColorCd(colorArray[j]) && colorArray[j].length === 7) {
886
823
  colorArray[j] += alphaVal;
887
824
  }
@@ -1146,6 +1083,17 @@ const deleteChildspriteAll = _parentObjName => {
1146
1083
  }
1147
1084
  };
1148
1085
 
1086
+ /**
1087
+ * div要素の削除
1088
+ * @param {object} _parentId
1089
+ * @param {string} _idName
1090
+ */
1091
+ const deleteDiv = (_parentId, _idName) => {
1092
+ if (document.getElementById(_idName) !== null) {
1093
+ _parentId.removeChild(document.getElementById(_idName));
1094
+ }
1095
+ };
1096
+
1149
1097
  /**
1150
1098
  * ボタンの作成 (CSS版・拡張属性対応)
1151
1099
  * @param {string} _id
@@ -1162,7 +1110,6 @@ const createCss2Button = (_id, _text, _func = _ => true, { x = 0, y = g_sHeight
1162
1110
  div.classList.add(`button_common`, ..._classes);
1163
1111
  div.innerHTML = _text;
1164
1112
  div.title = title;
1165
- div.ontouchstart = ``;
1166
1113
 
1167
1114
  const style = div.style;
1168
1115
  style.textAlign = align;
@@ -1185,13 +1132,13 @@ const createCss2Button = (_id, _text, _func = _ => true, { x = 0, y = g_sHeight
1185
1132
 
1186
1133
  // ボタンを押したときの動作
1187
1134
  const lsnrkey = g_handler.addListener(div, `click`, evt => {
1188
- if (!setVal(g_btnDeleteFlg[_id], false, C_TYP_BOOLEAN)) {
1135
+ if (!setBoolVal(g_btnDeleteFlg[_id])) {
1189
1136
  _func(evt);
1190
1137
  }
1191
1138
  if (typeof g_btnAddFunc[_id] === C_TYP_FUNCTION) {
1192
1139
  g_btnAddFunc[_id](evt, _func, resetFunc);
1193
1140
  }
1194
- if (!setVal(g_btnDeleteFlg[_id], false, C_TYP_BOOLEAN)) {
1141
+ if (!setBoolVal(g_btnDeleteFlg[_id])) {
1195
1142
  resetFunc(evt);
1196
1143
  }
1197
1144
  });
@@ -1199,7 +1146,7 @@ const createCss2Button = (_id, _text, _func = _ => true, { x = 0, y = g_sHeight
1199
1146
  // 右クリック時の処理
1200
1147
  div.oncontextmenu = evt => {
1201
1148
  if (typeof cxtFunc === C_TYP_FUNCTION) {
1202
- if (!setVal(g_cxtDeleteFlg[_id], false, C_TYP_BOOLEAN)) {
1149
+ if (!setBoolVal(g_cxtDeleteFlg[_id])) {
1203
1150
  cxtFunc(evt);
1204
1151
  }
1205
1152
  if (typeof g_cxtAddFunc[_id] === C_TYP_FUNCTION) {
@@ -1279,8 +1226,6 @@ const clearWindow = (_redrawFlg = false, _customDisplayName = ``) => {
1279
1226
  const layer0 = document.querySelector(`#layer0`);
1280
1227
  const l0ctx = layer0.getContext(`2d`);
1281
1228
 
1282
- const C_MARGIN = 0;
1283
-
1284
1229
  // 線画、図形をクリア
1285
1230
  l0ctx.clearRect(0, 0, g_sWidth, g_sHeight);
1286
1231
 
@@ -1292,14 +1237,14 @@ const clearWindow = (_redrawFlg = false, _customDisplayName = ``) => {
1292
1237
  // 線画 (title-line)
1293
1238
  l1ctx.beginPath();
1294
1239
  l1ctx.strokeStyle = `#cccccc`;
1295
- l1ctx.moveTo(C_MARGIN, C_MARGIN);
1296
- l1ctx.lineTo(g_sWidth - C_MARGIN, C_MARGIN);
1240
+ l1ctx.moveTo(0, 0);
1241
+ l1ctx.lineTo(g_sWidth, 0);
1297
1242
  l1ctx.stroke();
1298
1243
 
1299
1244
  l1ctx.beginPath();
1300
1245
  l1ctx.strokeStyle = `#cccccc`;
1301
- l1ctx.moveTo(C_MARGIN, g_sHeight - C_MARGIN);
1302
- l1ctx.lineTo(g_sWidth - C_MARGIN, g_sHeight - C_MARGIN);
1246
+ l1ctx.moveTo(0, g_sHeight);
1247
+ l1ctx.lineTo(g_sWidth, g_sHeight);
1303
1248
  l1ctx.stroke();
1304
1249
  }
1305
1250
  if (document.querySelector(`#layer2`) !== null) {
@@ -1356,17 +1301,14 @@ const drawDefaultBackImage = _key => {
1356
1301
  * @param {object} _obj
1357
1302
  */
1358
1303
  const makeSpriteImage = _obj => {
1359
- let tmpInnerHTML = `<img src=${_obj.path} class="${_obj.class}"
1360
- style="position:absolute;left:${_obj.left}px;top:${_obj.top}px`;
1361
- if (_obj.width !== 0 && _obj.width > 0) {
1304
+ let tmpInnerHTML = `<img src=${_obj.path} class="${_obj.class}" style="position:absolute;left:${_obj.left}px;top:${_obj.top}px`;
1305
+ if (_obj.width > 0) {
1362
1306
  tmpInnerHTML += `;width:${_obj.width}px`;
1363
1307
  }
1364
- if (_obj.height !== `` && setVal(_obj.height, 0, C_TYP_NUMBER) > 0) {
1308
+ if (setIntVal(_obj.height) > 0) {
1365
1309
  tmpInnerHTML += `;height:${_obj.height}px`;
1366
1310
  }
1367
- tmpInnerHTML += `;animation-name:${_obj.animationName}
1368
- ;animation-duration:${_obj.animationDuration}s
1369
- ;opacity:${_obj.opacity}">`;
1311
+ tmpInnerHTML += `;animation-name:${_obj.animationName};animation-duration:${_obj.animationDuration}s;opacity:${_obj.opacity}">`;
1370
1312
  return tmpInnerHTML;
1371
1313
  };
1372
1314
 
@@ -1375,11 +1317,10 @@ const makeSpriteImage = _obj => {
1375
1317
  * @param {object} _obj
1376
1318
  */
1377
1319
  const makeSpriteText = _obj => {
1378
- let tmpInnerHTML = `<span class="${_obj.class}"
1379
- style="display:inline-block;position:absolute;left:${_obj.left}px;top:${_obj.top}px`;
1320
+ let tmpInnerHTML = `<span class="${_obj.class}" style="display:inline-block;position:absolute;left:${_obj.left}px;top:${_obj.top}px`;
1380
1321
 
1381
1322
  // この場合のwidthは font-size と解釈する
1382
- if (_obj.width !== 0 && _obj.width > 0) {
1323
+ if (_obj.width > 0) {
1383
1324
  tmpInnerHTML += `;font-size:${_obj.width}px`;
1384
1325
  }
1385
1326
 
@@ -1387,9 +1328,7 @@ const makeSpriteText = _obj => {
1387
1328
  if (_obj.height !== ``) {
1388
1329
  tmpInnerHTML += `;color:${_obj.height}`;
1389
1330
  }
1390
- tmpInnerHTML += `;animation-name:${_obj.animationName}
1391
- ;animation-duration:${_obj.animationDuration}s
1392
- ;opacity:${_obj.opacity}">${_obj.path}</span>`;
1331
+ tmpInnerHTML += `;animation-name:${_obj.animationName};animation-duration:${_obj.animationDuration}s;opacity:${_obj.opacity}">${_obj.path}</span>`;
1393
1332
  return tmpInnerHTML;
1394
1333
  };
1395
1334
 
@@ -1433,7 +1372,7 @@ const makeSpriteData = (_data, _calcFrame = _frame => _frame) => {
1433
1372
 
1434
1373
  // 値チェックとエスケープ処理
1435
1374
  let tmpFrame;
1436
- if (setVal(tmpSpriteData[0], 200, C_TYP_NUMBER) === 0) {
1375
+ if (setIntVal(tmpSpriteData[0], -1) === 0) {
1437
1376
  tmpFrame = 0;
1438
1377
  } else {
1439
1378
  tmpFrame = roundZero(_calcFrame(setVal(tmpSpriteData[0], 200, C_TYP_CALC)));
@@ -1444,15 +1383,15 @@ const makeSpriteData = (_data, _calcFrame = _frame => _frame) => {
1444
1383
  }
1445
1384
 
1446
1385
  const tmpObj = {
1447
- path: escapeHtml(tmpSpriteData[2] ?? ``, g_escapeStr.escapeCode), // 画像パス or テキスト
1448
- class: escapeHtml(tmpSpriteData[3] ?? ``), // CSSクラス
1449
- left: setVal(tmpSpriteData[4], 0, C_TYP_CALC), // X座標
1450
- top: setVal(tmpSpriteData[5], 0, C_TYP_CALC), // Y座標
1451
- width: setVal(tmpSpriteData[6], 0, C_TYP_NUMBER), // spanタグの場合は font-size
1452
- height: escapeHtml(tmpSpriteData[7] ?? ``), // spanタグの場合は color(文字列可)
1386
+ path: escapeHtml(tmpSpriteData[2] ?? ``, g_escapeStr.escapeCode), // 画像パス or テキスト
1387
+ class: escapeHtml(tmpSpriteData[3] ?? ``), // CSSクラス
1388
+ left: setVal(tmpSpriteData[4], 0, C_TYP_CALC), // X座標
1389
+ top: setVal(tmpSpriteData[5], 0, C_TYP_CALC), // Y座標
1390
+ width: setIntVal(tmpSpriteData[6]), // spanタグの場合は font-size
1391
+ height: escapeHtml(tmpSpriteData[7] ?? ``), // spanタグの場合は color(文字列可)
1453
1392
  opacity: setVal(tmpSpriteData[8], 1, C_TYP_FLOAT),
1454
- animationName: escapeHtml(setVal(tmpSpriteData[9], C_DIS_NONE, C_TYP_STRING)),
1455
- animationDuration: setVal(tmpSpriteData[10], 0, C_TYP_NUMBER) / g_fps,
1393
+ animationName: escapeHtml(setVal(tmpSpriteData[9], C_DIS_NONE)),
1394
+ animationDuration: setIntVal(tmpSpriteData[10]) / g_fps,
1456
1395
  };
1457
1396
  if (g_headerObj.autoPreload) {
1458
1397
  if (checkImage(tmpObj.path)) {
@@ -1497,9 +1436,32 @@ const checkImage = _str => listMatching(_str, g_imgExtensions, { prefix: `[.]`,
1497
1436
  const getSpriteJumpFrame = _frames => {
1498
1437
  const jumpFrames = _frames.split(`:`);
1499
1438
  const jumpCnt = Math.floor(Math.random() * jumpFrames.length);
1500
- return setVal(Number(jumpFrames[jumpCnt]) - 1, 0, C_TYP_NUMBER);
1439
+ return setIntVal(Number(jumpFrames[jumpCnt]) - 1);
1501
1440
  };
1502
1441
 
1442
+ /**
1443
+ * 背景・マスクモーションの表示(共通処理)
1444
+ * @param {object} _spriteData
1445
+ * @param {string} _name
1446
+ * @param {boolean} _condition
1447
+ */
1448
+ const drawBaseSpriteData = (_spriteData, _name, _condition = true) => {
1449
+ const baseSprite = document.querySelector(`#${_name}Sprite${_spriteData.depth}`);
1450
+ if (_spriteData.command === ``) {
1451
+ if (_spriteData.depth === C_FLG_ALL) {
1452
+ for (let j = 0; j <= g_scoreObj[`${_name}MaxDepth`]; j++) {
1453
+ document.querySelector(`#${_name}Sprite${j}`).textContent = ``;
1454
+ }
1455
+ } else {
1456
+ baseSprite.textContent = ``;
1457
+ }
1458
+ } else {
1459
+ if (_condition) {
1460
+ baseSprite.innerHTML = _spriteData.htmlText;
1461
+ }
1462
+ }
1463
+ }
1464
+
1503
1465
  /**
1504
1466
  * 背景・マスクモーションの表示(タイトル・リザルト用)
1505
1467
  * @param {number} _frame
@@ -1513,31 +1475,19 @@ const drawSpriteData = (_frame, _displayName, _depthName) => {
1513
1475
 
1514
1476
  for (let j = 0; j < tmpObjs.length; j++) {
1515
1477
  const tmpObj = tmpObjs[j];
1516
- const baseSprite = document.querySelector(`#${spriteName}Sprite${tmpObj.depth}`);
1517
- if (tmpObj.command !== ``) {
1518
- if (tmpObj.command === `[loop]`) {
1519
- // キーワード指定:ループ
1520
- // 指定フレーム(class)へ移動する
1521
- g_scoreObj[`${spriteName}LoopCount`]++;
1478
+ drawBaseSpriteData(tmpObj, spriteName, ![`[loop]`, `[jump]`].includes(tmpObj.command));
1479
+ if (tmpObj.command === `[loop]`) {
1480
+ // キーワード指定:ループ
1481
+ // 指定フレーム(class)へ移動する
1482
+ g_scoreObj[`${spriteName}LoopCount`]++;
1483
+ return getSpriteJumpFrame(tmpObj.jumpFrame);
1484
+
1485
+ } else if (tmpObj.command === `[jump]`) {
1486
+ // キーワード指定:フレームジャンプ
1487
+ // 指定回数以上のループ(maxLoop)があれば指定フレーム(jumpFrame)へ移動する
1488
+ if (g_scoreObj[`${spriteName}LoopCount`] >= Number(tmpObj.maxLoop)) {
1489
+ g_scoreObj[`${spriteName}LoopCount`] = 0;
1522
1490
  return getSpriteJumpFrame(tmpObj.jumpFrame);
1523
-
1524
- } else if (tmpObj.command === `[jump]`) {
1525
- // キーワード指定:フレームジャンプ
1526
- // 指定回数以上のループ(maxLoop)があれば指定フレーム(jumpFrame)へ移動する
1527
- if (g_scoreObj[`${spriteName}LoopCount`] >= Number(tmpObj.maxLoop)) {
1528
- g_scoreObj[`${spriteName}LoopCount`] = 0;
1529
- return getSpriteJumpFrame(tmpObj.jumpFrame);
1530
- }
1531
- } else {
1532
- baseSprite.innerHTML = tmpObj.htmlText;
1533
- }
1534
- } else {
1535
- if (tmpObj.depth === C_FLG_ALL) {
1536
- for (let j = 0; j <= g_headerObj[`${spriteName}MaxDepth`]; j++) {
1537
- document.querySelector(`#${spriteName}Sprite${j}`).textContent = ``;
1538
- }
1539
- } else {
1540
- baseSprite.textContent = ``;
1541
1491
  }
1542
1492
  }
1543
1493
  }
@@ -1549,25 +1499,8 @@ const drawSpriteData = (_frame, _displayName, _depthName) => {
1549
1499
  * @param {number} _frame
1550
1500
  * @param {string} _depthName
1551
1501
  */
1552
- const drawMainSpriteData = (_frame, _depthName) => {
1553
-
1554
- const tmpObjs = g_scoreObj[`${_depthName}Data`][_frame];
1555
-
1556
- tmpObjs.forEach(tmpObj => {
1557
- const baseSprite = document.querySelector(`#${_depthName}Sprite${tmpObj.depth}`);
1558
- if (tmpObj.command !== ``) {
1559
- baseSprite.innerHTML = tmpObj.htmlText;
1560
- } else {
1561
- if (tmpObj.depth === C_FLG_ALL) {
1562
- for (let j = 0; j <= g_scoreObj[`${_depthName}MaxDepth`]; j++) {
1563
- document.querySelector(`#${_depthName}Sprite${j}`).textContent = ``;
1564
- }
1565
- } else {
1566
- baseSprite.textContent = ``;
1567
- }
1568
- }
1569
- });
1570
- };
1502
+ const drawMainSpriteData = (_frame, _depthName) =>
1503
+ g_scoreObj[`${_depthName}Data`][_frame].forEach(tmpObj => drawBaseSpriteData(tmpObj, _depthName));
1571
1504
 
1572
1505
  /**
1573
1506
  * タイトル・リザルトモーションの描画
@@ -1751,12 +1684,8 @@ const transTimerToFrame = _str => {
1751
1684
 
1752
1685
  const initialControl = async () => {
1753
1686
 
1754
- [g_sWidth, g_sHeight] = [
1755
- setVal($id(`canvas-frame`).width, 600, C_TYP_FLOAT), setVal($id(`canvas-frame`).height, 500, C_TYP_FLOAT)
1756
- ];
1757
-
1758
1687
  const stage = document.querySelector(`#canvas-frame`);
1759
- const divRoot = createEmptySprite(stage, `divRoot`, { margin: `auto`, letterSpacing: `normal` });
1688
+ const divRoot = createEmptySprite(stage, `divRoot`, g_windowObj.divRoot);
1760
1689
 
1761
1690
  // 背景の表示
1762
1691
  if (document.querySelector(`#layer0`) !== null) {
@@ -1768,7 +1697,7 @@ const initialControl = async () => {
1768
1697
  l0ctx.fillStyle = grd;
1769
1698
  l0ctx.fillRect(0, 0, g_sWidth, g_sHeight);
1770
1699
  } else {
1771
- createEmptySprite(divRoot, `divBack`, { background: `linear-gradient(#000000, #222222)` });
1700
+ createEmptySprite(divRoot, `divBack`, g_windowObj.divBack);
1772
1701
  }
1773
1702
 
1774
1703
  // Now Loadingを表示
@@ -1778,15 +1707,8 @@ const initialControl = async () => {
1778
1707
  g_canLoadDifInfoFlg = true;
1779
1708
 
1780
1709
  // 譜面データの読み込みオプション
1781
- const ampSplitInput = document.querySelector(`#enableAmpersandSplit`);
1782
- if (ampSplitInput !== null) {
1783
- g_enableAmpersandSplit = setVal(ampSplitInput.value, true, C_TYP_BOOLEAN);
1784
- }
1785
-
1786
- const decodeUriInput = document.querySelector(`#enableDecodeURI`);
1787
- if (decodeUriInput !== null) {
1788
- g_enableDecodeURI = setVal(decodeUriInput.value, false, C_TYP_BOOLEAN);
1789
- }
1710
+ g_enableAmpersandSplit = setBoolVal(document.querySelector(`#enableAmpersandSplit`)?.value, true);
1711
+ g_enableDecodeURI = setBoolVal(document.querySelector(`#enableDecodeURI`)?.value);
1790
1712
 
1791
1713
  // 作品別ローカルストレージの読み込み
1792
1714
  loadLocalStorage();
@@ -1803,19 +1725,17 @@ const initialControl = async () => {
1803
1725
  // 共通設定ファイルの読込
1804
1726
  await loadScript2(`${settingRoot}danoni_setting${settingType}.js?${g_randTime}`, false);
1805
1727
  loadLegacySettingFunc();
1806
- if (document.querySelector(`#lblLoading`) !== null) {
1807
- divRoot.removeChild(document.querySelector(`#lblLoading`));
1808
- }
1728
+ deleteDiv(divRoot, `lblLoading`);
1809
1729
 
1810
1730
  // クエリで譜面番号が指定されていればセット
1811
- g_stateObj.scoreId = setVal(getQueryParamVal(`scoreId`), 0, C_TYP_NUMBER);
1731
+ g_stateObj.scoreId = setIntVal(getQueryParamVal(`scoreId`));
1812
1732
 
1813
1733
  // 譜面ヘッダーの読込
1814
1734
  Object.assign(g_headerObj, preheaderConvert(g_rootObj));
1815
1735
 
1816
1736
  // CSSファイル内のbackgroundを取得するために再描画
1817
1737
  if (document.querySelector(`#layer0`) === null) {
1818
- divRoot.removeChild(document.querySelector(`#divBack`));
1738
+ deleteDiv(divRoot, `divBack`);
1819
1739
  createEmptySprite(divRoot, `divBack`);
1820
1740
  } else if (!g_headerObj.defaultSkinFlg && !g_headerObj.customBackUse) {
1821
1741
  createEmptySprite(divRoot, `divBack`);
@@ -1840,6 +1760,21 @@ const initialControl = async () => {
1840
1760
  makeDedupliArray(g_rootObj.keyExtraList.split(`,`), g_headerObj.undefinedKeyLists) : g_headerObj.undefinedKeyLists),
1841
1761
  });
1842
1762
 
1763
+ // 自動横幅拡張設定
1764
+ if (g_headerObj.autoSpread) {
1765
+ const widthList = [g_sWidth, g_presetObj.autoMinWidth ?? g_keyObj.minWidth];
1766
+ g_headerObj.keyLists.forEach(key => widthList.push(g_keyObj[`minWidth${key}`] ?? g_keyObj.minWidthDefault));
1767
+
1768
+ g_sWidth = Math.max(...widthList);
1769
+ $id(`canvas-frame`).width = `${g_sWidth}px`;
1770
+ }
1771
+ if (g_headerObj.playingWidth === `default`) {
1772
+ g_headerObj.playingWidth = g_sWidth;
1773
+ }
1774
+
1775
+ // 可変ウィンドウサイズを更新
1776
+ updateWindowSiz();
1777
+
1843
1778
  // キー数情報を初期化
1844
1779
  g_keyObj.currentKey = g_headerObj.keyLabels[g_stateObj.scoreId];
1845
1780
  g_keyObj.currentPtn = 0;
@@ -1867,16 +1802,16 @@ const initialControl = async () => {
1867
1802
 
1868
1803
  if (termRoopCnts.length === 1) {
1869
1804
  // Pattern Bの場合
1870
- lastCnt = setVal(tmpPreloadImages[1], 1, C_TYP_NUMBER);
1871
- paddingLen = String(setVal(tmpPreloadImages[1], 1, C_TYP_STRING)).length;
1805
+ lastCnt = setIntVal(tmpPreloadImages[1], 1);
1806
+ paddingLen = String(setVal(tmpPreloadImages[1], 1)).length;
1872
1807
  } else {
1873
1808
  // Pattern C, Dの場合
1874
- startCnt = setVal(termRoopCnts[0], 1, C_TYP_NUMBER);
1875
- lastCnt = setVal(termRoopCnts[1], 1, C_TYP_NUMBER);
1876
- paddingLen = String(setVal(termRoopCnts[1], 1, C_TYP_STRING)).length;
1809
+ startCnt = setIntVal(termRoopCnts[0], 1);
1810
+ lastCnt = setIntVal(termRoopCnts[1], 1);
1811
+ paddingLen = String(setVal(termRoopCnts[1], 1)).length;
1877
1812
  }
1878
1813
  for (let k = startCnt; k <= lastCnt; k++) {
1879
- preloadFile(`image`, tmpPreloadImages[0].replace(/\*/g, String(k).padStart(paddingLen, `0`)));
1814
+ preloadFile(`image`, tmpPreloadImages[0].replaceAll(`*`, String(k).padStart(paddingLen, `0`)));
1880
1815
  }
1881
1816
  }
1882
1817
  });
@@ -1897,8 +1832,8 @@ const initialControl = async () => {
1897
1832
  if (g_loadObj.main) {
1898
1833
 
1899
1834
  // 譜面分割、譜面番号固定かどうかをチェック
1900
- g_stateObj.dosDivideFlg = setVal(document.querySelector(`#externalDosDivide`)?.value ?? getQueryParamVal(`dosDivide`), false, C_TYP_BOOLEAN);
1901
- g_stateObj.scoreLockFlg = setVal(document.querySelector(`#externalDosLock`)?.value ?? getQueryParamVal(`dosLock`), false, C_TYP_BOOLEAN);
1835
+ g_stateObj.dosDivideFlg = setBoolVal(document.querySelector(`#externalDosDivide`)?.value ?? getQueryParamVal(`dosDivide`));
1836
+ g_stateObj.scoreLockFlg = setBoolVal(document.querySelector(`#externalDosLock`)?.value ?? getQueryParamVal(`dosLock`));
1902
1837
 
1903
1838
  for (let j = 1; j < g_headerObj.keyLabels.length; j++) {
1904
1839
 
@@ -2034,9 +1969,7 @@ const loadChartFile = async (_scoreId = g_stateObj.scoreId) => {
2034
1969
 
2035
1970
  await loadScript2(`${filename}?${Date.now()}`, false, charset);
2036
1971
  if (typeof externalDosInit === C_TYP_FUNCTION) {
2037
- if (document.querySelector(`#lblLoading`) !== null) {
2038
- divRoot.removeChild(document.querySelector(`#lblLoading`));
2039
- }
1972
+ deleteDiv(divRoot, `lblLoading`);
2040
1973
 
2041
1974
  // 外部データを読込(ファイルが見つからなかった場合は譜面追記をスキップ)
2042
1975
  externalDosInit();
@@ -2375,6 +2308,12 @@ const preheaderConvert = _dosObj => {
2375
2308
  // ヘッダー群の格納先
2376
2309
  const obj = {};
2377
2310
 
2311
+ // ウィンドウ位置の設定
2312
+ const align = _dosObj.windowAlign ?? g_presetObj.windowAlign;
2313
+ if (align !== undefined) {
2314
+ g_windowAlign[align]();
2315
+ }
2316
+
2378
2317
  obj.jsData = [];
2379
2318
 
2380
2319
  const setJsFiles = (_files, _defaultDir, _type = `custom`) => {
@@ -2394,21 +2333,21 @@ const preheaderConvert = _dosObj => {
2394
2333
 
2395
2334
  // 外部jsファイルの指定
2396
2335
  const tmpCustomjs = _dosObj.customjs ?? g_presetObj.customJs ?? C_JSF_CUSTOM;
2397
- setJsFiles(tmpCustomjs.split(`,`), C_DIR_JS);
2336
+ setJsFiles(tmpCustomjs.replaceAll(`*`, g_presetObj.customJs).split(`,`), C_DIR_JS);
2398
2337
 
2399
2338
  // 外部cssファイルの指定
2400
2339
  const tmpCustomcss = _dosObj.customcss ?? g_presetObj.customCss ?? ``;
2401
- setJsFiles(tmpCustomcss.split(`,`), C_DIR_CSS);
2340
+ setJsFiles(tmpCustomcss.replaceAll(`*`, g_presetObj.customCss).split(`,`), C_DIR_CSS);
2402
2341
 
2403
2342
  // デフォルト曲名表示、背景、Ready表示の利用有無
2404
2343
  g_titleLists.init.forEach(objName => {
2405
2344
  const objUpper = toCapitalize(objName);
2406
2345
  obj[`custom${objUpper}Use`] =
2407
- setVal(_dosObj[`custom${objUpper}Use`] ?? g_presetObj.customDesignUse?.[objName], false, C_TYP_BOOLEAN);
2346
+ setBoolVal(_dosObj[`custom${objUpper}Use`] ?? g_presetObj.customDesignUse?.[objName]);
2408
2347
  });
2409
2348
 
2410
2349
  // 背景・マスクモーションのパス指定方法を他の設定に合わせる設定
2411
- obj.syncBackPath = setVal(_dosObj.syncBackPath ?? g_presetObj.syncBackPath, false, C_TYP_BOOLEAN);
2350
+ obj.syncBackPath = setBoolVal(_dosObj.syncBackPath ?? g_presetObj.syncBackPath);
2412
2351
 
2413
2352
  return obj;
2414
2353
  };
@@ -2441,7 +2380,7 @@ const headerConvert = _dosObj => {
2441
2380
  obj.imgType[j] = {
2442
2381
  name: imgTypes[0],
2443
2382
  extension: imgTypes[1] || `svg`,
2444
- rotateEnabled: setVal(imgTypes[2], true, C_TYP_BOOLEAN),
2383
+ rotateEnabled: setBoolVal(imgTypes[2], true),
2445
2384
  flatStepHeight: setVal(imgTypes[3], C_ARW_WIDTH, C_TYP_FLOAT),
2446
2385
  };
2447
2386
  g_keycons.imgTypes[j] = (imgTypes[0] === `` ? `Original` : imgTypes[0]);
@@ -2467,6 +2406,15 @@ const headerConvert = _dosObj => {
2467
2406
  Object.assign(g_lblNameObj, g_lang_lblNameObj[g_localeObj.val], g_presetObj.lblName?.[g_localeObj.val]);
2468
2407
  Object.assign(g_msgObj, g_lang_msgObj[g_localeObj.val], g_presetObj.msg?.[g_localeObj.val]);
2469
2408
 
2409
+ // 自動横幅拡張設定
2410
+ obj.autoSpread = setBoolVal(_dosObj.autoSpread, g_presetObj.autoSpread ?? true);
2411
+
2412
+ // 横幅設定
2413
+ if (hasVal(_dosObj.windowWidth)) {
2414
+ g_sWidth = setIntVal(_dosObj.windowWidth, g_sWidth);
2415
+ $id(`canvas-frame`).width = `${g_sWidth}px`;
2416
+ }
2417
+
2470
2418
  // 曲名
2471
2419
  obj.musicTitles = [];
2472
2420
  obj.musicTitlesForView = [];
@@ -2521,13 +2469,13 @@ const headerConvert = _dosObj => {
2521
2469
  g_settings.speeds = [...Array((obj.maxSpeed - obj.minSpeed) * 20 + 1).keys()].map(i => obj.minSpeed + i / 20);
2522
2470
 
2523
2471
  // プレイ中のショートカットキー
2524
- obj.keyRetry = setVal(_dosObj.keyRetry, C_KEY_RETRY, C_TYP_NUMBER);
2472
+ obj.keyRetry = setIntVal(_dosObj.keyRetry, C_KEY_RETRY);
2525
2473
  obj.keyRetryDef = obj.keyRetry;
2526
- obj.keyTitleBack = setVal(_dosObj.keyTitleBack, C_KEY_TITLEBACK, C_TYP_NUMBER);
2474
+ obj.keyTitleBack = setIntVal(_dosObj.keyTitleBack, C_KEY_TITLEBACK);
2527
2475
  obj.keyTitleBackDef = obj.keyTitleBack;
2528
2476
 
2529
2477
  // フリーズアローの許容フレーム数設定
2530
- obj.frzAttempt = setVal(_dosObj.frzAttempt, C_FRM_FRZATTEMPT, C_TYP_NUMBER);
2478
+ obj.frzAttempt = setIntVal(_dosObj.frzAttempt, C_FRM_FRZATTEMPT);
2531
2479
 
2532
2480
  // 製作者表示
2533
2481
  if (hasVal(_dosObj.tuning)) {
@@ -2600,7 +2548,7 @@ const headerConvert = _dosObj => {
2600
2548
  obj.undefinedKeyLists = obj.keyLists.filter(key => g_keyObj[`chara${key}_0`] === undefined);
2601
2549
 
2602
2550
  // 譜面変更セレクターの利用有無
2603
- obj.difSelectorUse = (setVal(_dosObj.difSelectorUse, obj.keyLabels.length > 5, C_TYP_BOOLEAN));
2551
+ obj.difSelectorUse = (setBoolVal(_dosObj.difSelectorUse, obj.keyLabels.length > 5));
2604
2552
 
2605
2553
  // 初期速度の設定
2606
2554
  g_stateObj.speed = obj.initSpeeds[g_stateObj.scoreId];
@@ -2608,20 +2556,20 @@ const headerConvert = _dosObj => {
2608
2556
 
2609
2557
  // グラデーションのデフォルト中間色を設定
2610
2558
  divRoot.appendChild(createDivCss2Label(`dummyLabel`, ``, { pointerEvents: C_DIS_NONE }));
2611
- obj.baseBrightFlg = setVal(_dosObj.baseBright, checkLightOrDark(colorNameToCode(window.getComputedStyle(dummyLabel, ``).color)), C_TYP_BOOLEAN);
2559
+ obj.baseBrightFlg = setBoolVal(_dosObj.baseBright, checkLightOrDark(colorNameToCode(window.getComputedStyle(dummyLabel, ``).color)));
2612
2560
  const intermediateColor = obj.baseBrightFlg ? `#111111` : `#eeeeee`;
2613
2561
 
2614
2562
  // 矢印の色変化を常時グラデーションさせる設定
2615
2563
  obj.defaultColorgrd = [false, intermediateColor];
2616
2564
  if (hasVal(_dosObj.defaultColorgrd)) {
2617
2565
  obj.defaultColorgrd = _dosObj.defaultColorgrd.split(`,`);
2618
- obj.defaultColorgrd[0] = setVal(obj.defaultColorgrd[0], false, C_TYP_BOOLEAN);
2566
+ obj.defaultColorgrd[0] = setBoolVal(obj.defaultColorgrd[0]);
2619
2567
  obj.defaultColorgrd[1] = obj.defaultColorgrd[1] ?? intermediateColor;
2620
2568
  }
2621
2569
  g_rankObj.rankColorAllPerfect = intermediateColor;
2622
2570
 
2623
2571
  // カラーコードのゼロパディング有無設定
2624
- obj.colorCdPaddingUse = setVal(_dosObj.colorCdPaddingUse, false, C_TYP_BOOLEAN);
2572
+ obj.colorCdPaddingUse = setBoolVal(_dosObj.colorCdPaddingUse);
2625
2573
 
2626
2574
  // 最大ライフ
2627
2575
  obj.maxLifeVal = setVal(_dosObj.maxLifeVal, C_VAL_MAXLIFE, C_TYP_FLOAT);
@@ -2637,7 +2585,7 @@ const headerConvert = _dosObj => {
2637
2585
  });
2638
2586
 
2639
2587
  // フリーズアローのデフォルト色セットの利用有無 (true: 使用, false: 矢印色を優先してセット)
2640
- obj.defaultFrzColorUse = setVal(_dosObj.defaultFrzColorUse ?? g_presetObj.frzColors, true, C_TYP_BOOLEAN);
2588
+ obj.defaultFrzColorUse = setBoolVal(_dosObj.defaultFrzColorUse ?? g_presetObj.frzColors, true);
2641
2589
 
2642
2590
  // 矢印色変化に対応してフリーズアロー色を追随する範囲の設定
2643
2591
  // (defaultFrzColorUse=false時のみ)
@@ -2738,7 +2686,7 @@ const headerConvert = _dosObj => {
2738
2686
  g_posObj.distY = g_sHeight - C_STEP_Y + g_posObj.stepYR;
2739
2687
  g_posObj.reverseStepY = g_posObj.distY - g_posObj.stepY - g_posObj.stepDiffY - C_ARW_WIDTH;
2740
2688
  g_posObj.arrowHeight = g_sHeight + g_posObj.stepYR - g_posObj.stepDiffY * 2;
2741
- obj.bottomWordSetFlg = setVal(_dosObj.bottomWordSet, false, C_TYP_BOOLEAN);
2689
+ obj.bottomWordSetFlg = setBoolVal(_dosObj.bottomWordSet);
2742
2690
 
2743
2691
  // 矢印・フリーズアロー判定位置補正
2744
2692
  g_diffObj.arrowJdgY = (isNaN(parseFloat(_dosObj.arrowJdgY)) ? 0 : parseFloat(_dosObj.arrowJdgY));
@@ -2755,12 +2703,10 @@ const headerConvert = _dosObj => {
2755
2703
  }
2756
2704
 
2757
2705
  // ハッシュタグ
2758
- if (hasVal(_dosObj.hashTag)) {
2759
- obj.hashTag = _dosObj.hashTag;
2760
- }
2706
+ obj.hashTag = setVal(_dosObj.hashTag, ``);
2761
2707
 
2762
2708
  // 自動プリロードの設定
2763
- obj.autoPreload = setVal(_dosObj.autoPreload, true, C_TYP_BOOLEAN);
2709
+ obj.autoPreload = setBoolVal(_dosObj.autoPreload, true);
2764
2710
  g_headerObj.autoPreload = obj.autoPreload;
2765
2711
 
2766
2712
  // 読込対象の画像を指定(rel:preload)と同じ
@@ -2777,11 +2723,11 @@ const headerConvert = _dosObj => {
2777
2723
 
2778
2724
  // デフォルトReady/リザルト表示の遅延時間設定
2779
2725
  [`ready`, `result`].forEach(objName => {
2780
- obj[`${objName}DelayFrame`] = setVal(_dosObj[`${objName}DelayFrame`], 0, C_TYP_NUMBER);
2726
+ obj[`${objName}DelayFrame`] = setIntVal(_dosObj[`${objName}DelayFrame`]);
2781
2727
  });
2782
2728
 
2783
2729
  // デフォルトReady表示のアニメーション時間設定
2784
- obj.readyAnimationFrame = setVal(_dosObj.readyAnimationFrame, 150, C_TYP_NUMBER);
2730
+ obj.readyAnimationFrame = setIntVal(_dosObj.readyAnimationFrame, 150);
2785
2731
 
2786
2732
  // デフォルトReady表示のアニメーション名
2787
2733
  obj.readyAnimationName = _dosObj.readyAnimationName ?? `leftToRightFade`;
@@ -2798,20 +2744,16 @@ const headerConvert = _dosObj => {
2798
2744
  // デフォルト曲名表示のフォント名
2799
2745
  // (使用例: |titlefont=Century,Meiryo UI|)
2800
2746
  obj.titlefonts = g_titleLists.defaultFonts.concat();
2801
- if (hasVal(_dosObj.titlefont)) {
2802
- _dosObj.titlefont.split(`$`).forEach((font, j) => {
2803
- obj.titlefonts[j] = `'${(font.replace(/,/g, `', '`))}'`;
2804
- });
2805
- if (obj.titlefonts[1] === undefined) {
2806
- obj.titlefonts[1] = obj.titlefonts[0];
2807
- }
2747
+ _dosObj.titlefont?.split(`$`).forEach((font, j) => obj.titlefonts[j] = `'${(font.replaceAll(`,`, `', '`))}'`);
2748
+ if (obj.titlefonts[1] === undefined) {
2749
+ obj.titlefonts[1] = obj.titlefonts[0];
2808
2750
  }
2809
2751
 
2810
2752
  // デフォルト曲名表示, 背景矢印のグラデーション指定css
2811
2753
  g_titleLists.grdList.forEach(_name => {
2812
2754
  obj[`${_name}s`] = [];
2813
2755
  if (hasVal(_dosObj[_name])) {
2814
- const tmpTitlegrd = _dosObj[_name].replace(/,/g, `:`);
2756
+ const tmpTitlegrd = _dosObj[_name].replaceAll(`,`, `:`);
2815
2757
  obj[`${_name}s`] = tmpTitlegrd.split(`$`);
2816
2758
  obj[`${_name}`] = obj[`${_name}s`][0] ?? ``;
2817
2759
  }
@@ -2819,11 +2761,7 @@ const headerConvert = _dosObj => {
2819
2761
 
2820
2762
  // デフォルト曲名表示の表示位置調整
2821
2763
  obj.titlepos = [[0, 0], [0, 0]];
2822
- if (hasVal(_dosObj.titlepos)) {
2823
- _dosObj.titlepos.split(`$`).forEach((pos, j) => {
2824
- obj.titlepos[j] = pos.split(`,`).map(x => parseFloat(x));
2825
- });
2826
- }
2764
+ _dosObj.titlepos?.split(`$`).forEach((pos, j) => obj.titlepos[j] = pos.split(`,`).map(x => parseFloat(x)));
2827
2765
 
2828
2766
  // タイトル文字のアニメーション設定
2829
2767
  obj.titleAnimationName = [`leftToRight`];
@@ -2831,20 +2769,18 @@ const headerConvert = _dosObj => {
2831
2769
  obj.titleAnimationDelay = [0];
2832
2770
  obj.titleAnimationTimingFunction = [`ease`];
2833
2771
  obj.titleAnimationClass = [``];
2834
- if (hasVal(_dosObj.titleanimation)) {
2835
- _dosObj.titleanimation.split(`$`).forEach((pos, j) => {
2836
- const titleAnimation = pos.split(`,`);
2837
- obj.titleAnimationName[j] = setVal(titleAnimation[0], obj.titleAnimationName[0], C_TYP_STRING);
2838
- obj.titleAnimationDuration[j] = setVal(titleAnimation[1] / g_fps, obj.titleAnimationDuration[0], C_TYP_FLOAT);
2839
- obj.titleAnimationDelay[j] = setVal(titleAnimation[2] / g_fps, obj.titleAnimationDelay[0], C_TYP_FLOAT);
2840
- obj.titleAnimationTimingFunction[j] = setVal(titleAnimation[3], obj.titleAnimationName[3], C_TYP_STRING);
2841
- });
2842
- }
2843
- if (hasVal(_dosObj.titleanimationclass)) {
2844
- _dosObj.titleanimationclass.split(`$`).forEach((animationClass, j) => {
2845
- obj.titleAnimationClass[j] = animationClass ?? ``;
2846
- });
2847
- }
2772
+
2773
+ _dosObj.titleanimation?.split(`$`).forEach((pos, j) => {
2774
+ const titleAnimation = pos.split(`,`);
2775
+ obj.titleAnimationName[j] = setVal(titleAnimation[0], obj.titleAnimationName[0]);
2776
+ obj.titleAnimationDuration[j] = setVal(titleAnimation[1] / g_fps, obj.titleAnimationDuration[0], C_TYP_FLOAT);
2777
+ obj.titleAnimationDelay[j] = setVal(titleAnimation[2] / g_fps, obj.titleAnimationDelay[0], C_TYP_FLOAT);
2778
+ obj.titleAnimationTimingFunction[j] = setVal(titleAnimation[3], obj.titleAnimationName[3]);
2779
+ });
2780
+ _dosObj.titleanimationclass?.split(`$`).forEach((animationClass, j) => {
2781
+ obj.titleAnimationClass[j] = animationClass ?? ``;
2782
+ });
2783
+
2848
2784
  if (obj.titleAnimationName.length === 1) {
2849
2785
  g_titleLists.animation.forEach(pattern => {
2850
2786
  obj[`titleAnimation${pattern}`][1] = obj[`titleAnimation${pattern}`][0];
@@ -2855,13 +2791,13 @@ const headerConvert = _dosObj => {
2855
2791
  }
2856
2792
 
2857
2793
  // デフォルト曲名表示の複数行時の縦間隔
2858
- obj.titlelineheight = setVal(_dosObj.titlelineheight, ``, C_TYP_NUMBER);
2794
+ obj.titlelineheight = setIntVal(_dosObj.titlelineheight, ``);
2859
2795
 
2860
2796
  // フリーズアローの始点で通常矢印の判定を行うか(dotさんソース方式)
2861
- obj.frzStartjdgUse = setVal(_dosObj.frzStartjdgUse ?? g_presetObj.frzStartjdgUse, false, C_TYP_BOOLEAN);
2797
+ obj.frzStartjdgUse = setBoolVal(_dosObj.frzStartjdgUse ?? g_presetObj.frzStartjdgUse);
2862
2798
 
2863
2799
  // 譜面名に制作者名を付加するかどうかのフラグ
2864
- obj.makerView = setVal(_dosObj.makerView, false, C_TYP_BOOLEAN);
2800
+ obj.makerView = setBoolVal(_dosObj.makerView);
2865
2801
 
2866
2802
  // shuffleUse=group 時のみshuffle用配列を組み替える
2867
2803
  if (_dosObj.shuffleUse === `group`) {
@@ -2871,7 +2807,7 @@ const headerConvert = _dosObj => {
2871
2807
 
2872
2808
  // オプション利用可否設定
2873
2809
  g_canDisabledSettings.forEach(option => {
2874
- obj[`${option}Use`] = setVal(_dosObj[`${option}Use`] ?? g_presetObj.settingUse?.[option], true, C_TYP_BOOLEAN);
2810
+ obj[`${option}Use`] = setBoolVal(_dosObj[`${option}Use`] ?? g_presetObj.settingUse?.[option], true);
2875
2811
  });
2876
2812
 
2877
2813
  let interlockingErrorFlg = false;
@@ -2882,7 +2818,7 @@ const headerConvert = _dosObj => {
2882
2818
  const displayUse = (displayTempUse !== undefined ? displayTempUse.split(`,`) : [true, C_FLG_ON]);
2883
2819
 
2884
2820
  // displayUse -> ボタンの有効/無効, displaySet -> ボタンの初期値(ON/OFF)
2885
- obj[`${option}Use`] = setVal(displayUse[0], true, C_TYP_BOOLEAN);
2821
+ obj[`${option}Use`] = setBoolVal(displayUse[0], true);
2886
2822
  obj[`${option}Set`] = setVal(displayUse.length > 1 ? displayUse[1] :
2887
2823
  (obj[`${option}Use`] ? C_FLG_ON : C_FLG_OFF), ``, C_TYP_SWITCH);
2888
2824
  g_stateObj[`d_${option.toLowerCase()}`] = setVal(obj[`${option}Set`], C_FLG_ON, C_TYP_SWITCH);
@@ -2925,7 +2861,7 @@ const headerConvert = _dosObj => {
2925
2861
  }
2926
2862
 
2927
2863
  // 別キーパターンの使用有無
2928
- obj.transKeyUse = setVal(_dosObj.transKeyUse, true, C_TYP_BOOLEAN);
2864
+ obj.transKeyUse = setBoolVal(_dosObj.transKeyUse, true);
2929
2865
 
2930
2866
  // タイトル画面用・背景/マスクデータの分解 (下記すべてで1セット、改行区切り)
2931
2867
  // [フレーム数,階層,背景パス,class(CSSで別定義),X,Y,width,height,opacity,animationName,animationDuration]
@@ -2942,25 +2878,25 @@ const headerConvert = _dosObj => {
2942
2878
  });
2943
2879
 
2944
2880
  // 結果画面用のマスク透過設定
2945
- obj.masktitleButton = setVal(_dosObj.masktitleButton, false, C_TYP_BOOLEAN);
2881
+ obj.masktitleButton = setBoolVal(_dosObj.masktitleButton);
2946
2882
 
2947
2883
  // 結果画面用のマスク透過設定
2948
- obj.maskresultButton = setVal(_dosObj.maskresultButton, false, C_TYP_BOOLEAN);
2884
+ obj.maskresultButton = setBoolVal(_dosObj.maskresultButton);
2949
2885
 
2950
2886
  // color_dataの過去バージョン互換設定
2951
2887
  obj.colorDataType = _dosObj.colorDataType ?? ``;
2952
2888
 
2953
2889
  // リザルトモーションをDisplay:BackgroundのON/OFFと連動させるかどうかの設定
2954
- obj.resultMotionSet = setVal(_dosObj.resultMotionSet, true, C_TYP_BOOLEAN);
2890
+ obj.resultMotionSet = setBoolVal(_dosObj.resultMotionSet, true);
2955
2891
 
2956
2892
  // 譜面明細の使用可否
2957
- obj.scoreDetailUse = setVal(_dosObj.scoreDetailUse, true, C_TYP_BOOLEAN);
2893
+ obj.scoreDetailUse = setBoolVal(_dosObj.scoreDetailUse, true);
2958
2894
 
2959
2895
  // 判定位置をBackgroundのON/OFFと連動してリセットする設定
2960
- obj.jdgPosReset = setVal(_dosObj.jdgPosReset, true, C_TYP_BOOLEAN);
2896
+ obj.jdgPosReset = setBoolVal(_dosObj.jdgPosReset, true);
2961
2897
 
2962
2898
  // タイトル表示用コメント
2963
- const newlineTag = setVal(_dosObj.commentAutoBr, true, C_TYP_BOOLEAN) ? `<br>` : ``;
2899
+ const newlineTag = setBoolVal(_dosObj.commentAutoBr, true) ? `<br>` : ``;
2964
2900
  const tmpComment = (_dosObj[`commentVal${g_localeObj.val}`] ?? _dosObj.commentVal ?? ``).split(`\r\n`).join(`\n`);
2965
2901
  obj.commentVal = tmpComment.split(`\n`).join(newlineTag);
2966
2902
 
@@ -2972,16 +2908,16 @@ const headerConvert = _dosObj => {
2972
2908
  }
2973
2909
 
2974
2910
  // コメントの外部化設定
2975
- obj.commentExternal = setVal(_dosObj.commentExternal, false, C_TYP_BOOLEAN);
2911
+ obj.commentExternal = setBoolVal(_dosObj.commentExternal);
2976
2912
 
2977
2913
  // Reverse時の歌詞の自動反転制御
2978
2914
  obj.wordAutoReverse = _dosObj.wordAutoReverse ?? g_presetObj.wordAutoReverse ?? `auto`;
2979
2915
 
2980
2916
  // プレイサイズ(X方向)
2981
- obj.playingWidth = setVal(_dosObj.playingWidth, g_sWidth, C_TYP_NUMBER);
2917
+ obj.playingWidth = setIntVal(_dosObj.playingWidth, `default`);
2982
2918
 
2983
2919
  // プレイ左上位置(X座標)
2984
- obj.playingX = setVal(_dosObj.playingX, 0, C_TYP_NUMBER);
2920
+ obj.playingX = setIntVal(_dosObj.playingX);
2985
2921
 
2986
2922
  // プレイ中クレジットを表示しないエリアのサイズ(X方向)
2987
2923
  obj.customViewWidth = setVal(_dosObj.customViewWidth, 0, C_TYP_FLOAT);
@@ -3017,16 +2953,14 @@ const headerConvert = _dosObj => {
3017
2953
  * 曲名(1行)の取得
3018
2954
  * @param {string} _musicName
3019
2955
  */
3020
- const getMusicNameSimple = _musicName => {
3021
- return _musicName.split(`<br>`).join(` `).split(`<nbr>`).join(``).split(`<dbr>`).join(` `);
3022
- };
2956
+ const getMusicNameSimple = _musicName => replaceStr(_musicName, g_escapeStr.musicNameSimple);
3023
2957
 
3024
2958
  /**
3025
2959
  * 曲名(複数行)の取得
3026
2960
  * @param {string} _musicName
3027
2961
  */
3028
2962
  const getMusicNameMultiLine = _musicName => {
3029
- const tmpName = _musicName.split(`<nbr>`).join(`<br>`).split(`<dbr>`).join(`<br>`).split(`<br>`);
2963
+ const tmpName = replaceStr(_musicName, g_escapeStr.musicNameMultiLine).split(`<br>`);
3030
2964
  return tmpName.length === 1 ? [tmpName[0], ``] : tmpName;
3031
2965
  };
3032
2966
 
@@ -3050,9 +2984,7 @@ const updateImgType = _imgType => {
3050
2984
  * ゲージ設定リストへの追加
3051
2985
  * @param {object} _obj
3052
2986
  */
3053
- const addGaugeFulls = _obj => {
3054
- _obj.map(key => g_gaugeOptionObj.customFulls[key] = false);
3055
- };
2987
+ const addGaugeFulls = _obj => _obj.map(key => g_gaugeOptionObj.customFulls[key] = false);
3056
2988
 
3057
2989
  /**
3058
2990
  * 矢印・フリーズアロー色のデータ変換
@@ -3101,19 +3033,18 @@ const resetBaseColorList = (_baseObj, _dosObj, { scoreId = `` } = {}) => {
3101
3033
  _baseObj[_frzInit].length : firstFrzColors.length;
3102
3034
  for (let k = 0; k < baseLength; k++) {
3103
3035
  currentFrzColors[k] = setVal(firstFrzColors[k],
3104
- _baseObj.defaultFrzColorUse ? _baseObj[_frzInit][k] : obj[`${_name}Str`][j], C_TYP_STRING);
3036
+ _baseObj.defaultFrzColorUse ? _baseObj[_frzInit][k] : obj[`${_name}Str`][j]);
3105
3037
  }
3106
3038
 
3107
- Object.keys(_baseObj.dfColorgrdSet).forEach(type => {
3039
+ Object.keys(_baseObj.dfColorgrdSet).forEach(type =>
3108
3040
  [obj[`${_frzName}${type}`][j], obj[`${_frzName}Str${type}`][j], obj[`${_frzName}Org${type}`][j]] =
3109
- setColorList(tmpFrzColors[j], currentFrzColors, _baseObj[_frzInit].length, {
3110
- _defaultColorgrd: _baseObj.dfColorgrdSet[type],
3111
- _colorCdPaddingUse: _baseObj.colorCdPaddingUse,
3112
- _defaultFrzColorUse: _baseObj.defaultFrzColorUse,
3113
- _objType: `frz`,
3114
- _shadowFlg: pattern === `Shadow`,
3115
- });
3116
- });
3041
+ setColorList(tmpFrzColors[j], currentFrzColors, _baseObj[_frzInit].length, {
3042
+ _defaultColorgrd: _baseObj.dfColorgrdSet[type],
3043
+ _colorCdPaddingUse: _baseObj.colorCdPaddingUse,
3044
+ _defaultFrzColorUse: _baseObj.defaultFrzColorUse,
3045
+ _objType: `frz`,
3046
+ _shadowFlg: pattern === `Shadow`,
3047
+ }));
3117
3048
  }
3118
3049
 
3119
3050
  obj[`${_name}Default`] = obj[_name].concat();
@@ -3166,7 +3097,7 @@ const setColorList = (_data, _colorInit, _colorInitLength,
3166
3097
  colorList = colorStr.concat();
3167
3098
 
3168
3099
  for (let j = 0; j < colorList.length; j++) {
3169
- const tmpSetColorOrg = colorStr[j].replace(/0x/g, `#`).split(`:`);
3100
+ const tmpSetColorOrg = colorStr[j].replaceAll(`0x`, `#`).split(`:`);
3170
3101
  const hasColor = tmpSetColorOrg.some(tmpColorOrg => {
3171
3102
  if (hasVal(tmpColorOrg) && (isColorCd(tmpColorOrg) || !hasAnglePointInfo(tmpColorOrg) || tmpColorOrg === `Default`)) {
3172
3103
  colorOrg[j] = colorCdPadding(_colorCdPaddingUse, colorToHex(tmpColorOrg));
@@ -3397,8 +3328,7 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList.split(`,`) }
3397
3328
  if (_dosObj[keyheader] !== undefined) {
3398
3329
  const tmps = _dosObj[keyheader].split(`$`);
3399
3330
  for (let k = 0; k < tmps.length; k++) {
3400
- g_keyObj[`${keyheader}_${k}`] = setVal(g_keyObj[`${_name}${tmps[k]}`],
3401
- setVal(tmps[k], ``, _type), C_TYP_STRING);
3331
+ g_keyObj[`${keyheader}_${k}`] = setVal(g_keyObj[`${_name}${tmps[k]}`], setVal(tmps[k], ``, _type));
3402
3332
  }
3403
3333
  }
3404
3334
  };
@@ -3453,6 +3383,9 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList.split(`,`) }
3453
3383
  // キーの名前 (keyNameX)
3454
3384
  g_keyObj[`keyName${newKey}`] = _dosObj[`keyName${newKey}`] ?? newKey;
3455
3385
 
3386
+ // キーの最小横幅 (minWidthX)
3387
+ g_keyObj[`minWidth${newKey}`] = _dosObj[`minWidth${newKey}`] ?? g_keyObj.minWidthDefault;
3388
+
3456
3389
  // 矢印色パターン (colorX_Y)
3457
3390
  tmpMinPatterns = newKeyMultiParam(newKey, `color`, toNumber, {
3458
3391
  errCd: `E_0101`,
@@ -3474,13 +3407,13 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList.split(`,`) }
3474
3407
  for (let k = 0; k < tmpDivs.length; k++) {
3475
3408
  tmpDivPtn = tmpDivs[k].split(`,`);
3476
3409
 
3477
- if (setVal(tmpDivPtn[0], -1, C_TYP_NUMBER) !== -1) {
3478
- g_keyObj[`div${newKey}_${k}`] = setVal(tmpDivPtn[0], g_keyObj[`chara${newKey}_0`].length, C_TYP_NUMBER);
3410
+ if (setIntVal(tmpDivPtn[0], -1) !== -1) {
3411
+ g_keyObj[`div${newKey}_${k}`] = setIntVal(tmpDivPtn[0], g_keyObj[`chara${newKey}_0`].length);
3479
3412
  } else if (g_keyObj[`div${tmpDivPtn[0]}`] !== undefined) {
3480
3413
  // 既定キーパターンが指定された場合、存在すればその値を適用
3481
3414
  g_keyObj[`div${newKey}_${k}`] = g_keyObj[`div${tmpDivPtn[0]}`];
3482
- g_keyObj[`divMax${newKey}_${k}`] = setVal(g_keyObj[`divMax${tmpDivPtn[0]}`], undefined, C_TYP_NUMBER);
3483
- } else if (setVal(g_keyObj[`div${newKey}_${k}`], -1, C_TYP_NUMBER) !== -1) {
3415
+ g_keyObj[`divMax${newKey}_${k}`] = setIntVal(g_keyObj[`divMax${tmpDivPtn[0]}`], undefined);
3416
+ } else if (setIntVal(g_keyObj[`div${newKey}_${k}`], -1) !== -1) {
3484
3417
  // すでに定義済みの場合はスキップ
3485
3418
  continue;
3486
3419
  } else if (g_keyObj[`chara${newKey}_0`] !== undefined) {
@@ -3615,11 +3548,8 @@ const titleInit = _ => {
3615
3548
  const titlegrd2 = g_headerObj.titlegrds[1] || titlegrd1;
3616
3549
 
3617
3550
  const titlegrds = [];
3618
- [titlegrd1, titlegrd2].forEach((titlegrd, j) => {
3619
- titlegrds[j] = makeColorGradation(titlegrd, {
3620
- _defaultColorgrd: false, _objType: `titleMusic`,
3621
- });
3622
- });
3551
+ [titlegrd1, titlegrd2].forEach((titlegrd, j) =>
3552
+ titlegrds[j] = makeColorGradation(titlegrd, { _defaultColorgrd: false, _objType: `titleMusic` }));
3623
3553
 
3624
3554
  let titlefontsize = 64;
3625
3555
  for (let j = 0; j < g_headerObj.musicTitleForView.length; j++) {
@@ -3630,8 +3560,8 @@ const titleInit = _ => {
3630
3560
 
3631
3561
  // 変数 titlesize の定義 (使用例: |titlesize=40$20|)
3632
3562
  const titlefontsizes = (g_headerObj.titlesize !== `` ? g_headerObj.titlesize.split(`$`).join(`,`).split(`,`) : [titlefontsize, titlefontsize]);
3633
- const titlefontsize1 = setVal(titlefontsizes[0], titlefontsize, C_TYP_NUMBER);
3634
- const titlefontsize2 = setVal(titlefontsizes[1], titlefontsize1, C_TYP_NUMBER);
3563
+ const titlefontsize1 = setIntVal(titlefontsizes[0], titlefontsize);
3564
+ const titlefontsize2 = setIntVal(titlefontsizes[1], titlefontsize1);
3635
3565
 
3636
3566
  // 変数 titlelineheight の定義 (使用例: |titlelineheight=50|)
3637
3567
  const titlelineheight = (g_headerObj.titlelineheight !== `` ? g_headerObj.titlelineheight - (titlefontsize2 + 10) : 0);
@@ -3651,7 +3581,7 @@ const titleInit = _ => {
3651
3581
  background: ${titlegrds[0]};
3652
3582
  background-clip: text;
3653
3583
  -webkit-background-clip: text;
3654
- -webkit-text-fill-color: rgba(255,255,255,0.0);
3584
+ color: rgba(255,255,255,0.0);
3655
3585
  ${txtAnimations[0]}
3656
3586
  " class="${g_headerObj.titleAnimationClass[0]}">
3657
3587
  ${g_headerObj.musicTitleForView[0]}
@@ -3664,7 +3594,7 @@ const titleInit = _ => {
3664
3594
  background: ${titlegrds[1]};
3665
3595
  background-clip: text;
3666
3596
  -webkit-background-clip: text;
3667
- -webkit-text-fill-color: rgba(255,255,255,0.0);
3597
+ color: rgba(255,255,255,0.0);
3668
3598
  ${txtAnimations[1]}
3669
3599
  " class="${g_headerObj.titleAnimationClass[1]}">
3670
3600
  ${g_headerObj.musicTitleForView[1] ?? ``}
@@ -3903,9 +3833,7 @@ const makeInfoWindow = (_text, _animationName = ``, _backColor = `#ccccff`) => {
3903
3833
  */
3904
3834
  const setWindowStyle = (_text, _bkColor, _textColor, _align = C_ALIGN_LEFT) => {
3905
3835
 
3906
- if (document.querySelector(`#lblWarning`) !== null) {
3907
- divRoot.removeChild(lblWarning);
3908
- }
3836
+ deleteDiv(divRoot, `lblWarning`);
3909
3837
 
3910
3838
  // ウィンドウ枠の行を取得するために一時的な枠を作成
3911
3839
  const tmplbl = createDivCss2Label(`lblTmpWarning`, _text, {
@@ -4026,12 +3954,11 @@ const optionInit = _ => {
4026
3954
  const setSpriteList = _settingList => {
4027
3955
  const optionWidth = (g_sWidth - 450) / 2;
4028
3956
  const spriteList = [];
4029
- _settingList.forEach(setting => {
3957
+ _settingList.forEach(setting =>
4030
3958
  spriteList[setting[0]] = createEmptySprite(optionsprite, `${setting[0]}Sprite`, {
4031
3959
  x: 25, y: setting[1] * C_LEN_SETLBL_HEIGHT + setting[2] + 20,
4032
3960
  w: optionWidth + setting[3], h: C_LEN_SETLBL_HEIGHT + setting[4],
4033
- });
4034
- });
3961
+ }));
4035
3962
  return spriteList;
4036
3963
  };
4037
3964
 
@@ -4040,9 +3967,7 @@ const setSpriteList = _settingList => {
4040
3967
  * @param {string} _sprite
4041
3968
  * @returns
4042
3969
  */
4043
- const createOptionSprite = _sprite => createEmptySprite(_sprite, `optionsprite`, {
4044
- x: (g_sWidth - 450) / 2, y: 65 + (g_sHeight - 500) / 2, w: 450, h: 325,
4045
- });
3970
+ const createOptionSprite = _sprite => createEmptySprite(_sprite, `optionsprite`, g_windowObj.optionSprite);
4046
3971
 
4047
3972
  /**
4048
3973
  * スライダー共通処理
@@ -4164,10 +4089,8 @@ const createOptionWindow = _sprite => {
4164
4089
  const createDifWindow = (_key = ``) => {
4165
4090
  g_currentPage = `difSelector`;
4166
4091
  setShortcutEvent(g_currentPage);
4167
- const difList = createEmptySprite(optionsprite, `difList`, { x: 165, y: 65, w: 280, h: 255, overflow: `auto` }, g_cssObj.settings_DifSelector);
4168
- const difCover = createEmptySprite(optionsprite, `difCover`, {
4169
- x: 25, y: 65, w: 140, h: 255, overflow: `auto`, opacity: 0.95
4170
- }, g_cssObj.settings_DifSelector);
4092
+ const difList = createEmptySprite(optionsprite, `difList`, g_windowObj.difList, g_cssObj.settings_DifSelector);
4093
+ const difCover = createEmptySprite(optionsprite, `difCover`, g_windowObj.difCover, g_cssObj.settings_DifSelector);
4171
4094
 
4172
4095
  // リスト再作成
4173
4096
  makeDifList(difList, _key);
@@ -4253,7 +4176,7 @@ const createOptionWindow = _sprite => {
4253
4176
  * @param {boolean} _graphUseFlg
4254
4177
  */
4255
4178
  const createScoreDetail = (_name, _graphUseFlg = true) => {
4256
- const detailObj = createEmptySprite(scoreDetail, `detail${_name}`, { w: 420, h: 230, visibility: `hidden` });
4179
+ const detailObj = createEmptySprite(scoreDetail, `detail${_name}`, g_windowObj.detailObj);
4257
4180
 
4258
4181
  if (_graphUseFlg) {
4259
4182
  const graphObj = document.createElement(`canvas`);
@@ -4283,10 +4206,7 @@ const createOptionWindow = _sprite => {
4283
4206
  }, g_cssObj.button_Mini)
4284
4207
  );
4285
4208
  g_stateObj.scoreDetailViewFlg = false;
4286
-
4287
- const scoreDetail = createEmptySprite(optionsprite, `scoreDetail`, {
4288
- x: 20, y: 90, w: 420, h: 230, visibility: `hidden`,
4289
- }, g_cssObj.settings_DifSelector);
4209
+ const scoreDetail = createEmptySprite(optionsprite, `scoreDetail`, g_windowObj.scoreDetail, g_cssObj.settings_DifSelector);
4290
4210
  const viewScText = _ => createScText(lnkScoreDetail, `ScoreDetail`, { targetLabel: `lnkScoreDetail`, x: -10 });
4291
4211
 
4292
4212
  /**
@@ -4300,7 +4220,7 @@ const createOptionWindow = _sprite => {
4300
4220
  setSetting(_val, `scoreDetail`);
4301
4221
  viewScText();
4302
4222
  $id(`detail${g_stateObj.scoreDetail}`).visibility = `visible`;
4303
- }
4223
+ };
4304
4224
 
4305
4225
  multiAppend(scoreDetail,
4306
4226
  createScoreDetail(`Speed`),
@@ -4530,9 +4450,8 @@ const createOptionWindow = _sprite => {
4530
4450
  * @param {string} _data
4531
4451
  * @param {object} _obj
4532
4452
  */
4533
- const makeDifInfoLabel = (_lbl, _data, { x = 130, y = 25, w = 125, h = 35, siz = C_SIZ_DIFSELECTOR, ...rest } = {}) => {
4534
- return createDivCss2Label(_lbl, _data, { x, y, w, h, siz, align: C_ALIGN_LEFT, ...rest });
4535
- }
4453
+ const makeDifInfoLabel = (_lbl, _data, { x = 130, y = 25, w = 125, h = 35, siz = C_SIZ_DIFSELECTOR, ...rest } = {}) =>
4454
+ createDivCss2Label(_lbl, _data, { x, y, w, h, siz, align: C_ALIGN_LEFT, ...rest });
4536
4455
 
4537
4456
  let printData = ``;
4538
4457
  for (let j = 0; j < g_detailObj.arrowCnt.length; j++) {
@@ -4910,7 +4829,7 @@ const createOptionWindow = _sprite => {
4910
4829
  const isNotSameKey = (g_keyObj.prevKey !== g_keyObj.currentKey);
4911
4830
 
4912
4831
  if (g_headerObj.dummyScoreNos !== undefined) {
4913
- g_stateObj.dummyId = setVal(g_headerObj.dummyScoreNos[g_stateObj.scoreId], ``, C_TYP_NUMBER);
4832
+ g_stateObj.dummyId = setIntVal(g_headerObj.dummyScoreNos[g_stateObj.scoreId], ``);
4914
4833
  }
4915
4834
  // 特殊キーフラグ
4916
4835
  g_stateObj.extraKeyFlg = g_headerObj.keyExtraList.includes(g_keyObj.currentKey);
@@ -4967,10 +4886,10 @@ const createOptionWindow = _sprite => {
4967
4886
  g_keyObj[`shuffle${keyCtrlPtn}`] = g_keyObj[`shuffle${keyCtrlPtn}_${g_keycons.shuffleGroupNum}`].concat();
4968
4887
  }
4969
4888
  if (g_headerObj.keyRetryDef === C_KEY_RETRY) {
4970
- g_headerObj.keyRetry = setVal(g_keyObj[`keyRetry${keyCtrlPtn}`], g_headerObj.keyRetryDef, C_TYP_NUMBER);
4889
+ g_headerObj.keyRetry = setIntVal(g_keyObj[`keyRetry${keyCtrlPtn}`], g_headerObj.keyRetryDef);
4971
4890
  }
4972
4891
  if (g_headerObj.keyTitleBackDef === C_KEY_TITLEBACK) {
4973
- g_headerObj.keyTitleBack = setVal(g_keyObj[`keyTitleBack${keyCtrlPtn}`], g_headerObj.keyTitleBackDef, C_TYP_NUMBER);
4892
+ g_headerObj.keyTitleBack = setIntVal(g_keyObj[`keyTitleBack${keyCtrlPtn}`], g_headerObj.keyTitleBackDef);
4974
4893
  }
4975
4894
  }
4976
4895
 
@@ -5423,9 +5342,7 @@ const createSettingsDisplayWindow = _sprite => {
5423
5342
  ];
5424
5343
 
5425
5344
  // 設定毎に個別のスプライトを作成し、その中にラベル・ボタン類を配置
5426
- const displaySprite = createEmptySprite(optionsprite, `displaySprite`, {
5427
- x: 25, y: 30, w: (g_sWidth - 450) / 2, h: C_LEN_SETLBL_HEIGHT * 5,
5428
- });
5345
+ const displaySprite = createEmptySprite(optionsprite, `displaySprite`, g_windowObj.displaySprite);
5429
5346
  const spriteList = setSpriteList(settingList);
5430
5347
 
5431
5348
  _sprite.appendChild(
@@ -5565,7 +5482,7 @@ const keyConfigInit = (_kcType = g_kcType) => {
5565
5482
  );
5566
5483
 
5567
5484
  // キーの一覧を表示
5568
- const keyconSprite = createEmptySprite(divRoot, `keyconSprite`, { y: 88 + (g_sHeight - 500) / 2, h: g_sHeight, overflow: `auto` });
5485
+ const keyconSprite = createEmptySprite(divRoot, `keyconSprite`, g_windowObj.keyconSprite);
5569
5486
  const tkObj = getKeyInfo();
5570
5487
  const [keyCtrlPtn, keyNum, posMax, divideCnt] =
5571
5488
  [tkObj.keyCtrlPtn, tkObj.keyNum, tkObj.posMax, tkObj.divideCnt];
@@ -5709,8 +5626,8 @@ const keyConfigInit = (_kcType = g_kcType) => {
5709
5626
 
5710
5627
  // 割り当て先のキー名を表示
5711
5628
  for (let k = 0; k < g_keyObj[`keyCtrl${keyCtrlPtn}`][j].length; k++) {
5712
- g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setVal(g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k], 0, C_TYP_NUMBER);
5713
- g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k] = setVal(g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k], 0, C_TYP_NUMBER);
5629
+ g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setIntVal(g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k]);
5630
+ g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k] = setIntVal(g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k]);
5714
5631
 
5715
5632
  keyconSprite.appendChild(
5716
5633
  createCss2Button(`keycon${j}_${k}`, g_kCd[g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k]], _ => {
@@ -6077,7 +5994,7 @@ const keyConfigInit = (_kcType = g_kcType) => {
6077
5994
  if (window.confirm(g_msgObj.keyResetConfirm)) {
6078
5995
  for (let j = 0; j < keyNum; j++) {
6079
5996
  for (let k = 0; k < g_keyObj[`keyCtrl${keyCtrlPtn}`][j].length; k++) {
6080
- g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setVal(g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k], 0, C_TYP_NUMBER);
5997
+ g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setIntVal(g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k]);
6081
5998
  document.querySelector(`#keycon${j}_${k}`).textContent = g_kCd[g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k]];
6082
5999
  changeKeyConfigColor(j, k, g_keyObj.currentPtn === -1 ? g_cssObj.keyconfig_Defaultkey : g_cssObj.title_base);
6083
6000
  }
@@ -6254,7 +6171,7 @@ const loadMusic = _ => {
6254
6171
  request.addEventListener(`load`, _ => {
6255
6172
  if (request.status >= 200 && request.status < 300) {
6256
6173
  const blobUrl = URL.createObjectURL(request.response);
6257
- createEmptySprite(divRoot, `loader`, { y: g_sHeight - 10, h: 10, backgroundColor: `#333333` });
6174
+ createEmptySprite(divRoot, `loader`, g_windowObj.loader);
6258
6175
  lblLoading.textContent = g_lblNameObj.pleaseWait;
6259
6176
  setAudio(blobUrl);
6260
6177
  } else {
@@ -6722,24 +6639,9 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6722
6639
  }
6723
6640
 
6724
6641
  // 矢印名からフリーズアロー名への変換
6725
- let frzName = g_keyObj[`chara${_keyCtrlPtn}`][j].replace(`leftdia`, `frzLdia`);
6726
- frzName = frzName.replace(`rightdia`, `frzRdia`);
6727
- frzName = frzName.replace(`left`, `frzLeft`);
6728
- frzName = frzName.replace(`down`, `frzDown`);
6729
- frzName = frzName.replace(`up`, `frzUp`);
6730
- frzName = frzName.replace(`right`, `frzRight`);
6731
- frzName = frzName.replace(`space`, `frzSpace`);
6732
- frzName = frzName.replace(`iyo`, `frzIyo`);
6733
- frzName = frzName.replace(`gor`, `frzGor`);
6734
- frzName = frzName.replace(`oni`, `foni`);
6735
-
6642
+ let frzName = replaceStr(g_keyObj[`chara${_keyCtrlPtn}`][j], g_escapeStr.frzName);
6736
6643
  if (frzName.indexOf(`frz`) === -1 && frzName.indexOf(`foni`) === -1) {
6737
- if ((frzName.startsWith(`s`)) || frzName.startsWith(`t`) ||
6738
- (frzName.startsWith(`a`) && !frzName.startsWith(`arrow`))) {
6739
- frzName = frzName.replace(frzName.slice(1), `frz${toCapitalize(frzName.slice(1))}`);
6740
- } else {
6741
- frzName = frzName.replace(frzName, `frz${toCapitalize(frzName)}`);
6742
- }
6644
+ frzName = frzName.replaceAll(frzName, `frz${toCapitalize(frzName)}`);
6743
6645
  }
6744
6646
 
6745
6647
  // フリーズアローデータの分解 (2つで1セット)
@@ -6844,7 +6746,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6844
6746
  const frame = calcFrame(tmpcssMotionData[0]);
6845
6747
  const arrowNum = parseFloat(tmpcssMotionData[1]);
6846
6748
  const styleUp = (tmpcssMotionData[2] === `none` ? `` : tmpcssMotionData[2]);
6847
- const styleDown = (tmpcssMotionData[3] === `none` ? `` : setVal(tmpcssMotionData[3], styleUp, C_TYP_STRING));
6749
+ const styleDown = (tmpcssMotionData[3] === `none` ? `` : setVal(tmpcssMotionData[3], styleUp));
6848
6750
 
6849
6751
  cssMotionData.push([frame, arrowNum, styleUp, styleDown]);
6850
6752
  });
@@ -6853,6 +6755,20 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6853
6755
  return [];
6854
6756
  };
6855
6757
 
6758
+ /**
6759
+ * 譜面データの優先順配列の取得
6760
+ * @param {string} _header
6761
+ * @param {string} _type
6762
+ * @param {number} _scoreNo
6763
+ * @returns
6764
+ */
6765
+ const getPriorityList = (_header, _type, _scoreNo) => [
6766
+ _dosObj[`${_header}${_type}${g_localeObj.val}${_scoreNo}_data`],
6767
+ _dosObj[`${_header}${_type}${g_localeObj.val}_data`],
6768
+ _dosObj[`${_header}${_type}${_scoreNo}_data`],
6769
+ _dosObj[`${_header}${_type}_data`]
6770
+ ];
6771
+
6856
6772
  /**
6857
6773
  * 歌詞データの分解
6858
6774
  * @param {string} _scoreNo
@@ -6861,14 +6777,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6861
6777
  const wordDataList = [];
6862
6778
  let wordReverseFlg = false;
6863
6779
  const divideCnt = getKeyInfo().divideCnt;
6864
-
6865
- const addDataList = (_type = ``) =>
6866
- wordDataList.push(
6867
- _dosObj[`word${_type}${g_localeObj.val}${_scoreNo}_data`],
6868
- _dosObj[`word${_type}${g_localeObj.val}_data`],
6869
- _dosObj[`word${_type}${_scoreNo}_data`],
6870
- _dosObj[`word${_type}_data`]
6871
- );
6780
+ const addDataList = (_type = ``) => wordDataList.push(...getPriorityList(`word`, _type, _scoreNo));
6872
6781
 
6873
6782
  if (g_stateObj.scroll !== `---`) {
6874
6783
  addDataList(`Alt`);
@@ -6933,7 +6842,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6933
6842
  checkDuplicatedObjects(wordData[tmpWordData[k]]);
6934
6843
 
6935
6844
  if (tmpWordData.length > 3 && tmpWordData.length < 6) {
6936
- tmpWordData[3] = setVal(tmpWordData[3], C_WOD_FRAME, C_TYP_NUMBER);
6845
+ tmpWordData[3] = setIntVal(tmpWordData[3], C_WOD_FRAME);
6937
6846
  wordData[tmpWordData[0]][addFrame].push(tmpWordData[1],
6938
6847
  escapeHtmlForEnabledTag(tmpWordData[2]), tmpWordData[3]);
6939
6848
  break;
@@ -6954,13 +6863,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6954
6863
  */
6955
6864
  const makeBackgroundData = (_header, _scoreNo) => {
6956
6865
  const dataList = [];
6957
- const addDataList = (_type = ``) =>
6958
- dataList.push(
6959
- _dosObj[`${_header}${_type}${g_localeObj.val}${_scoreNo}_data`],
6960
- _dosObj[`${_header}${_type}${g_localeObj.val}_data`],
6961
- _dosObj[`${_header}${_type}${_scoreNo}_data`],
6962
- _dosObj[`${_header}${_type}_data`]
6963
- );
6866
+ const addDataList = (_type = ``) => dataList.push(...getPriorityList(_header, _type, _scoreNo));
6964
6867
 
6965
6868
  if (g_stateObj.scroll !== `---`) {
6966
6869
  addDataList(`Alt`);
@@ -6981,13 +6884,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6981
6884
  */
6982
6885
  const makeBackgroundResultData = (_header, _scoreNo, _defaultHeader = ``) => {
6983
6886
  const dataList = [];
6984
- const addResultDataList = _headerType =>
6985
- dataList.push(
6986
- _dosObj[`${_headerType}${g_localeObj.val}${_scoreNo}_data`],
6987
- _dosObj[`${_headerType}${g_localeObj.val}_data`],
6988
- _dosObj[`${_headerType}${_scoreNo}_data`],
6989
- _dosObj[`${_headerType}_data`],
6990
- );
6887
+ const addResultDataList = _headerType => dataList.push(...getPriorityList(``, _headerType, _scoreNo));
6991
6888
  addResultDataList(_header);
6992
6889
  if (_defaultHeader !== ``) {
6993
6890
  addResultDataList(_defaultHeader);
@@ -7774,6 +7671,7 @@ const getArrowSettings = _ => {
7774
7671
  g_workObj.arrowRtn = copyArray2d(g_keyObj[`stepRtn${keyCtrlPtn}`]);
7775
7672
  g_workObj.keyCtrl = copyArray2d(g_keyObj[`keyCtrl${keyCtrlPtn}`]);
7776
7673
  g_workObj.diffList = [];
7674
+ g_workObj.mainEndTime = 0;
7777
7675
 
7778
7676
  const keyCtrlLen = g_workObj.keyCtrl.length;
7779
7677
  g_workObj.keyCtrlN = [...Array(keyCtrlLen)].map(_ => []);
@@ -8684,22 +8582,10 @@ const MainInit = _ => {
8684
8582
  * @param _j 矢印の位置
8685
8583
  */
8686
8584
  const checkKeyUpFunc = {
8687
-
8688
- frzOFF: (_j) => {
8689
- return g_workObj.keyHitFlg[_j].find(flg => flg);
8690
- },
8691
-
8692
- frzON: (_j) => {
8693
- return true;
8694
- },
8695
-
8696
- dummyFrzOFF: (_j) => {
8697
- return true;
8698
- },
8699
-
8700
- dummyFrzON: (_j) => {
8701
- return true;
8702
- },
8585
+ frzOFF: (_j) => g_workObj.keyHitFlg[_j].find(flg => flg),
8586
+ frzON: (_j) => true,
8587
+ dummyFrzOFF: (_j) => true,
8588
+ dummyFrzON: (_j) => true,
8703
8589
  };
8704
8590
 
8705
8591
  /**
@@ -9080,7 +8966,7 @@ const MainInit = _ => {
9080
8966
 
9081
8967
  g_workObj.lastFadeFrame[wordDepth] = currentFrame;
9082
8968
  g_workObj.wordFadeFrame[wordDepth] = (tmpObj.length > 2 ?
9083
- setVal(tmpObj[2], C_WOD_FRAME, C_TYP_NUMBER) : C_WOD_FRAME);
8969
+ setIntVal(tmpObj[2], C_WOD_FRAME) : C_WOD_FRAME);
9084
8970
 
9085
8971
  g_wordSprite.style.animationDuration = `${g_workObj.wordFadeFrame[wordDepth] / g_fps}s`;
9086
8972
  g_wordSprite.style.animationTimingFunction = `linear`;
@@ -9094,7 +8980,7 @@ const MainInit = _ => {
9094
8980
  } else if (/\[fontSize=\d+\]/.test(g_wordObj.wordDat)) {
9095
8981
 
9096
8982
  // フォントサイズ変更
9097
- const fontSize = setVal(g_wordObj.wordDat.match(/\d+/)[0], C_SIZ_MAIN, C_TYP_NUMBER);
8983
+ const fontSize = setIntVal(g_wordObj.wordDat.match(/\d+/)[0], C_SIZ_MAIN);
9098
8984
  g_wordSprite.style.fontSize = `${fontSize}px`;
9099
8985
 
9100
8986
  } else {
@@ -9133,7 +9019,8 @@ const MainInit = _ => {
9133
9019
  }
9134
9020
  resetKeyControl();
9135
9021
  clearTimeout(g_timeoutEvtId);
9136
- setTimeout(_ => resultInit(), 100);
9022
+ g_workObj.mainEndTime = thisTime;
9023
+ resultInit();
9137
9024
 
9138
9025
  } else if (g_workObj.lifeVal === 0 && g_workObj.lifeBorder === 0) {
9139
9026
 
@@ -9685,7 +9572,7 @@ const resultInit = _ => {
9685
9572
  // 曲時間制御変数
9686
9573
  let thisTime;
9687
9574
  let buffTime;
9688
- let resultStartTime = performance.now();
9575
+ let resultStartTime = g_workObj.mainEndTime > 0 ? g_workObj.mainEndTime : performance.now();
9689
9576
 
9690
9577
  if (g_stateObj.d_background === C_FLG_OFF && g_headerObj.resultMotionSet) {
9691
9578
  } else {
@@ -9728,12 +9615,8 @@ const resultInit = _ => {
9728
9615
  // タイトル文字描画
9729
9616
  divRoot.appendChild(getTitleDivLabel(`lblTitle`, g_lblNameObj.result, 0, 15, `settings_Title`));
9730
9617
 
9731
- const playDataWindow = createEmptySprite(divRoot, `playDataWindow`, {
9732
- x: g_sWidth / 2 - 225, y: 70 + (g_sHeight - 500) / 2, w: 450, h: 110,
9733
- }, g_cssObj.result_PlayDataWindow);
9734
- const resultWindow = createEmptySprite(divRoot, `resultWindow`, {
9735
- x: g_sWidth / 2 - 200, y: 185 + (g_sHeight - 500) / 2, w: 400, h: 210,
9736
- });
9618
+ const playDataWindow = createEmptySprite(divRoot, `playDataWindow`, g_windowObj.playDataWindow, g_cssObj.result_PlayDataWindow);
9619
+ const resultWindow = createEmptySprite(divRoot, `resultWindow`, g_windowObj.resultWindow);
9737
9620
 
9738
9621
  const playingArrows = g_resultObj.ii + g_resultObj.shakin +
9739
9622
  g_resultObj.matari + g_resultObj.shobon + g_resultObj.uwan +
@@ -9780,10 +9663,7 @@ const resultInit = _ => {
9780
9663
  }
9781
9664
 
9782
9665
  const keyCtrlPtn = `${g_keyObj.currentKey}_${g_keyObj.currentPtn}`;
9783
- let transKeyData = ``;
9784
- if (hasVal(g_keyObj[`transKey${keyCtrlPtn}`])) {
9785
- transKeyData = `(` + g_keyObj[`transKey${keyCtrlPtn}`] + `)`;
9786
- }
9666
+ const transKeyData = hasVal(g_keyObj[`transKey${keyCtrlPtn}`]) ? `(` + g_keyObj[`transKey${keyCtrlPtn}`] + `)` : ``;
9787
9667
 
9788
9668
  /**
9789
9669
  * プレイスタイルのカスタム有無
@@ -10012,7 +9892,7 @@ const resultInit = _ => {
10012
9892
 
10013
9893
  // Twitter用リザルト
10014
9894
  // スコアを上塗りする可能性があるため、カスタムイベント後に配置
10015
- const hashTag = (g_headerObj.hashTag !== undefined ? ` ${g_headerObj.hashTag}` : ``);
9895
+ const hashTag = (hasVal(g_headerObj.hashTag) ? ` ${g_headerObj.hashTag}` : ``);
10016
9896
  let tweetDifData = `${getKeyName(g_headerObj.keyLabels[g_stateObj.scoreId])}${transKeyData}${getStgDetailName('k-')}${g_headerObj.difLabels[g_stateObj.scoreId]}${assistFlg}`;
10017
9897
  if (g_stateObj.shuffle !== `OFF`) {
10018
9898
  tweetDifData += `:${getShuffleName()}`;
@@ -10027,18 +9907,19 @@ const resultInit = _ => {
10027
9907
  tweetMaxCombo += `-${g_resultObj.fmaxCombo}`;
10028
9908
  }
10029
9909
 
10030
- let tweetResultTmp = g_headerObj.resultFormat.split(`[hashTag]`).join(`${hashTag}`)
10031
- .split(`[musicTitle]`).join(`${musicTitle}`)
10032
- .split(`[keyLabel]`).join(`${tweetDifData}`)
10033
- .split(`[maker]`).join(`${g_headerObj.tuning}`)
10034
- .split(`[rank]`).join(`${rankMark}`)
10035
- .split(`[score]`).join(`${g_resultObj.score}`)
10036
- .split(`[playStyle]`).join(`${playStyleData}`)
10037
- .split(`[arrowJdg]`).join(`${g_resultObj.ii}-${g_resultObj.shakin}-${g_resultObj.matari}-${g_resultObj.shobon}-${g_resultObj.uwan}`)
10038
- .split(`[frzJdg]`).join(tweetFrzJdg)
10039
- .split(`[maxCombo]`).join(tweetMaxCombo)
10040
- .split(`[url]`).join(`${twiturl.toString()}`.replace(/[\t\n]/g, ``));
10041
-
9910
+ let tweetResultTmp = replaceStr(g_headerObj.resultFormat, [
9911
+ [`[hashTag]`, hashTag],
9912
+ [`[musicTitle]`, musicTitle],
9913
+ [`[keyLabel]`, tweetDifData],
9914
+ [`[maker]`, g_headerObj.tuning],
9915
+ [`[rank]`, rankMark],
9916
+ [`[score]`, g_resultObj.score],
9917
+ [`[playStyle]`, playStyleData],
9918
+ [`[arrowJdg]`, `${g_resultObj.ii}-${g_resultObj.shakin}-${g_resultObj.matari}-${g_resultObj.shobon}-${g_resultObj.uwan}`],
9919
+ [`[frzJdg]`, tweetFrzJdg],
9920
+ [`[maxCombo]`, tweetMaxCombo],
9921
+ [`[url]`, g_isLocal ? `` : `${twiturl.toString()}`.replace(/[\t\n]/g, ``)]
9922
+ ]);
10042
9923
  if (g_presetObj.resultVals !== undefined) {
10043
9924
  Object.keys(g_presetObj.resultVals).forEach(key => {
10044
9925
  tweetResultTmp = tweetResultTmp.split(`[${key}]`).join(g_resultObj[g_presetObj.resultVals[key]]);
@@ -10151,8 +10032,7 @@ const resultInit = _ => {
10151
10032
  g_scoreObj.maskResultFrameNum++;
10152
10033
  g_timeoutEvtResultId = setTimeout(_ => flowResultTimeline(), 1000 / g_fps - buffTime);
10153
10034
  };
10154
-
10155
- g_timeoutEvtResultId = setTimeout(_ => flowResultTimeline(), 1000 / g_fps);
10035
+ flowResultTimeline();
10156
10036
 
10157
10037
  // キー操作イベント(デフォルト)
10158
10038
  setShortcutEvent(g_currentPage);