danoniplus 26.7.0 → 27.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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/12
7
+ * Revised : 2022/03/27
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 26.7.0`;
12
- const g_revisedDate = `2022/03/12`;
11
+ const g_version = `Ver 27.2.0`;
12
+ const g_revisedDate = `2022/03/27`;
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
  }
@@ -1028,6 +965,24 @@ const createImg = (_id, _imgPath, _x, _y, _width, _height) => {
1028
965
  return div;
1029
966
  };
1030
967
 
968
+ /**
969
+ * ColorPickerの作成
970
+ * @param {string} _id
971
+ * @param {string} _color
972
+ * @param {object} _obj
973
+ * @returns
974
+ */
975
+ const createColorPicker = (_parentObj, _id, { x = 0, y = 0 } = {}) => {
976
+ const picker = document.createElement(`input`);
977
+ picker.setAttribute(`type`, `color`);
978
+ picker.id = _id;
979
+ picker.style.left = `${x}px`;
980
+ picker.style.top = `${y}px`;
981
+ picker.style.position = `absolute`;
982
+ _parentObj.appendChild(picker);
983
+ return picker;
984
+ };
985
+
1031
986
  /**
1032
987
  * 色付きオブジェクトの作成 (拡張属性対応)
1033
988
  * @param {string} _id
@@ -1146,6 +1101,17 @@ const deleteChildspriteAll = _parentObjName => {
1146
1101
  }
1147
1102
  };
1148
1103
 
1104
+ /**
1105
+ * div要素の削除
1106
+ * @param {object} _parentId
1107
+ * @param {string} _idName
1108
+ */
1109
+ const deleteDiv = (_parentId, _idName) => {
1110
+ if (document.getElementById(_idName) !== null) {
1111
+ _parentId.removeChild(document.getElementById(_idName));
1112
+ }
1113
+ };
1114
+
1149
1115
  /**
1150
1116
  * ボタンの作成 (CSS版・拡張属性対応)
1151
1117
  * @param {string} _id
@@ -1162,7 +1128,6 @@ const createCss2Button = (_id, _text, _func = _ => true, { x = 0, y = g_sHeight
1162
1128
  div.classList.add(`button_common`, ..._classes);
1163
1129
  div.innerHTML = _text;
1164
1130
  div.title = title;
1165
- div.ontouchstart = ``;
1166
1131
 
1167
1132
  const style = div.style;
1168
1133
  style.textAlign = align;
@@ -1185,13 +1150,13 @@ const createCss2Button = (_id, _text, _func = _ => true, { x = 0, y = g_sHeight
1185
1150
 
1186
1151
  // ボタンを押したときの動作
1187
1152
  const lsnrkey = g_handler.addListener(div, `click`, evt => {
1188
- if (!setVal(g_btnDeleteFlg[_id], false, C_TYP_BOOLEAN)) {
1153
+ if (!setBoolVal(g_btnDeleteFlg[_id])) {
1189
1154
  _func(evt);
1190
1155
  }
1191
1156
  if (typeof g_btnAddFunc[_id] === C_TYP_FUNCTION) {
1192
1157
  g_btnAddFunc[_id](evt, _func, resetFunc);
1193
1158
  }
1194
- if (!setVal(g_btnDeleteFlg[_id], false, C_TYP_BOOLEAN)) {
1159
+ if (!setBoolVal(g_btnDeleteFlg[_id])) {
1195
1160
  resetFunc(evt);
1196
1161
  }
1197
1162
  });
@@ -1199,7 +1164,7 @@ const createCss2Button = (_id, _text, _func = _ => true, { x = 0, y = g_sHeight
1199
1164
  // 右クリック時の処理
1200
1165
  div.oncontextmenu = evt => {
1201
1166
  if (typeof cxtFunc === C_TYP_FUNCTION) {
1202
- if (!setVal(g_cxtDeleteFlg[_id], false, C_TYP_BOOLEAN)) {
1167
+ if (!setBoolVal(g_cxtDeleteFlg[_id])) {
1203
1168
  cxtFunc(evt);
1204
1169
  }
1205
1170
  if (typeof g_cxtAddFunc[_id] === C_TYP_FUNCTION) {
@@ -1278,8 +1243,7 @@ const clearWindow = (_redrawFlg = false, _customDisplayName = ``) => {
1278
1243
  // レイヤー情報取得
1279
1244
  const layer0 = document.querySelector(`#layer0`);
1280
1245
  const l0ctx = layer0.getContext(`2d`);
1281
-
1282
- const C_MARGIN = 0;
1246
+ layer0.width = g_sWidth;
1283
1247
 
1284
1248
  // 線画、図形をクリア
1285
1249
  l0ctx.clearRect(0, 0, g_sWidth, g_sHeight);
@@ -1287,24 +1251,26 @@ const clearWindow = (_redrawFlg = false, _customDisplayName = ``) => {
1287
1251
  if (document.querySelector(`#layer1`) !== null) {
1288
1252
  const layer1 = document.querySelector(`#layer1`);
1289
1253
  const l1ctx = layer1.getContext(`2d`);
1254
+ layer1.width = g_sWidth;
1290
1255
  l1ctx.clearRect(0, 0, g_sWidth, g_sHeight);
1291
1256
 
1292
1257
  // 線画 (title-line)
1293
1258
  l1ctx.beginPath();
1294
1259
  l1ctx.strokeStyle = `#cccccc`;
1295
- l1ctx.moveTo(C_MARGIN, C_MARGIN);
1296
- l1ctx.lineTo(g_sWidth - C_MARGIN, C_MARGIN);
1260
+ l1ctx.moveTo(0, 0);
1261
+ l1ctx.lineTo(layer1.width, 0);
1297
1262
  l1ctx.stroke();
1298
1263
 
1299
1264
  l1ctx.beginPath();
1300
1265
  l1ctx.strokeStyle = `#cccccc`;
1301
- l1ctx.moveTo(C_MARGIN, g_sHeight - C_MARGIN);
1302
- l1ctx.lineTo(g_sWidth - C_MARGIN, g_sHeight - C_MARGIN);
1266
+ l1ctx.moveTo(0, g_sHeight);
1267
+ l1ctx.lineTo(layer1.width, g_sHeight);
1303
1268
  l1ctx.stroke();
1304
1269
  }
1305
1270
  if (document.querySelector(`#layer2`) !== null) {
1306
1271
  const layer2 = document.querySelector(`#layer2`);
1307
1272
  const l2ctx = layer2.getContext(`2d`);
1273
+ layer2.width = g_sWidth;
1308
1274
  l2ctx.clearRect(0, 0, g_sWidth, g_sHeight);
1309
1275
  }
1310
1276
  }
@@ -1356,17 +1322,14 @@ const drawDefaultBackImage = _key => {
1356
1322
  * @param {object} _obj
1357
1323
  */
1358
1324
  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) {
1325
+ let tmpInnerHTML = `<img src=${_obj.path} class="${_obj.class}" style="position:absolute;left:${_obj.left}px;top:${_obj.top}px`;
1326
+ if (_obj.width > 0) {
1362
1327
  tmpInnerHTML += `;width:${_obj.width}px`;
1363
1328
  }
1364
- if (_obj.height !== `` && setVal(_obj.height, 0, C_TYP_NUMBER) > 0) {
1329
+ if (setIntVal(_obj.height) > 0) {
1365
1330
  tmpInnerHTML += `;height:${_obj.height}px`;
1366
1331
  }
1367
- tmpInnerHTML += `;animation-name:${_obj.animationName}
1368
- ;animation-duration:${_obj.animationDuration}s
1369
- ;opacity:${_obj.opacity}">`;
1332
+ tmpInnerHTML += `;animation-name:${_obj.animationName};animation-duration:${_obj.animationDuration}s;opacity:${_obj.opacity}">`;
1370
1333
  return tmpInnerHTML;
1371
1334
  };
1372
1335
 
@@ -1375,11 +1338,10 @@ const makeSpriteImage = _obj => {
1375
1338
  * @param {object} _obj
1376
1339
  */
1377
1340
  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`;
1341
+ let tmpInnerHTML = `<span class="${_obj.class}" style="display:inline-block;position:absolute;left:${_obj.left}px;top:${_obj.top}px`;
1380
1342
 
1381
1343
  // この場合のwidthは font-size と解釈する
1382
- if (_obj.width !== 0 && _obj.width > 0) {
1344
+ if (_obj.width > 0) {
1383
1345
  tmpInnerHTML += `;font-size:${_obj.width}px`;
1384
1346
  }
1385
1347
 
@@ -1387,9 +1349,7 @@ const makeSpriteText = _obj => {
1387
1349
  if (_obj.height !== ``) {
1388
1350
  tmpInnerHTML += `;color:${_obj.height}`;
1389
1351
  }
1390
- tmpInnerHTML += `;animation-name:${_obj.animationName}
1391
- ;animation-duration:${_obj.animationDuration}s
1392
- ;opacity:${_obj.opacity}">${_obj.path}</span>`;
1352
+ tmpInnerHTML += `;animation-name:${_obj.animationName};animation-duration:${_obj.animationDuration}s;opacity:${_obj.opacity}">${_obj.path}</span>`;
1393
1353
  return tmpInnerHTML;
1394
1354
  };
1395
1355
 
@@ -1433,7 +1393,7 @@ const makeSpriteData = (_data, _calcFrame = _frame => _frame) => {
1433
1393
 
1434
1394
  // 値チェックとエスケープ処理
1435
1395
  let tmpFrame;
1436
- if (setVal(tmpSpriteData[0], 200, C_TYP_NUMBER) === 0) {
1396
+ if (setIntVal(tmpSpriteData[0], -1) === 0) {
1437
1397
  tmpFrame = 0;
1438
1398
  } else {
1439
1399
  tmpFrame = roundZero(_calcFrame(setVal(tmpSpriteData[0], 200, C_TYP_CALC)));
@@ -1444,15 +1404,15 @@ const makeSpriteData = (_data, _calcFrame = _frame => _frame) => {
1444
1404
  }
1445
1405
 
1446
1406
  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(文字列可)
1407
+ path: escapeHtml(tmpSpriteData[2] ?? ``, g_escapeStr.escapeCode), // 画像パス or テキスト
1408
+ class: escapeHtml(tmpSpriteData[3] ?? ``), // CSSクラス
1409
+ left: setVal(tmpSpriteData[4], 0, C_TYP_CALC), // X座標
1410
+ top: setVal(tmpSpriteData[5], 0, C_TYP_CALC), // Y座標
1411
+ width: setIntVal(tmpSpriteData[6]), // spanタグの場合は font-size
1412
+ height: escapeHtml(tmpSpriteData[7] ?? ``), // spanタグの場合は color(文字列可)
1453
1413
  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,
1414
+ animationName: escapeHtml(setVal(tmpSpriteData[9], C_DIS_NONE)),
1415
+ animationDuration: setIntVal(tmpSpriteData[10]) / g_fps,
1456
1416
  };
1457
1417
  if (g_headerObj.autoPreload) {
1458
1418
  if (checkImage(tmpObj.path)) {
@@ -1497,9 +1457,32 @@ const checkImage = _str => listMatching(_str, g_imgExtensions, { prefix: `[.]`,
1497
1457
  const getSpriteJumpFrame = _frames => {
1498
1458
  const jumpFrames = _frames.split(`:`);
1499
1459
  const jumpCnt = Math.floor(Math.random() * jumpFrames.length);
1500
- return setVal(Number(jumpFrames[jumpCnt]) - 1, 0, C_TYP_NUMBER);
1460
+ return setIntVal(Number(jumpFrames[jumpCnt]) - 1);
1501
1461
  };
1502
1462
 
1463
+ /**
1464
+ * 背景・マスクモーションの表示(共通処理)
1465
+ * @param {object} _spriteData
1466
+ * @param {string} _name
1467
+ * @param {boolean} _condition
1468
+ */
1469
+ const drawBaseSpriteData = (_spriteData, _name, _condition = true) => {
1470
+ const baseSprite = document.querySelector(`#${_name}Sprite${_spriteData.depth}`);
1471
+ if (_spriteData.command === ``) {
1472
+ if (_spriteData.depth === C_FLG_ALL) {
1473
+ for (let j = 0; j <= g_scoreObj[`${_name}MaxDepth`]; j++) {
1474
+ document.querySelector(`#${_name}Sprite${j}`).textContent = ``;
1475
+ }
1476
+ } else {
1477
+ baseSprite.textContent = ``;
1478
+ }
1479
+ } else {
1480
+ if (_condition) {
1481
+ baseSprite.innerHTML = _spriteData.htmlText;
1482
+ }
1483
+ }
1484
+ }
1485
+
1503
1486
  /**
1504
1487
  * 背景・マスクモーションの表示(タイトル・リザルト用)
1505
1488
  * @param {number} _frame
@@ -1513,31 +1496,19 @@ const drawSpriteData = (_frame, _displayName, _depthName) => {
1513
1496
 
1514
1497
  for (let j = 0; j < tmpObjs.length; j++) {
1515
1498
  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`]++;
1499
+ drawBaseSpriteData(tmpObj, spriteName, ![`[loop]`, `[jump]`].includes(tmpObj.command));
1500
+ if (tmpObj.command === `[loop]`) {
1501
+ // キーワード指定:ループ
1502
+ // 指定フレーム(class)へ移動する
1503
+ g_scoreObj[`${spriteName}LoopCount`]++;
1504
+ return getSpriteJumpFrame(tmpObj.jumpFrame);
1505
+
1506
+ } else if (tmpObj.command === `[jump]`) {
1507
+ // キーワード指定:フレームジャンプ
1508
+ // 指定回数以上のループ(maxLoop)があれば指定フレーム(jumpFrame)へ移動する
1509
+ if (g_scoreObj[`${spriteName}LoopCount`] >= Number(tmpObj.maxLoop)) {
1510
+ g_scoreObj[`${spriteName}LoopCount`] = 0;
1522
1511
  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
1512
  }
1542
1513
  }
1543
1514
  }
@@ -1549,25 +1520,8 @@ const drawSpriteData = (_frame, _displayName, _depthName) => {
1549
1520
  * @param {number} _frame
1550
1521
  * @param {string} _depthName
1551
1522
  */
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
- };
1523
+ const drawMainSpriteData = (_frame, _depthName) =>
1524
+ g_scoreObj[`${_depthName}Data`][_frame].forEach(tmpObj => drawBaseSpriteData(tmpObj, _depthName));
1571
1525
 
1572
1526
  /**
1573
1527
  * タイトル・リザルトモーションの描画
@@ -1751,12 +1705,8 @@ const transTimerToFrame = _str => {
1751
1705
 
1752
1706
  const initialControl = async () => {
1753
1707
 
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
1708
  const stage = document.querySelector(`#canvas-frame`);
1759
- const divRoot = createEmptySprite(stage, `divRoot`, { margin: `auto`, letterSpacing: `normal` });
1709
+ const divRoot = createEmptySprite(stage, `divRoot`, g_windowObj.divRoot);
1760
1710
 
1761
1711
  // 背景の表示
1762
1712
  if (document.querySelector(`#layer0`) !== null) {
@@ -1768,7 +1718,7 @@ const initialControl = async () => {
1768
1718
  l0ctx.fillStyle = grd;
1769
1719
  l0ctx.fillRect(0, 0, g_sWidth, g_sHeight);
1770
1720
  } else {
1771
- createEmptySprite(divRoot, `divBack`, { background: `linear-gradient(#000000, #222222)` });
1721
+ createEmptySprite(divRoot, `divBack`, g_windowObj.divBack);
1772
1722
  }
1773
1723
 
1774
1724
  // Now Loadingを表示
@@ -1778,15 +1728,8 @@ const initialControl = async () => {
1778
1728
  g_canLoadDifInfoFlg = true;
1779
1729
 
1780
1730
  // 譜面データの読み込みオプション
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
- }
1731
+ g_enableAmpersandSplit = setBoolVal(document.querySelector(`#enableAmpersandSplit`)?.value, true);
1732
+ g_enableDecodeURI = setBoolVal(document.querySelector(`#enableDecodeURI`)?.value);
1790
1733
 
1791
1734
  // 作品別ローカルストレージの読み込み
1792
1735
  loadLocalStorage();
@@ -1803,19 +1746,17 @@ const initialControl = async () => {
1803
1746
  // 共通設定ファイルの読込
1804
1747
  await loadScript2(`${settingRoot}danoni_setting${settingType}.js?${g_randTime}`, false);
1805
1748
  loadLegacySettingFunc();
1806
- if (document.querySelector(`#lblLoading`) !== null) {
1807
- divRoot.removeChild(document.querySelector(`#lblLoading`));
1808
- }
1749
+ deleteDiv(divRoot, `lblLoading`);
1809
1750
 
1810
1751
  // クエリで譜面番号が指定されていればセット
1811
- g_stateObj.scoreId = setVal(getQueryParamVal(`scoreId`), 0, C_TYP_NUMBER);
1752
+ g_stateObj.scoreId = setIntVal(getQueryParamVal(`scoreId`));
1812
1753
 
1813
1754
  // 譜面ヘッダーの読込
1814
1755
  Object.assign(g_headerObj, preheaderConvert(g_rootObj));
1815
1756
 
1816
1757
  // CSSファイル内のbackgroundを取得するために再描画
1817
1758
  if (document.querySelector(`#layer0`) === null) {
1818
- divRoot.removeChild(document.querySelector(`#divBack`));
1759
+ deleteDiv(divRoot, `divBack`);
1819
1760
  createEmptySprite(divRoot, `divBack`);
1820
1761
  } else if (!g_headerObj.defaultSkinFlg && !g_headerObj.customBackUse) {
1821
1762
  createEmptySprite(divRoot, `divBack`);
@@ -1840,6 +1781,21 @@ const initialControl = async () => {
1840
1781
  makeDedupliArray(g_rootObj.keyExtraList.split(`,`), g_headerObj.undefinedKeyLists) : g_headerObj.undefinedKeyLists),
1841
1782
  });
1842
1783
 
1784
+ // 自動横幅拡張設定
1785
+ if (g_headerObj.autoSpread) {
1786
+ const widthList = [g_sWidth, g_presetObj.autoMinWidth ?? g_keyObj.minWidth];
1787
+ g_headerObj.keyLists.forEach(key => widthList.push(g_keyObj[`minWidth${key}`] ?? g_keyObj.minWidthDefault));
1788
+
1789
+ g_sWidth = Math.max(...widthList);
1790
+ $id(`canvas-frame`).width = `${g_sWidth}px`;
1791
+ }
1792
+ if (g_headerObj.playingWidth === `default`) {
1793
+ g_headerObj.playingWidth = g_sWidth;
1794
+ }
1795
+
1796
+ // 可変ウィンドウサイズを更新
1797
+ updateWindowSiz();
1798
+
1843
1799
  // キー数情報を初期化
1844
1800
  g_keyObj.currentKey = g_headerObj.keyLabels[g_stateObj.scoreId];
1845
1801
  g_keyObj.currentPtn = 0;
@@ -1867,16 +1823,16 @@ const initialControl = async () => {
1867
1823
 
1868
1824
  if (termRoopCnts.length === 1) {
1869
1825
  // Pattern Bの場合
1870
- lastCnt = setVal(tmpPreloadImages[1], 1, C_TYP_NUMBER);
1871
- paddingLen = String(setVal(tmpPreloadImages[1], 1, C_TYP_STRING)).length;
1826
+ lastCnt = setIntVal(tmpPreloadImages[1], 1);
1827
+ paddingLen = String(setVal(tmpPreloadImages[1], 1)).length;
1872
1828
  } else {
1873
1829
  // 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;
1830
+ startCnt = setIntVal(termRoopCnts[0], 1);
1831
+ lastCnt = setIntVal(termRoopCnts[1], 1);
1832
+ paddingLen = String(setVal(termRoopCnts[1], 1)).length;
1877
1833
  }
1878
1834
  for (let k = startCnt; k <= lastCnt; k++) {
1879
- preloadFile(`image`, tmpPreloadImages[0].replace(/\*/g, String(k).padStart(paddingLen, `0`)));
1835
+ preloadFile(`image`, tmpPreloadImages[0].replaceAll(`*`, String(k).padStart(paddingLen, `0`)));
1880
1836
  }
1881
1837
  }
1882
1838
  });
@@ -1897,8 +1853,8 @@ const initialControl = async () => {
1897
1853
  if (g_loadObj.main) {
1898
1854
 
1899
1855
  // 譜面分割、譜面番号固定かどうかをチェック
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);
1856
+ g_stateObj.dosDivideFlg = setBoolVal(document.querySelector(`#externalDosDivide`)?.value ?? getQueryParamVal(`dosDivide`));
1857
+ g_stateObj.scoreLockFlg = setBoolVal(document.querySelector(`#externalDosLock`)?.value ?? getQueryParamVal(`dosLock`));
1902
1858
 
1903
1859
  for (let j = 1; j < g_headerObj.keyLabels.length; j++) {
1904
1860
 
@@ -2034,9 +1990,7 @@ const loadChartFile = async (_scoreId = g_stateObj.scoreId) => {
2034
1990
 
2035
1991
  await loadScript2(`${filename}?${Date.now()}`, false, charset);
2036
1992
  if (typeof externalDosInit === C_TYP_FUNCTION) {
2037
- if (document.querySelector(`#lblLoading`) !== null) {
2038
- divRoot.removeChild(document.querySelector(`#lblLoading`));
2039
- }
1993
+ deleteDiv(divRoot, `lblLoading`);
2040
1994
 
2041
1995
  // 外部データを読込(ファイルが見つからなかった場合は譜面追記をスキップ)
2042
1996
  externalDosInit();
@@ -2375,6 +2329,12 @@ const preheaderConvert = _dosObj => {
2375
2329
  // ヘッダー群の格納先
2376
2330
  const obj = {};
2377
2331
 
2332
+ // ウィンドウ位置の設定
2333
+ const align = _dosObj.windowAlign ?? g_presetObj.windowAlign;
2334
+ if (align !== undefined) {
2335
+ g_windowAlign[align]();
2336
+ }
2337
+
2378
2338
  obj.jsData = [];
2379
2339
 
2380
2340
  const setJsFiles = (_files, _defaultDir, _type = `custom`) => {
@@ -2394,21 +2354,21 @@ const preheaderConvert = _dosObj => {
2394
2354
 
2395
2355
  // 外部jsファイルの指定
2396
2356
  const tmpCustomjs = _dosObj.customjs ?? g_presetObj.customJs ?? C_JSF_CUSTOM;
2397
- setJsFiles(tmpCustomjs.split(`,`), C_DIR_JS);
2357
+ setJsFiles(tmpCustomjs.replaceAll(`*`, g_presetObj.customJs).split(`,`), C_DIR_JS);
2398
2358
 
2399
2359
  // 外部cssファイルの指定
2400
2360
  const tmpCustomcss = _dosObj.customcss ?? g_presetObj.customCss ?? ``;
2401
- setJsFiles(tmpCustomcss.split(`,`), C_DIR_CSS);
2361
+ setJsFiles(tmpCustomcss.replaceAll(`*`, g_presetObj.customCss).split(`,`), C_DIR_CSS);
2402
2362
 
2403
2363
  // デフォルト曲名表示、背景、Ready表示の利用有無
2404
2364
  g_titleLists.init.forEach(objName => {
2405
2365
  const objUpper = toCapitalize(objName);
2406
2366
  obj[`custom${objUpper}Use`] =
2407
- setVal(_dosObj[`custom${objUpper}Use`] ?? g_presetObj.customDesignUse?.[objName], false, C_TYP_BOOLEAN);
2367
+ setBoolVal(_dosObj[`custom${objUpper}Use`] ?? g_presetObj.customDesignUse?.[objName]);
2408
2368
  });
2409
2369
 
2410
2370
  // 背景・マスクモーションのパス指定方法を他の設定に合わせる設定
2411
- obj.syncBackPath = setVal(_dosObj.syncBackPath ?? g_presetObj.syncBackPath, false, C_TYP_BOOLEAN);
2371
+ obj.syncBackPath = setBoolVal(_dosObj.syncBackPath ?? g_presetObj.syncBackPath);
2412
2372
 
2413
2373
  return obj;
2414
2374
  };
@@ -2441,7 +2401,7 @@ const headerConvert = _dosObj => {
2441
2401
  obj.imgType[j] = {
2442
2402
  name: imgTypes[0],
2443
2403
  extension: imgTypes[1] || `svg`,
2444
- rotateEnabled: setVal(imgTypes[2], true, C_TYP_BOOLEAN),
2404
+ rotateEnabled: setBoolVal(imgTypes[2], true),
2445
2405
  flatStepHeight: setVal(imgTypes[3], C_ARW_WIDTH, C_TYP_FLOAT),
2446
2406
  };
2447
2407
  g_keycons.imgTypes[j] = (imgTypes[0] === `` ? `Original` : imgTypes[0]);
@@ -2467,6 +2427,15 @@ const headerConvert = _dosObj => {
2467
2427
  Object.assign(g_lblNameObj, g_lang_lblNameObj[g_localeObj.val], g_presetObj.lblName?.[g_localeObj.val]);
2468
2428
  Object.assign(g_msgObj, g_lang_msgObj[g_localeObj.val], g_presetObj.msg?.[g_localeObj.val]);
2469
2429
 
2430
+ // 自動横幅拡張設定
2431
+ obj.autoSpread = setBoolVal(_dosObj.autoSpread, g_presetObj.autoSpread ?? true);
2432
+
2433
+ // 横幅設定
2434
+ if (hasVal(_dosObj.windowWidth)) {
2435
+ g_sWidth = setIntVal(_dosObj.windowWidth, g_sWidth);
2436
+ $id(`canvas-frame`).width = `${g_sWidth}px`;
2437
+ }
2438
+
2470
2439
  // 曲名
2471
2440
  obj.musicTitles = [];
2472
2441
  obj.musicTitlesForView = [];
@@ -2521,13 +2490,13 @@ const headerConvert = _dosObj => {
2521
2490
  g_settings.speeds = [...Array((obj.maxSpeed - obj.minSpeed) * 20 + 1).keys()].map(i => obj.minSpeed + i / 20);
2522
2491
 
2523
2492
  // プレイ中のショートカットキー
2524
- obj.keyRetry = setVal(_dosObj.keyRetry, C_KEY_RETRY, C_TYP_NUMBER);
2493
+ obj.keyRetry = setIntVal(_dosObj.keyRetry, C_KEY_RETRY);
2525
2494
  obj.keyRetryDef = obj.keyRetry;
2526
- obj.keyTitleBack = setVal(_dosObj.keyTitleBack, C_KEY_TITLEBACK, C_TYP_NUMBER);
2495
+ obj.keyTitleBack = setIntVal(_dosObj.keyTitleBack, C_KEY_TITLEBACK);
2527
2496
  obj.keyTitleBackDef = obj.keyTitleBack;
2528
2497
 
2529
2498
  // フリーズアローの許容フレーム数設定
2530
- obj.frzAttempt = setVal(_dosObj.frzAttempt, C_FRM_FRZATTEMPT, C_TYP_NUMBER);
2499
+ obj.frzAttempt = setIntVal(_dosObj.frzAttempt, C_FRM_FRZATTEMPT);
2531
2500
 
2532
2501
  // 製作者表示
2533
2502
  if (hasVal(_dosObj.tuning)) {
@@ -2600,7 +2569,7 @@ const headerConvert = _dosObj => {
2600
2569
  obj.undefinedKeyLists = obj.keyLists.filter(key => g_keyObj[`chara${key}_0`] === undefined);
2601
2570
 
2602
2571
  // 譜面変更セレクターの利用有無
2603
- obj.difSelectorUse = (setVal(_dosObj.difSelectorUse, obj.keyLabels.length > 5, C_TYP_BOOLEAN));
2572
+ obj.difSelectorUse = (setBoolVal(_dosObj.difSelectorUse, obj.keyLabels.length > 5));
2604
2573
 
2605
2574
  // 初期速度の設定
2606
2575
  g_stateObj.speed = obj.initSpeeds[g_stateObj.scoreId];
@@ -2608,20 +2577,20 @@ const headerConvert = _dosObj => {
2608
2577
 
2609
2578
  // グラデーションのデフォルト中間色を設定
2610
2579
  divRoot.appendChild(createDivCss2Label(`dummyLabel`, ``, { pointerEvents: C_DIS_NONE }));
2611
- obj.baseBrightFlg = setVal(_dosObj.baseBright, checkLightOrDark(colorNameToCode(window.getComputedStyle(dummyLabel, ``).color)), C_TYP_BOOLEAN);
2580
+ obj.baseBrightFlg = setBoolVal(_dosObj.baseBright, checkLightOrDark(colorNameToCode(window.getComputedStyle(dummyLabel, ``).color)));
2612
2581
  const intermediateColor = obj.baseBrightFlg ? `#111111` : `#eeeeee`;
2613
2582
 
2614
2583
  // 矢印の色変化を常時グラデーションさせる設定
2615
2584
  obj.defaultColorgrd = [false, intermediateColor];
2616
2585
  if (hasVal(_dosObj.defaultColorgrd)) {
2617
2586
  obj.defaultColorgrd = _dosObj.defaultColorgrd.split(`,`);
2618
- obj.defaultColorgrd[0] = setVal(obj.defaultColorgrd[0], false, C_TYP_BOOLEAN);
2587
+ obj.defaultColorgrd[0] = setBoolVal(obj.defaultColorgrd[0]);
2619
2588
  obj.defaultColorgrd[1] = obj.defaultColorgrd[1] ?? intermediateColor;
2620
2589
  }
2621
2590
  g_rankObj.rankColorAllPerfect = intermediateColor;
2622
2591
 
2623
2592
  // カラーコードのゼロパディング有無設定
2624
- obj.colorCdPaddingUse = setVal(_dosObj.colorCdPaddingUse, false, C_TYP_BOOLEAN);
2593
+ obj.colorCdPaddingUse = setBoolVal(_dosObj.colorCdPaddingUse);
2625
2594
 
2626
2595
  // 最大ライフ
2627
2596
  obj.maxLifeVal = setVal(_dosObj.maxLifeVal, C_VAL_MAXLIFE, C_TYP_FLOAT);
@@ -2637,7 +2606,7 @@ const headerConvert = _dosObj => {
2637
2606
  });
2638
2607
 
2639
2608
  // フリーズアローのデフォルト色セットの利用有無 (true: 使用, false: 矢印色を優先してセット)
2640
- obj.defaultFrzColorUse = setVal(_dosObj.defaultFrzColorUse ?? g_presetObj.frzColors, true, C_TYP_BOOLEAN);
2609
+ obj.defaultFrzColorUse = setBoolVal(_dosObj.defaultFrzColorUse ?? g_presetObj.frzColors, true);
2641
2610
 
2642
2611
  // 矢印色変化に対応してフリーズアロー色を追随する範囲の設定
2643
2612
  // (defaultFrzColorUse=false時のみ)
@@ -2656,10 +2625,9 @@ const headerConvert = _dosObj => {
2656
2625
  }
2657
2626
 
2658
2627
  // 初期色情報
2628
+ const baseColor = (obj.baseBrightFlg ? `light` : `dark`);
2629
+ Object.assign(g_dfColorObj, g_dfColorBaseObj[baseColor]);
2659
2630
  Object.keys(g_dfColorObj).forEach(key => obj[key] = g_dfColorObj[key].concat());
2660
- if (obj.baseBrightFlg) {
2661
- Object.keys(g_dfColorLightObj).forEach(key => obj[key] = g_dfColorLightObj[key].concat());
2662
- }
2663
2631
  obj.frzColorDefault = [];
2664
2632
 
2665
2633
  // ダミー用初期矢印色
@@ -2738,7 +2706,7 @@ const headerConvert = _dosObj => {
2738
2706
  g_posObj.distY = g_sHeight - C_STEP_Y + g_posObj.stepYR;
2739
2707
  g_posObj.reverseStepY = g_posObj.distY - g_posObj.stepY - g_posObj.stepDiffY - C_ARW_WIDTH;
2740
2708
  g_posObj.arrowHeight = g_sHeight + g_posObj.stepYR - g_posObj.stepDiffY * 2;
2741
- obj.bottomWordSetFlg = setVal(_dosObj.bottomWordSet, false, C_TYP_BOOLEAN);
2709
+ obj.bottomWordSetFlg = setBoolVal(_dosObj.bottomWordSet);
2742
2710
 
2743
2711
  // 矢印・フリーズアロー判定位置補正
2744
2712
  g_diffObj.arrowJdgY = (isNaN(parseFloat(_dosObj.arrowJdgY)) ? 0 : parseFloat(_dosObj.arrowJdgY));
@@ -2755,12 +2723,10 @@ const headerConvert = _dosObj => {
2755
2723
  }
2756
2724
 
2757
2725
  // ハッシュタグ
2758
- if (hasVal(_dosObj.hashTag)) {
2759
- obj.hashTag = _dosObj.hashTag;
2760
- }
2726
+ obj.hashTag = setVal(_dosObj.hashTag, ``);
2761
2727
 
2762
2728
  // 自動プリロードの設定
2763
- obj.autoPreload = setVal(_dosObj.autoPreload, true, C_TYP_BOOLEAN);
2729
+ obj.autoPreload = setBoolVal(_dosObj.autoPreload, true);
2764
2730
  g_headerObj.autoPreload = obj.autoPreload;
2765
2731
 
2766
2732
  // 読込対象の画像を指定(rel:preload)と同じ
@@ -2777,11 +2743,11 @@ const headerConvert = _dosObj => {
2777
2743
 
2778
2744
  // デフォルトReady/リザルト表示の遅延時間設定
2779
2745
  [`ready`, `result`].forEach(objName => {
2780
- obj[`${objName}DelayFrame`] = setVal(_dosObj[`${objName}DelayFrame`], 0, C_TYP_NUMBER);
2746
+ obj[`${objName}DelayFrame`] = setIntVal(_dosObj[`${objName}DelayFrame`]);
2781
2747
  });
2782
2748
 
2783
2749
  // デフォルトReady表示のアニメーション時間設定
2784
- obj.readyAnimationFrame = setVal(_dosObj.readyAnimationFrame, 150, C_TYP_NUMBER);
2750
+ obj.readyAnimationFrame = setIntVal(_dosObj.readyAnimationFrame, 150);
2785
2751
 
2786
2752
  // デフォルトReady表示のアニメーション名
2787
2753
  obj.readyAnimationName = _dosObj.readyAnimationName ?? `leftToRightFade`;
@@ -2798,20 +2764,16 @@ const headerConvert = _dosObj => {
2798
2764
  // デフォルト曲名表示のフォント名
2799
2765
  // (使用例: |titlefont=Century,Meiryo UI|)
2800
2766
  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
- }
2767
+ _dosObj.titlefont?.split(`$`).forEach((font, j) => obj.titlefonts[j] = `'${(font.replaceAll(`,`, `', '`))}'`);
2768
+ if (obj.titlefonts[1] === undefined) {
2769
+ obj.titlefonts[1] = obj.titlefonts[0];
2808
2770
  }
2809
2771
 
2810
2772
  // デフォルト曲名表示, 背景矢印のグラデーション指定css
2811
2773
  g_titleLists.grdList.forEach(_name => {
2812
2774
  obj[`${_name}s`] = [];
2813
2775
  if (hasVal(_dosObj[_name])) {
2814
- const tmpTitlegrd = _dosObj[_name].replace(/,/g, `:`);
2776
+ const tmpTitlegrd = _dosObj[_name].replaceAll(`,`, `:`);
2815
2777
  obj[`${_name}s`] = tmpTitlegrd.split(`$`);
2816
2778
  obj[`${_name}`] = obj[`${_name}s`][0] ?? ``;
2817
2779
  }
@@ -2819,11 +2781,7 @@ const headerConvert = _dosObj => {
2819
2781
 
2820
2782
  // デフォルト曲名表示の表示位置調整
2821
2783
  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
- }
2784
+ _dosObj.titlepos?.split(`$`).forEach((pos, j) => obj.titlepos[j] = pos.split(`,`).map(x => parseFloat(x)));
2827
2785
 
2828
2786
  // タイトル文字のアニメーション設定
2829
2787
  obj.titleAnimationName = [`leftToRight`];
@@ -2831,20 +2789,18 @@ const headerConvert = _dosObj => {
2831
2789
  obj.titleAnimationDelay = [0];
2832
2790
  obj.titleAnimationTimingFunction = [`ease`];
2833
2791
  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
- }
2792
+
2793
+ _dosObj.titleanimation?.split(`$`).forEach((pos, j) => {
2794
+ const titleAnimation = pos.split(`,`);
2795
+ obj.titleAnimationName[j] = setVal(titleAnimation[0], obj.titleAnimationName[0]);
2796
+ obj.titleAnimationDuration[j] = setVal(titleAnimation[1] / g_fps, obj.titleAnimationDuration[0], C_TYP_FLOAT);
2797
+ obj.titleAnimationDelay[j] = setVal(titleAnimation[2] / g_fps, obj.titleAnimationDelay[0], C_TYP_FLOAT);
2798
+ obj.titleAnimationTimingFunction[j] = setVal(titleAnimation[3], obj.titleAnimationName[3]);
2799
+ });
2800
+ _dosObj.titleanimationclass?.split(`$`).forEach((animationClass, j) => {
2801
+ obj.titleAnimationClass[j] = animationClass ?? ``;
2802
+ });
2803
+
2848
2804
  if (obj.titleAnimationName.length === 1) {
2849
2805
  g_titleLists.animation.forEach(pattern => {
2850
2806
  obj[`titleAnimation${pattern}`][1] = obj[`titleAnimation${pattern}`][0];
@@ -2855,13 +2811,13 @@ const headerConvert = _dosObj => {
2855
2811
  }
2856
2812
 
2857
2813
  // デフォルト曲名表示の複数行時の縦間隔
2858
- obj.titlelineheight = setVal(_dosObj.titlelineheight, ``, C_TYP_NUMBER);
2814
+ obj.titlelineheight = setIntVal(_dosObj.titlelineheight, ``);
2859
2815
 
2860
2816
  // フリーズアローの始点で通常矢印の判定を行うか(dotさんソース方式)
2861
- obj.frzStartjdgUse = setVal(_dosObj.frzStartjdgUse ?? g_presetObj.frzStartjdgUse, false, C_TYP_BOOLEAN);
2817
+ obj.frzStartjdgUse = setBoolVal(_dosObj.frzStartjdgUse ?? g_presetObj.frzStartjdgUse);
2862
2818
 
2863
2819
  // 譜面名に制作者名を付加するかどうかのフラグ
2864
- obj.makerView = setVal(_dosObj.makerView, false, C_TYP_BOOLEAN);
2820
+ obj.makerView = setBoolVal(_dosObj.makerView);
2865
2821
 
2866
2822
  // shuffleUse=group 時のみshuffle用配列を組み替える
2867
2823
  if (_dosObj.shuffleUse === `group`) {
@@ -2871,7 +2827,7 @@ const headerConvert = _dosObj => {
2871
2827
 
2872
2828
  // オプション利用可否設定
2873
2829
  g_canDisabledSettings.forEach(option => {
2874
- obj[`${option}Use`] = setVal(_dosObj[`${option}Use`] ?? g_presetObj.settingUse?.[option], true, C_TYP_BOOLEAN);
2830
+ obj[`${option}Use`] = setBoolVal(_dosObj[`${option}Use`] ?? g_presetObj.settingUse?.[option], true);
2875
2831
  });
2876
2832
 
2877
2833
  let interlockingErrorFlg = false;
@@ -2882,7 +2838,7 @@ const headerConvert = _dosObj => {
2882
2838
  const displayUse = (displayTempUse !== undefined ? displayTempUse.split(`,`) : [true, C_FLG_ON]);
2883
2839
 
2884
2840
  // displayUse -> ボタンの有効/無効, displaySet -> ボタンの初期値(ON/OFF)
2885
- obj[`${option}Use`] = setVal(displayUse[0], true, C_TYP_BOOLEAN);
2841
+ obj[`${option}Use`] = setBoolVal(displayUse[0], true);
2886
2842
  obj[`${option}Set`] = setVal(displayUse.length > 1 ? displayUse[1] :
2887
2843
  (obj[`${option}Use`] ? C_FLG_ON : C_FLG_OFF), ``, C_TYP_SWITCH);
2888
2844
  g_stateObj[`d_${option.toLowerCase()}`] = setVal(obj[`${option}Set`], C_FLG_ON, C_TYP_SWITCH);
@@ -2925,7 +2881,7 @@ const headerConvert = _dosObj => {
2925
2881
  }
2926
2882
 
2927
2883
  // 別キーパターンの使用有無
2928
- obj.transKeyUse = setVal(_dosObj.transKeyUse, true, C_TYP_BOOLEAN);
2884
+ obj.transKeyUse = setBoolVal(_dosObj.transKeyUse, true);
2929
2885
 
2930
2886
  // タイトル画面用・背景/マスクデータの分解 (下記すべてで1セット、改行区切り)
2931
2887
  // [フレーム数,階層,背景パス,class(CSSで別定義),X,Y,width,height,opacity,animationName,animationDuration]
@@ -2942,25 +2898,25 @@ const headerConvert = _dosObj => {
2942
2898
  });
2943
2899
 
2944
2900
  // 結果画面用のマスク透過設定
2945
- obj.masktitleButton = setVal(_dosObj.masktitleButton, false, C_TYP_BOOLEAN);
2901
+ obj.masktitleButton = setBoolVal(_dosObj.masktitleButton);
2946
2902
 
2947
2903
  // 結果画面用のマスク透過設定
2948
- obj.maskresultButton = setVal(_dosObj.maskresultButton, false, C_TYP_BOOLEAN);
2904
+ obj.maskresultButton = setBoolVal(_dosObj.maskresultButton);
2949
2905
 
2950
2906
  // color_dataの過去バージョン互換設定
2951
2907
  obj.colorDataType = _dosObj.colorDataType ?? ``;
2952
2908
 
2953
2909
  // リザルトモーションをDisplay:BackgroundのON/OFFと連動させるかどうかの設定
2954
- obj.resultMotionSet = setVal(_dosObj.resultMotionSet, true, C_TYP_BOOLEAN);
2910
+ obj.resultMotionSet = setBoolVal(_dosObj.resultMotionSet, true);
2955
2911
 
2956
2912
  // 譜面明細の使用可否
2957
- obj.scoreDetailUse = setVal(_dosObj.scoreDetailUse, true, C_TYP_BOOLEAN);
2913
+ obj.scoreDetailUse = setBoolVal(_dosObj.scoreDetailUse, true);
2958
2914
 
2959
2915
  // 判定位置をBackgroundのON/OFFと連動してリセットする設定
2960
- obj.jdgPosReset = setVal(_dosObj.jdgPosReset, true, C_TYP_BOOLEAN);
2916
+ obj.jdgPosReset = setBoolVal(_dosObj.jdgPosReset, true);
2961
2917
 
2962
2918
  // タイトル表示用コメント
2963
- const newlineTag = setVal(_dosObj.commentAutoBr, true, C_TYP_BOOLEAN) ? `<br>` : ``;
2919
+ const newlineTag = setBoolVal(_dosObj.commentAutoBr, true) ? `<br>` : ``;
2964
2920
  const tmpComment = (_dosObj[`commentVal${g_localeObj.val}`] ?? _dosObj.commentVal ?? ``).split(`\r\n`).join(`\n`);
2965
2921
  obj.commentVal = tmpComment.split(`\n`).join(newlineTag);
2966
2922
 
@@ -2972,16 +2928,16 @@ const headerConvert = _dosObj => {
2972
2928
  }
2973
2929
 
2974
2930
  // コメントの外部化設定
2975
- obj.commentExternal = setVal(_dosObj.commentExternal, false, C_TYP_BOOLEAN);
2931
+ obj.commentExternal = setBoolVal(_dosObj.commentExternal);
2976
2932
 
2977
2933
  // Reverse時の歌詞の自動反転制御
2978
2934
  obj.wordAutoReverse = _dosObj.wordAutoReverse ?? g_presetObj.wordAutoReverse ?? `auto`;
2979
2935
 
2980
2936
  // プレイサイズ(X方向)
2981
- obj.playingWidth = setVal(_dosObj.playingWidth, g_sWidth, C_TYP_NUMBER);
2937
+ obj.playingWidth = setIntVal(_dosObj.playingWidth, `default`);
2982
2938
 
2983
2939
  // プレイ左上位置(X座標)
2984
- obj.playingX = setVal(_dosObj.playingX, 0, C_TYP_NUMBER);
2940
+ obj.playingX = setIntVal(_dosObj.playingX);
2985
2941
 
2986
2942
  // プレイ中クレジットを表示しないエリアのサイズ(X方向)
2987
2943
  obj.customViewWidth = setVal(_dosObj.customViewWidth, 0, C_TYP_FLOAT);
@@ -3048,9 +3004,7 @@ const updateImgType = _imgType => {
3048
3004
  * ゲージ設定リストへの追加
3049
3005
  * @param {object} _obj
3050
3006
  */
3051
- const addGaugeFulls = _obj => {
3052
- _obj.map(key => g_gaugeOptionObj.customFulls[key] = false);
3053
- };
3007
+ const addGaugeFulls = _obj => _obj.map(key => g_gaugeOptionObj.customFulls[key] = false);
3054
3008
 
3055
3009
  /**
3056
3010
  * 矢印・フリーズアロー色のデータ変換
@@ -3099,19 +3053,18 @@ const resetBaseColorList = (_baseObj, _dosObj, { scoreId = `` } = {}) => {
3099
3053
  _baseObj[_frzInit].length : firstFrzColors.length;
3100
3054
  for (let k = 0; k < baseLength; k++) {
3101
3055
  currentFrzColors[k] = setVal(firstFrzColors[k],
3102
- _baseObj.defaultFrzColorUse ? _baseObj[_frzInit][k] : obj[`${_name}Str`][j], C_TYP_STRING);
3056
+ _baseObj.defaultFrzColorUse ? _baseObj[_frzInit][k] : obj[`${_name}Str`][j]);
3103
3057
  }
3104
3058
 
3105
- Object.keys(_baseObj.dfColorgrdSet).forEach(type => {
3059
+ Object.keys(_baseObj.dfColorgrdSet).forEach(type =>
3106
3060
  [obj[`${_frzName}${type}`][j], obj[`${_frzName}Str${type}`][j], obj[`${_frzName}Org${type}`][j]] =
3107
- setColorList(tmpFrzColors[j], currentFrzColors, _baseObj[_frzInit].length, {
3108
- _defaultColorgrd: _baseObj.dfColorgrdSet[type],
3109
- _colorCdPaddingUse: _baseObj.colorCdPaddingUse,
3110
- _defaultFrzColorUse: _baseObj.defaultFrzColorUse,
3111
- _objType: `frz`,
3112
- _shadowFlg: pattern === `Shadow`,
3113
- });
3114
- });
3061
+ setColorList(tmpFrzColors[j], currentFrzColors, _baseObj[_frzInit].length, {
3062
+ _defaultColorgrd: _baseObj.dfColorgrdSet[type],
3063
+ _colorCdPaddingUse: _baseObj.colorCdPaddingUse,
3064
+ _defaultFrzColorUse: _baseObj.defaultFrzColorUse,
3065
+ _objType: `frz`,
3066
+ _shadowFlg: pattern === `Shadow`,
3067
+ }));
3115
3068
  }
3116
3069
 
3117
3070
  obj[`${_name}Default`] = obj[_name].concat();
@@ -3164,7 +3117,7 @@ const setColorList = (_data, _colorInit, _colorInitLength,
3164
3117
  colorList = colorStr.concat();
3165
3118
 
3166
3119
  for (let j = 0; j < colorList.length; j++) {
3167
- const tmpSetColorOrg = colorStr[j].replace(/0x/g, `#`).split(`:`);
3120
+ const tmpSetColorOrg = colorStr[j].replaceAll(`0x`, `#`).split(`:`);
3168
3121
  const hasColor = tmpSetColorOrg.some(tmpColorOrg => {
3169
3122
  if (hasVal(tmpColorOrg) && (isColorCd(tmpColorOrg) || !hasAnglePointInfo(tmpColorOrg) || tmpColorOrg === `Default`)) {
3170
3123
  colorOrg[j] = colorCdPadding(_colorCdPaddingUse, colorToHex(tmpColorOrg));
@@ -3395,8 +3348,7 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList.split(`,`) }
3395
3348
  if (_dosObj[keyheader] !== undefined) {
3396
3349
  const tmps = _dosObj[keyheader].split(`$`);
3397
3350
  for (let k = 0; k < tmps.length; k++) {
3398
- g_keyObj[`${keyheader}_${k}`] = setVal(g_keyObj[`${_name}${tmps[k]}`],
3399
- setVal(tmps[k], ``, _type), C_TYP_STRING);
3351
+ g_keyObj[`${keyheader}_${k}`] = setVal(g_keyObj[`${_name}${tmps[k]}`], setVal(tmps[k], ``, _type));
3400
3352
  }
3401
3353
  }
3402
3354
  };
@@ -3451,6 +3403,9 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList.split(`,`) }
3451
3403
  // キーの名前 (keyNameX)
3452
3404
  g_keyObj[`keyName${newKey}`] = _dosObj[`keyName${newKey}`] ?? newKey;
3453
3405
 
3406
+ // キーの最小横幅 (minWidthX)
3407
+ g_keyObj[`minWidth${newKey}`] = _dosObj[`minWidth${newKey}`] ?? g_keyObj.minWidthDefault;
3408
+
3454
3409
  // 矢印色パターン (colorX_Y)
3455
3410
  tmpMinPatterns = newKeyMultiParam(newKey, `color`, toNumber, {
3456
3411
  errCd: `E_0101`,
@@ -3472,13 +3427,13 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList.split(`,`) }
3472
3427
  for (let k = 0; k < tmpDivs.length; k++) {
3473
3428
  tmpDivPtn = tmpDivs[k].split(`,`);
3474
3429
 
3475
- if (setVal(tmpDivPtn[0], -1, C_TYP_NUMBER) !== -1) {
3476
- g_keyObj[`div${newKey}_${k}`] = setVal(tmpDivPtn[0], g_keyObj[`chara${newKey}_0`].length, C_TYP_NUMBER);
3430
+ if (setIntVal(tmpDivPtn[0], -1) !== -1) {
3431
+ g_keyObj[`div${newKey}_${k}`] = setIntVal(tmpDivPtn[0], g_keyObj[`chara${newKey}_0`].length);
3477
3432
  } else if (g_keyObj[`div${tmpDivPtn[0]}`] !== undefined) {
3478
3433
  // 既定キーパターンが指定された場合、存在すればその値を適用
3479
3434
  g_keyObj[`div${newKey}_${k}`] = g_keyObj[`div${tmpDivPtn[0]}`];
3480
- g_keyObj[`divMax${newKey}_${k}`] = setVal(g_keyObj[`divMax${tmpDivPtn[0]}`], undefined, C_TYP_NUMBER);
3481
- } else if (setVal(g_keyObj[`div${newKey}_${k}`], -1, C_TYP_NUMBER) !== -1) {
3435
+ g_keyObj[`divMax${newKey}_${k}`] = setIntVal(g_keyObj[`divMax${tmpDivPtn[0]}`], undefined);
3436
+ } else if (setIntVal(g_keyObj[`div${newKey}_${k}`], -1) !== -1) {
3482
3437
  // すでに定義済みの場合はスキップ
3483
3438
  continue;
3484
3439
  } else if (g_keyObj[`chara${newKey}_0`] !== undefined) {
@@ -3613,11 +3568,8 @@ const titleInit = _ => {
3613
3568
  const titlegrd2 = g_headerObj.titlegrds[1] || titlegrd1;
3614
3569
 
3615
3570
  const titlegrds = [];
3616
- [titlegrd1, titlegrd2].forEach((titlegrd, j) => {
3617
- titlegrds[j] = makeColorGradation(titlegrd, {
3618
- _defaultColorgrd: false, _objType: `titleMusic`,
3619
- });
3620
- });
3571
+ [titlegrd1, titlegrd2].forEach((titlegrd, j) =>
3572
+ titlegrds[j] = makeColorGradation(titlegrd, { _defaultColorgrd: false, _objType: `titleMusic` }));
3621
3573
 
3622
3574
  let titlefontsize = 64;
3623
3575
  for (let j = 0; j < g_headerObj.musicTitleForView.length; j++) {
@@ -3628,8 +3580,8 @@ const titleInit = _ => {
3628
3580
 
3629
3581
  // 変数 titlesize の定義 (使用例: |titlesize=40$20|)
3630
3582
  const titlefontsizes = (g_headerObj.titlesize !== `` ? g_headerObj.titlesize.split(`$`).join(`,`).split(`,`) : [titlefontsize, titlefontsize]);
3631
- const titlefontsize1 = setVal(titlefontsizes[0], titlefontsize, C_TYP_NUMBER);
3632
- const titlefontsize2 = setVal(titlefontsizes[1], titlefontsize1, C_TYP_NUMBER);
3583
+ const titlefontsize1 = setIntVal(titlefontsizes[0], titlefontsize);
3584
+ const titlefontsize2 = setIntVal(titlefontsizes[1], titlefontsize1);
3633
3585
 
3634
3586
  // 変数 titlelineheight の定義 (使用例: |titlelineheight=50|)
3635
3587
  const titlelineheight = (g_headerObj.titlelineheight !== `` ? g_headerObj.titlelineheight - (titlefontsize2 + 10) : 0);
@@ -3649,7 +3601,7 @@ const titleInit = _ => {
3649
3601
  background: ${titlegrds[0]};
3650
3602
  background-clip: text;
3651
3603
  -webkit-background-clip: text;
3652
- -webkit-text-fill-color: rgba(255,255,255,0.0);
3604
+ color: rgba(255,255,255,0.0);
3653
3605
  ${txtAnimations[0]}
3654
3606
  " class="${g_headerObj.titleAnimationClass[0]}">
3655
3607
  ${g_headerObj.musicTitleForView[0]}
@@ -3662,7 +3614,7 @@ const titleInit = _ => {
3662
3614
  background: ${titlegrds[1]};
3663
3615
  background-clip: text;
3664
3616
  -webkit-background-clip: text;
3665
- -webkit-text-fill-color: rgba(255,255,255,0.0);
3617
+ color: rgba(255,255,255,0.0);
3666
3618
  ${txtAnimations[1]}
3667
3619
  " class="${g_headerObj.titleAnimationClass[1]}">
3668
3620
  ${g_headerObj.musicTitleForView[1] ?? ``}
@@ -3901,9 +3853,7 @@ const makeInfoWindow = (_text, _animationName = ``, _backColor = `#ccccff`) => {
3901
3853
  */
3902
3854
  const setWindowStyle = (_text, _bkColor, _textColor, _align = C_ALIGN_LEFT) => {
3903
3855
 
3904
- if (document.querySelector(`#lblWarning`) !== null) {
3905
- divRoot.removeChild(lblWarning);
3906
- }
3856
+ deleteDiv(divRoot, `lblWarning`);
3907
3857
 
3908
3858
  // ウィンドウ枠の行を取得するために一時的な枠を作成
3909
3859
  const tmplbl = createDivCss2Label(`lblTmpWarning`, _text, {
@@ -4024,12 +3974,11 @@ const optionInit = _ => {
4024
3974
  const setSpriteList = _settingList => {
4025
3975
  const optionWidth = (g_sWidth - 450) / 2;
4026
3976
  const spriteList = [];
4027
- _settingList.forEach(setting => {
3977
+ _settingList.forEach(setting =>
4028
3978
  spriteList[setting[0]] = createEmptySprite(optionsprite, `${setting[0]}Sprite`, {
4029
3979
  x: 25, y: setting[1] * C_LEN_SETLBL_HEIGHT + setting[2] + 20,
4030
3980
  w: optionWidth + setting[3], h: C_LEN_SETLBL_HEIGHT + setting[4],
4031
- });
4032
- });
3981
+ }));
4033
3982
  return spriteList;
4034
3983
  };
4035
3984
 
@@ -4038,9 +3987,7 @@ const setSpriteList = _settingList => {
4038
3987
  * @param {string} _sprite
4039
3988
  * @returns
4040
3989
  */
4041
- const createOptionSprite = _sprite => createEmptySprite(_sprite, `optionsprite`, {
4042
- x: (g_sWidth - 450) / 2, y: 65 + (g_sHeight - 500) / 2, w: 450, h: 325,
4043
- });
3990
+ const createOptionSprite = _sprite => createEmptySprite(_sprite, `optionsprite`, g_windowObj.optionSprite);
4044
3991
 
4045
3992
  /**
4046
3993
  * スライダー共通処理
@@ -4162,10 +4109,8 @@ const createOptionWindow = _sprite => {
4162
4109
  const createDifWindow = (_key = ``) => {
4163
4110
  g_currentPage = `difSelector`;
4164
4111
  setShortcutEvent(g_currentPage);
4165
- const difList = createEmptySprite(optionsprite, `difList`, { x: 165, y: 65, w: 280, h: 255, overflow: `auto` }, g_cssObj.settings_DifSelector);
4166
- const difCover = createEmptySprite(optionsprite, `difCover`, {
4167
- x: 25, y: 65, w: 140, h: 255, overflow: `auto`, opacity: 0.95
4168
- }, g_cssObj.settings_DifSelector);
4112
+ const difList = createEmptySprite(optionsprite, `difList`, g_windowObj.difList, g_cssObj.settings_DifSelector);
4113
+ const difCover = createEmptySprite(optionsprite, `difCover`, g_windowObj.difCover, g_cssObj.settings_DifSelector);
4169
4114
 
4170
4115
  // リスト再作成
4171
4116
  makeDifList(difList, _key);
@@ -4251,7 +4196,7 @@ const createOptionWindow = _sprite => {
4251
4196
  * @param {boolean} _graphUseFlg
4252
4197
  */
4253
4198
  const createScoreDetail = (_name, _graphUseFlg = true) => {
4254
- const detailObj = createEmptySprite(scoreDetail, `detail${_name}`, { w: 420, h: 230, visibility: `hidden` });
4199
+ const detailObj = createEmptySprite(scoreDetail, `detail${_name}`, g_windowObj.detailObj);
4255
4200
 
4256
4201
  if (_graphUseFlg) {
4257
4202
  const graphObj = document.createElement(`canvas`);
@@ -4281,10 +4226,7 @@ const createOptionWindow = _sprite => {
4281
4226
  }, g_cssObj.button_Mini)
4282
4227
  );
4283
4228
  g_stateObj.scoreDetailViewFlg = false;
4284
-
4285
- const scoreDetail = createEmptySprite(optionsprite, `scoreDetail`, {
4286
- x: 20, y: 90, w: 420, h: 230, visibility: `hidden`,
4287
- }, g_cssObj.settings_DifSelector);
4229
+ const scoreDetail = createEmptySprite(optionsprite, `scoreDetail`, g_windowObj.scoreDetail, g_cssObj.settings_DifSelector);
4288
4230
  const viewScText = _ => createScText(lnkScoreDetail, `ScoreDetail`, { targetLabel: `lnkScoreDetail`, x: -10 });
4289
4231
 
4290
4232
  /**
@@ -4298,7 +4240,7 @@ const createOptionWindow = _sprite => {
4298
4240
  setSetting(_val, `scoreDetail`);
4299
4241
  viewScText();
4300
4242
  $id(`detail${g_stateObj.scoreDetail}`).visibility = `visible`;
4301
- }
4243
+ };
4302
4244
 
4303
4245
  multiAppend(scoreDetail,
4304
4246
  createScoreDetail(`Speed`),
@@ -4528,9 +4470,8 @@ const createOptionWindow = _sprite => {
4528
4470
  * @param {string} _data
4529
4471
  * @param {object} _obj
4530
4472
  */
4531
- const makeDifInfoLabel = (_lbl, _data, { x = 130, y = 25, w = 125, h = 35, siz = C_SIZ_DIFSELECTOR, ...rest } = {}) => {
4532
- return createDivCss2Label(_lbl, _data, { x, y, w, h, siz, align: C_ALIGN_LEFT, ...rest });
4533
- }
4473
+ const makeDifInfoLabel = (_lbl, _data, { x = 130, y = 25, w = 125, h = 35, siz = C_SIZ_DIFSELECTOR, ...rest } = {}) =>
4474
+ createDivCss2Label(_lbl, _data, { x, y, w, h, siz, align: C_ALIGN_LEFT, ...rest });
4534
4475
 
4535
4476
  let printData = ``;
4536
4477
  for (let j = 0; j < g_detailObj.arrowCnt.length; j++) {
@@ -4908,7 +4849,7 @@ const createOptionWindow = _sprite => {
4908
4849
  const isNotSameKey = (g_keyObj.prevKey !== g_keyObj.currentKey);
4909
4850
 
4910
4851
  if (g_headerObj.dummyScoreNos !== undefined) {
4911
- g_stateObj.dummyId = setVal(g_headerObj.dummyScoreNos[g_stateObj.scoreId], ``, C_TYP_NUMBER);
4852
+ g_stateObj.dummyId = setIntVal(g_headerObj.dummyScoreNos[g_stateObj.scoreId], ``);
4912
4853
  }
4913
4854
  // 特殊キーフラグ
4914
4855
  g_stateObj.extraKeyFlg = g_headerObj.keyExtraList.includes(g_keyObj.currentKey);
@@ -4965,10 +4906,10 @@ const createOptionWindow = _sprite => {
4965
4906
  g_keyObj[`shuffle${keyCtrlPtn}`] = g_keyObj[`shuffle${keyCtrlPtn}_${g_keycons.shuffleGroupNum}`].concat();
4966
4907
  }
4967
4908
  if (g_headerObj.keyRetryDef === C_KEY_RETRY) {
4968
- g_headerObj.keyRetry = setVal(g_keyObj[`keyRetry${keyCtrlPtn}`], g_headerObj.keyRetryDef, C_TYP_NUMBER);
4909
+ g_headerObj.keyRetry = setIntVal(g_keyObj[`keyRetry${keyCtrlPtn}`], g_headerObj.keyRetryDef);
4969
4910
  }
4970
4911
  if (g_headerObj.keyTitleBackDef === C_KEY_TITLEBACK) {
4971
- g_headerObj.keyTitleBack = setVal(g_keyObj[`keyTitleBack${keyCtrlPtn}`], g_headerObj.keyTitleBackDef, C_TYP_NUMBER);
4912
+ g_headerObj.keyTitleBack = setIntVal(g_keyObj[`keyTitleBack${keyCtrlPtn}`], g_headerObj.keyTitleBackDef);
4972
4913
  }
4973
4914
  }
4974
4915
 
@@ -5421,9 +5362,7 @@ const createSettingsDisplayWindow = _sprite => {
5421
5362
  ];
5422
5363
 
5423
5364
  // 設定毎に個別のスプライトを作成し、その中にラベル・ボタン類を配置
5424
- const displaySprite = createEmptySprite(optionsprite, `displaySprite`, {
5425
- x: 25, y: 30, w: (g_sWidth - 450) / 2, h: C_LEN_SETLBL_HEIGHT * 5,
5426
- });
5365
+ const displaySprite = createEmptySprite(optionsprite, `displaySprite`, g_windowObj.displaySprite);
5427
5366
  const spriteList = setSpriteList(settingList);
5428
5367
 
5429
5368
  _sprite.appendChild(
@@ -5563,7 +5502,7 @@ const keyConfigInit = (_kcType = g_kcType) => {
5563
5502
  );
5564
5503
 
5565
5504
  // キーの一覧を表示
5566
- const keyconSprite = createEmptySprite(divRoot, `keyconSprite`, { y: 88 + (g_sHeight - 500) / 2, h: g_sHeight, overflow: `auto` });
5505
+ const keyconSprite = createEmptySprite(divRoot, `keyconSprite`, g_windowObj.keyconSprite);
5567
5506
  const tkObj = getKeyInfo();
5568
5507
  const [keyCtrlPtn, keyNum, posMax, divideCnt] =
5569
5508
  [tkObj.keyCtrlPtn, tkObj.keyNum, tkObj.posMax, tkObj.divideCnt];
@@ -5707,8 +5646,8 @@ const keyConfigInit = (_kcType = g_kcType) => {
5707
5646
 
5708
5647
  // 割り当て先のキー名を表示
5709
5648
  for (let k = 0; k < g_keyObj[`keyCtrl${keyCtrlPtn}`][j].length; k++) {
5710
- g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setVal(g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k], 0, C_TYP_NUMBER);
5711
- g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k] = setVal(g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k], 0, C_TYP_NUMBER);
5649
+ g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setIntVal(g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k]);
5650
+ g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k] = setIntVal(g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k]);
5712
5651
 
5713
5652
  keyconSprite.appendChild(
5714
5653
  createCss2Button(`keycon${j}_${k}`, g_kCd[g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k]], _ => {
@@ -5976,11 +5915,26 @@ const keyConfigInit = (_kcType = g_kcType) => {
5976
5915
  lnkKcType.textContent = getStgDetailName(g_kcType);
5977
5916
  };
5978
5917
 
5918
+ /**
5919
+ * ColorPickerの色切替
5920
+ * @param {number} _j
5921
+ * @param {string} _type
5922
+ * @param {string} _color
5923
+ */
5924
+ const changeColorPicker = (_j, _type, _color) => {
5925
+ if (_color !== ``) {
5926
+ document.getElementById(`pick${_type}${_j}`).value = _color.slice(0, 7);
5927
+ document.getElementById(`pick${_type}${_j}`).style.display = C_DIS_INHERIT;
5928
+ } else {
5929
+ document.getElementById(`pick${_type}${_j}`).style.display = C_DIS_NONE;
5930
+ }
5931
+ };
5932
+
5979
5933
  /**
5980
5934
  * ColorTypeの制御
5981
5935
  * @param {number} _scrollNum
5982
5936
  */
5983
- const setColorType = (_scrollNum = 1) => {
5937
+ const setColorType = (_scrollNum = 1, _reloadFlg = true) => {
5984
5938
  const nextNum = getNextNum(_scrollNum, `colorTypes`, g_colorType);
5985
5939
  g_colorType = g_keycons.colorTypes[nextNum];
5986
5940
  if (g_headerObj.colorUse) {
@@ -5989,6 +5943,15 @@ const keyConfigInit = (_kcType = g_kcType) => {
5989
5943
  changeSetColor();
5990
5944
  viewGroupObj.color(`_${g_keycons.colorGroupNum}`);
5991
5945
  lnkColorType.textContent = `${getStgDetailName(g_colorType)}${g_localStorage.colorType === g_colorType ? ' *' : ''}`;
5946
+ if (_reloadFlg) {
5947
+ colorPickSprite.style.display = ([`Default`, `Type0`].includes(g_colorType) ? C_DIS_NONE : C_DIS_INHERIT);
5948
+ for (let j = 0; j < g_headerObj.setColor.length; j++) {
5949
+ changeColorPicker(j, `arrow`, g_headerObj.setColor[j]);
5950
+ changeColorPicker(j, `arrowShadow`, g_headerObj.setShadowColor[j]);
5951
+ changeColorPicker(j, `frz`, g_headerObj.frzColor[j][0]);
5952
+ changeColorPicker(j, `frzBar`, g_headerObj.frzColor[j][1]);
5953
+ }
5954
+ }
5992
5955
  };
5993
5956
 
5994
5957
  const setImgType = (_scrollNum = 1) => {
@@ -6001,6 +5964,53 @@ const keyConfigInit = (_kcType = g_kcType) => {
6001
5964
  keyConfigInit(g_kcType);
6002
5965
  };
6003
5966
 
5967
+ const colorPickSprite = createEmptySprite(divRoot, `colorPickSprite`, g_windowObj.colorPickSprite);
5968
+ if ([`Default`, `Type0`].includes(g_colorType)) {
5969
+ colorPickSprite.style.display = C_DIS_NONE;
5970
+ }
5971
+ const pickPos = { x: 0, w: 50, h: 15, siz: 11, align: C_ALIGN_LEFT, background: `#${g_headerObj.baseBrightFlg ? `eeeeee` : `111111`}80` };
5972
+ multiAppend(colorPickSprite,
5973
+ createDivCss2Label(`lblPickArrow`, g_lblNameObj.s_arrow, Object.assign({ y: 0 }, pickPos)),
5974
+ createDivCss2Label(`lblPickFrz`, g_lblNameObj.s_frz, Object.assign({ y: 140 }, pickPos)),
5975
+ createCss2Button(`lnkColorCopy`, `[↓]`, _ => {
5976
+ if (window.confirm(g_msgObj.colorCopyConfirm)) {
5977
+ for (let j = 0; j < g_headerObj.setColor.length; j++) {
5978
+ g_headerObj[`frzColor${g_colorType}`][j] = [...Array(g_headerObj[`frzColor${g_colorType}`][j].length)].fill(g_headerObj[`setColor${g_colorType}`][j]);
5979
+ [``, `Bar`].forEach((val, k) =>
5980
+ document.getElementById(`pickfrz${val}${j}`).value = g_headerObj[`frzColor${g_colorType}`][j][k]);
5981
+ }
5982
+ }
5983
+ }, { x: 35, y: -5, w: 30, h: 20, siz: 14 }, g_cssObj.button_Start),
5984
+ );
5985
+
5986
+ /**
5987
+ * ColorPicker部分の作成
5988
+ * @param {number} _j
5989
+ * @param {string} _type
5990
+ * @param {function} _func
5991
+ * @param {object} _obj
5992
+ */
5993
+ const createColorPickWindow = (_j, _type, _func, { x = 0, y = 15 } = {}) => {
5994
+ const picker = createColorPicker(colorPickSprite, `pick${_type}${_j}`, { x, y: y + 25 * _j });
5995
+ picker.addEventListener(`change`, _func);
5996
+ };
5997
+
5998
+ for (let j = 0; j < g_headerObj.setColor.length; j++) {
5999
+ createColorPickWindow(j, `arrow`, _ => {
6000
+ g_headerObj[`setColor${g_colorType}`][j] = document.getElementById(`pickarrow${j}`).value;
6001
+ setColorType(0, false);
6002
+ });
6003
+
6004
+ createColorPickWindow(j, `arrowShadow`, _ => {
6005
+ g_headerObj[`setShadowColor${g_colorType}`][j] = `${document.getElementById(`pickarrowShadow${j}`).value}80`;
6006
+ setColorType(0, false);
6007
+ }, { x: 25 });
6008
+
6009
+ [``, `Bar`].forEach((val, k) =>
6010
+ createColorPickWindow(j, `frz${val}`, _ =>
6011
+ g_headerObj[`frzColor${g_colorType}`][j][k] = document.getElementById(`pickfrz${val}${j}`).value, { x: 25 * k, y: 155 }));
6012
+ }
6013
+
6004
6014
  // ConfigType, ColorTypeの初期設定
6005
6015
  setConfigType(0);
6006
6016
  setColorType(0);
@@ -6075,7 +6085,7 @@ const keyConfigInit = (_kcType = g_kcType) => {
6075
6085
  if (window.confirm(g_msgObj.keyResetConfirm)) {
6076
6086
  for (let j = 0; j < keyNum; j++) {
6077
6087
  for (let k = 0; k < g_keyObj[`keyCtrl${keyCtrlPtn}`][j].length; k++) {
6078
- g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setVal(g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k], 0, C_TYP_NUMBER);
6088
+ g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setIntVal(g_keyObj[`keyCtrl${keyCtrlPtn}d`][j][k]);
6079
6089
  document.querySelector(`#keycon${j}_${k}`).textContent = g_kCd[g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k]];
6080
6090
  changeKeyConfigColor(j, k, g_keyObj.currentPtn === -1 ? g_cssObj.keyconfig_Defaultkey : g_cssObj.title_base);
6081
6091
  }
@@ -6252,7 +6262,7 @@ const loadMusic = _ => {
6252
6262
  request.addEventListener(`load`, _ => {
6253
6263
  if (request.status >= 200 && request.status < 300) {
6254
6264
  const blobUrl = URL.createObjectURL(request.response);
6255
- createEmptySprite(divRoot, `loader`, { y: g_sHeight - 10, h: 10, backgroundColor: `#333333` });
6265
+ createEmptySprite(divRoot, `loader`, g_windowObj.loader);
6256
6266
  lblLoading.textContent = g_lblNameObj.pleaseWait;
6257
6267
  setAudio(blobUrl);
6258
6268
  } else {
@@ -6722,12 +6732,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6722
6732
  // 矢印名からフリーズアロー名への変換
6723
6733
  let frzName = replaceStr(g_keyObj[`chara${_keyCtrlPtn}`][j], g_escapeStr.frzName);
6724
6734
  if (frzName.indexOf(`frz`) === -1 && frzName.indexOf(`foni`) === -1) {
6725
- if ((frzName.startsWith(`s`)) || frzName.startsWith(`t`) ||
6726
- (frzName.startsWith(`a`) && !frzName.startsWith(`arrow`))) {
6727
- frzName = frzName.replace(frzName.slice(1), `frz${toCapitalize(frzName.slice(1))}`);
6728
- } else {
6729
- frzName = frzName.replace(frzName, `frz${toCapitalize(frzName)}`);
6730
- }
6735
+ frzName = frzName.replaceAll(frzName, `frz${toCapitalize(frzName)}`);
6731
6736
  }
6732
6737
 
6733
6738
  // フリーズアローデータの分解 (2つで1セット)
@@ -6832,7 +6837,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6832
6837
  const frame = calcFrame(tmpcssMotionData[0]);
6833
6838
  const arrowNum = parseFloat(tmpcssMotionData[1]);
6834
6839
  const styleUp = (tmpcssMotionData[2] === `none` ? `` : tmpcssMotionData[2]);
6835
- const styleDown = (tmpcssMotionData[3] === `none` ? `` : setVal(tmpcssMotionData[3], styleUp, C_TYP_STRING));
6840
+ const styleDown = (tmpcssMotionData[3] === `none` ? `` : setVal(tmpcssMotionData[3], styleUp));
6836
6841
 
6837
6842
  cssMotionData.push([frame, arrowNum, styleUp, styleDown]);
6838
6843
  });
@@ -6841,6 +6846,20 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6841
6846
  return [];
6842
6847
  };
6843
6848
 
6849
+ /**
6850
+ * 譜面データの優先順配列の取得
6851
+ * @param {string} _header
6852
+ * @param {string} _type
6853
+ * @param {number} _scoreNo
6854
+ * @returns
6855
+ */
6856
+ const getPriorityList = (_header, _type, _scoreNo) => [
6857
+ _dosObj[`${_header}${_type}${g_localeObj.val}${_scoreNo}_data`],
6858
+ _dosObj[`${_header}${_type}${g_localeObj.val}_data`],
6859
+ _dosObj[`${_header}${_type}${_scoreNo}_data`],
6860
+ _dosObj[`${_header}${_type}_data`]
6861
+ ];
6862
+
6844
6863
  /**
6845
6864
  * 歌詞データの分解
6846
6865
  * @param {string} _scoreNo
@@ -6849,14 +6868,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6849
6868
  const wordDataList = [];
6850
6869
  let wordReverseFlg = false;
6851
6870
  const divideCnt = getKeyInfo().divideCnt;
6852
-
6853
- const addDataList = (_type = ``) =>
6854
- wordDataList.push(
6855
- _dosObj[`word${_type}${g_localeObj.val}${_scoreNo}_data`],
6856
- _dosObj[`word${_type}${g_localeObj.val}_data`],
6857
- _dosObj[`word${_type}${_scoreNo}_data`],
6858
- _dosObj[`word${_type}_data`]
6859
- );
6871
+ const addDataList = (_type = ``) => wordDataList.push(...getPriorityList(`word`, _type, _scoreNo));
6860
6872
 
6861
6873
  if (g_stateObj.scroll !== `---`) {
6862
6874
  addDataList(`Alt`);
@@ -6921,7 +6933,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6921
6933
  checkDuplicatedObjects(wordData[tmpWordData[k]]);
6922
6934
 
6923
6935
  if (tmpWordData.length > 3 && tmpWordData.length < 6) {
6924
- tmpWordData[3] = setVal(tmpWordData[3], C_WOD_FRAME, C_TYP_NUMBER);
6936
+ tmpWordData[3] = setIntVal(tmpWordData[3], C_WOD_FRAME);
6925
6937
  wordData[tmpWordData[0]][addFrame].push(tmpWordData[1],
6926
6938
  escapeHtmlForEnabledTag(tmpWordData[2]), tmpWordData[3]);
6927
6939
  break;
@@ -6942,13 +6954,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6942
6954
  */
6943
6955
  const makeBackgroundData = (_header, _scoreNo) => {
6944
6956
  const dataList = [];
6945
- const addDataList = (_type = ``) =>
6946
- dataList.push(
6947
- _dosObj[`${_header}${_type}${g_localeObj.val}${_scoreNo}_data`],
6948
- _dosObj[`${_header}${_type}${g_localeObj.val}_data`],
6949
- _dosObj[`${_header}${_type}${_scoreNo}_data`],
6950
- _dosObj[`${_header}${_type}_data`]
6951
- );
6957
+ const addDataList = (_type = ``) => dataList.push(...getPriorityList(_header, _type, _scoreNo));
6952
6958
 
6953
6959
  if (g_stateObj.scroll !== `---`) {
6954
6960
  addDataList(`Alt`);
@@ -6969,13 +6975,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
6969
6975
  */
6970
6976
  const makeBackgroundResultData = (_header, _scoreNo, _defaultHeader = ``) => {
6971
6977
  const dataList = [];
6972
- const addResultDataList = _headerType =>
6973
- dataList.push(
6974
- _dosObj[`${_headerType}${g_localeObj.val}${_scoreNo}_data`],
6975
- _dosObj[`${_headerType}${g_localeObj.val}_data`],
6976
- _dosObj[`${_headerType}${_scoreNo}_data`],
6977
- _dosObj[`${_headerType}_data`],
6978
- );
6978
+ const addResultDataList = _headerType => dataList.push(...getPriorityList(``, _headerType, _scoreNo));
6979
6979
  addResultDataList(_header);
6980
6980
  if (_defaultHeader !== ``) {
6981
6981
  addResultDataList(_defaultHeader);
@@ -7762,6 +7762,7 @@ const getArrowSettings = _ => {
7762
7762
  g_workObj.arrowRtn = copyArray2d(g_keyObj[`stepRtn${keyCtrlPtn}`]);
7763
7763
  g_workObj.keyCtrl = copyArray2d(g_keyObj[`keyCtrl${keyCtrlPtn}`]);
7764
7764
  g_workObj.diffList = [];
7765
+ g_workObj.mainEndTime = 0;
7765
7766
 
7766
7767
  const keyCtrlLen = g_workObj.keyCtrl.length;
7767
7768
  g_workObj.keyCtrlN = [...Array(keyCtrlLen)].map(_ => []);
@@ -9056,7 +9057,7 @@ const MainInit = _ => {
9056
9057
 
9057
9058
  g_workObj.lastFadeFrame[wordDepth] = currentFrame;
9058
9059
  g_workObj.wordFadeFrame[wordDepth] = (tmpObj.length > 2 ?
9059
- setVal(tmpObj[2], C_WOD_FRAME, C_TYP_NUMBER) : C_WOD_FRAME);
9060
+ setIntVal(tmpObj[2], C_WOD_FRAME) : C_WOD_FRAME);
9060
9061
 
9061
9062
  g_wordSprite.style.animationDuration = `${g_workObj.wordFadeFrame[wordDepth] / g_fps}s`;
9062
9063
  g_wordSprite.style.animationTimingFunction = `linear`;
@@ -9070,7 +9071,7 @@ const MainInit = _ => {
9070
9071
  } else if (/\[fontSize=\d+\]/.test(g_wordObj.wordDat)) {
9071
9072
 
9072
9073
  // フォントサイズ変更
9073
- const fontSize = setVal(g_wordObj.wordDat.match(/\d+/)[0], C_SIZ_MAIN, C_TYP_NUMBER);
9074
+ const fontSize = setIntVal(g_wordObj.wordDat.match(/\d+/)[0], C_SIZ_MAIN);
9074
9075
  g_wordSprite.style.fontSize = `${fontSize}px`;
9075
9076
 
9076
9077
  } else {
@@ -9109,7 +9110,8 @@ const MainInit = _ => {
9109
9110
  }
9110
9111
  resetKeyControl();
9111
9112
  clearTimeout(g_timeoutEvtId);
9112
- setTimeout(_ => resultInit(), 100);
9113
+ g_workObj.mainEndTime = thisTime;
9114
+ resultInit();
9113
9115
 
9114
9116
  } else if (g_workObj.lifeVal === 0 && g_workObj.lifeBorder === 0) {
9115
9117
 
@@ -9661,7 +9663,7 @@ const resultInit = _ => {
9661
9663
  // 曲時間制御変数
9662
9664
  let thisTime;
9663
9665
  let buffTime;
9664
- let resultStartTime = performance.now();
9666
+ let resultStartTime = g_workObj.mainEndTime > 0 ? g_workObj.mainEndTime : performance.now();
9665
9667
 
9666
9668
  if (g_stateObj.d_background === C_FLG_OFF && g_headerObj.resultMotionSet) {
9667
9669
  } else {
@@ -9704,12 +9706,8 @@ const resultInit = _ => {
9704
9706
  // タイトル文字描画
9705
9707
  divRoot.appendChild(getTitleDivLabel(`lblTitle`, g_lblNameObj.result, 0, 15, `settings_Title`));
9706
9708
 
9707
- const playDataWindow = createEmptySprite(divRoot, `playDataWindow`, {
9708
- x: g_sWidth / 2 - 225, y: 70 + (g_sHeight - 500) / 2, w: 450, h: 110,
9709
- }, g_cssObj.result_PlayDataWindow);
9710
- const resultWindow = createEmptySprite(divRoot, `resultWindow`, {
9711
- x: g_sWidth / 2 - 200, y: 185 + (g_sHeight - 500) / 2, w: 400, h: 210,
9712
- });
9709
+ const playDataWindow = createEmptySprite(divRoot, `playDataWindow`, g_windowObj.playDataWindow, g_cssObj.result_PlayDataWindow);
9710
+ const resultWindow = createEmptySprite(divRoot, `resultWindow`, g_windowObj.resultWindow);
9713
9711
 
9714
9712
  const playingArrows = g_resultObj.ii + g_resultObj.shakin +
9715
9713
  g_resultObj.matari + g_resultObj.shobon + g_resultObj.uwan +
@@ -9985,7 +9983,7 @@ const resultInit = _ => {
9985
9983
 
9986
9984
  // Twitter用リザルト
9987
9985
  // スコアを上塗りする可能性があるため、カスタムイベント後に配置
9988
- const hashTag = (g_headerObj.hashTag !== undefined ? ` ${g_headerObj.hashTag}` : ``);
9986
+ const hashTag = (hasVal(g_headerObj.hashTag) ? ` ${g_headerObj.hashTag}` : ``);
9989
9987
  let tweetDifData = `${getKeyName(g_headerObj.keyLabels[g_stateObj.scoreId])}${transKeyData}${getStgDetailName('k-')}${g_headerObj.difLabels[g_stateObj.scoreId]}${assistFlg}`;
9990
9988
  if (g_stateObj.shuffle !== `OFF`) {
9991
9989
  tweetDifData += `:${getShuffleName()}`;
@@ -10125,8 +10123,7 @@ const resultInit = _ => {
10125
10123
  g_scoreObj.maskResultFrameNum++;
10126
10124
  g_timeoutEvtResultId = setTimeout(_ => flowResultTimeline(), 1000 / g_fps - buffTime);
10127
10125
  };
10128
-
10129
- g_timeoutEvtResultId = setTimeout(_ => flowResultTimeline(), 1000 / g_fps);
10126
+ flowResultTimeline();
10130
10127
 
10131
10128
  // キー操作イベント(デフォルト)
10132
10129
  setShortcutEvent(g_currentPage);