arcanumcube 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,19 @@
1
1
  # Arcanum Cube
2
2
 
3
- Arcanum Cube is a cube puzzle module written in Typescript. Supports creation and manipulation of WebGL mesh groups.
3
+ Arcanum Cube Arcanum Cube is a WebGL cube puzzle module written in TypeScript. You can create Three.js meshes group and twist cube.
4
4
 
5
- [Demo Page](https://mawxiwtz.github.io/arcanumcube/)
5
+ ## Demo Page
6
+
7
+ - [Example](https://mawxiwtz.github.io/arcanumcube/) \
8
+ Rotation only
9
+
10
+ ## Installation
11
+
12
+ You can add arcanumcube as an npm dependency:
13
+
14
+ ```
15
+ npm install arcanumcube
16
+ ```
6
17
 
7
18
  ## Usage
8
19
 
@@ -16,11 +27,14 @@ import * as ARCCUBE from 'arcanumcube';
16
27
  2. create a cube object
17
28
 
18
29
  ```
30
+ const scene = new THREE.Scene();
31
+ :
19
32
  const arccube = new ARCCUBE.WebGLArcanumCube();
20
33
  await arccube.init();
21
34
  const arccubeGroup = arccube.getGroup();
22
35
  arccubeGroup.position.set(0, 0, 0);
23
36
  scene.add(arccubeGroup);
37
+ :
24
38
 
25
39
  renderer.setAnimationLoop((time) => {
26
40
  :
@@ -43,6 +57,10 @@ arccube.tweenTwist('U');
43
57
  arccube.reset();
44
58
  ```
45
59
 
60
+ ## Document
61
+
62
+ Currently under construction
63
+
46
64
  ## License
47
65
 
48
66
  Released under the MIT license
@@ -43,6 +43,7 @@ __export(arcanumcube_exports, {
43
43
  FACE: () => FACE,
44
44
  GetSkinByName: () => GetSkinByName,
45
45
  GetSkinNameList: () => GetSkinNameList,
46
+ MatchGoalState: () => MatchGoalState,
46
47
  SIDE_MAX: () => SIDE_MAX,
47
48
  SIDE_MIDDLE: () => SIDE_MIDDLE,
48
49
  SIDE_MIN: () => SIDE_MIN,
@@ -329,6 +330,42 @@ function getRandomTwistList(steps = 0) {
329
330
  }
330
331
  return list;
331
332
  }
333
+ var SIDE_FACES = Object.freeze([
334
+ [1, 2, 4, 5],
335
+ [2, 0, 5, 3],
336
+ [0, 1, 3, 4],
337
+ [2, 1, 5, 4],
338
+ [0, 2, 3, 5],
339
+ [1, 0, 4, 3]
340
+ ]);
341
+ function getInitialState(up, front) {
342
+ const down = (up + 3) % 6;
343
+ const side = SIDE_FACES[up];
344
+ const state = new Array(CUBE_SIZE * CUBE_SIZE).fill(up);
345
+ for (let i = 0; i < 4; i++) {
346
+ if (i == 2) {
347
+ const downs = [...Array(CUBE_SIZE * CUBE_SIZE)].fill(down);
348
+ state.push(...downs);
349
+ }
350
+ const sides = [...Array(CUBE_SIZE * CUBE_SIZE)].fill(side[(front + i) % 4]);
351
+ state.push(...sides);
352
+ }
353
+ return state;
354
+ }
355
+ function isSameArrays(arr1, arr2) {
356
+ if (arr1.length !== arr2.length) return false;
357
+ return !arr1.some((v, i) => v !== arr2[i]);
358
+ }
359
+ var GOAL_STATE_LIST = [];
360
+ for (let up = 0; up < 6; up++) {
361
+ for (let front = 0; front < 4; front++) {
362
+ GOAL_STATE_LIST.push(getInitialState(up, front));
363
+ }
364
+ }
365
+ Object.freeze(GOAL_STATE_LIST);
366
+ function MatchGoalState(state) {
367
+ return GOAL_STATE_LIST.some((s) => isSameArrays(state, s));
368
+ }
332
369
  var Cube = class {
333
370
  type;
334
371
  position;
@@ -473,6 +510,9 @@ var ArcanumCube = class {
473
510
  const list = this.getUndoList(steps);
474
511
  this.twist(list, true);
475
512
  }
513
+ isSolved() {
514
+ return MatchGoalState(this.getStickerColors());
515
+ }
476
516
  getHistory() {
477
517
  return this._history;
478
518
  }
@@ -1200,7 +1240,8 @@ var WebGLCube = class extends Cube {
1200
1240
  gap: 0.01,
1201
1241
  enableShadow: false,
1202
1242
  skin: DefaultSkin,
1203
- wireframe: false
1243
+ wireframe: false,
1244
+ wireframeColor: 32768
1204
1245
  };
1205
1246
  if (opts) {
1206
1247
  Object.assign(this._config, opts);
@@ -1244,7 +1285,7 @@ var WebGLCube = class extends Cube {
1244
1285
  }
1245
1286
  if (config.wireframe) {
1246
1287
  mat.wireframe = config.wireframe;
1247
- mat.color = new THREE3.Color("#080");
1288
+ mat.color = new THREE3.Color(config.wireframeColor);
1248
1289
  }
1249
1290
  const m = new THREE3.Mesh(geo, mat);
1250
1291
  m.name = this.type;
@@ -1285,7 +1326,7 @@ var WebGLCube = class extends Cube {
1285
1326
  }
1286
1327
  if (config.wireframe) {
1287
1328
  pmat.wireframe = config.wireframe;
1288
- pmat.color = new THREE3.Color("#080");
1329
+ pmat.color = new THREE3.Color(config.wireframeColor);
1289
1330
  }
1290
1331
  const pm = new THREE3.Mesh(pgeo, pmat);
1291
1332
  pm.name = CUBE.STICKER;
@@ -1375,7 +1416,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1375
1416
  /** tween group */
1376
1417
  _tweens;
1377
1418
  /** light at the center of cube */
1378
- _pointLights;
1419
+ _coreLights;
1379
1420
  constructor(options) {
1380
1421
  super(options);
1381
1422
  this._config = {
@@ -1387,8 +1428,13 @@ var WebGLArcanumCube = class extends ArcanumCube {
1387
1428
  gap: 0.01,
1388
1429
  enableShadow: false,
1389
1430
  skin: DefaultSkin,
1390
- enableLight: false,
1391
- wireframe: false
1431
+ autoReset: true,
1432
+ enableCoreLight: false,
1433
+ coreLightColor: 33023,
1434
+ coreLightIntensity: 30,
1435
+ wireframe: false,
1436
+ wireframeColor: 32768,
1437
+ twistOptions: {}
1392
1438
  };
1393
1439
  this._matrix = [];
1394
1440
  this._group = new THREE3.Group();
@@ -1396,7 +1442,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1396
1442
  this._cubeMap = {};
1397
1443
  this._cancelDragDeg = 15;
1398
1444
  this._tweens = new TWEEN.Group();
1399
- this._pointLights = [];
1445
+ this._coreLights = [];
1400
1446
  if (options) {
1401
1447
  Object.assign(this._config, options);
1402
1448
  }
@@ -1422,7 +1468,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1422
1468
  this._cubeMap = {};
1423
1469
  this._matrix = [];
1424
1470
  this._history = [];
1425
- this._pointLights = [];
1471
+ this._coreLights = [];
1426
1472
  const fixedGroups = new THREE3.Group();
1427
1473
  const config = this._config;
1428
1474
  const yarray = [];
@@ -1438,7 +1484,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
1438
1484
  enableShadow: config.enableShadow,
1439
1485
  skin: config.skin,
1440
1486
  envMap: config.envMap,
1441
- wireframe: config.wireframe
1487
+ wireframe: config.wireframe,
1488
+ wireframeColor: config.wireframeColor
1442
1489
  });
1443
1490
  cube.init();
1444
1491
  xarray.push(cube);
@@ -1446,18 +1493,18 @@ var WebGLArcanumCube = class extends ArcanumCube {
1446
1493
  this._cubeObjectList.push(entityGroup);
1447
1494
  this._cubeMap[entityGroup.id] = cube;
1448
1495
  fixedGroups.add(cube.getGroup());
1449
- if (config.enableLight) {
1496
+ if (config.enableCoreLight) {
1450
1497
  if (x !== SIDE_MIN && y !== SIDE_MIN && z !== SIDE_MIN) {
1451
1498
  const light = new THREE3.PointLight(
1452
- config.wireframe ? 32768 : 33023,
1453
- 30,
1499
+ config.wireframe ? config.wireframeColor : config.coreLightColor,
1500
+ config.coreLightIntensity,
1454
1501
  20,
1455
1502
  0.1
1456
1503
  );
1457
1504
  light.position.x = (x - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
1458
1505
  light.position.y = (y - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
1459
1506
  light.position.z += (z - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
1460
- this._pointLights.push(light);
1507
+ this._coreLights.push(light);
1461
1508
  }
1462
1509
  }
1463
1510
  }
@@ -1467,8 +1514,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
1467
1514
  }
1468
1515
  this._matrix = yarray;
1469
1516
  this._group.clear();
1470
- if (config.enableLight) {
1471
- this._pointLights.forEach((light) => {
1517
+ if (config.enableCoreLight) {
1518
+ this._coreLights.forEach((light) => {
1472
1519
  this._group.add(light);
1473
1520
  });
1474
1521
  }
@@ -1670,8 +1717,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
1670
1717
  }
1671
1718
  }
1672
1719
  this._group.clear();
1673
- if (this._config.enableLight) {
1674
- this._pointLights.forEach((light) => {
1720
+ if (this._config.enableCoreLight) {
1721
+ this._coreLights.forEach((light) => {
1675
1722
  this._group.add(light);
1676
1723
  });
1677
1724
  }
@@ -1708,7 +1755,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1708
1755
  // twist randomly several steps
1709
1756
  scramble(steps = 0, duration = 3e3) {
1710
1757
  const list = getRandomTwistList(steps);
1711
- this.tweenTwist(list, false, duration);
1758
+ this.tweenTwist(list, false, duration, false);
1712
1759
  }
1713
1760
  undo(steps = 1, duration = 300) {
1714
1761
  const list = this.getUndoList(steps);
@@ -1716,17 +1763,25 @@ var WebGLArcanumCube = class extends ArcanumCube {
1716
1763
  }
1717
1764
  // twisting(複数回対応)
1718
1765
  // durationを0にするとTweenなしとなる
1719
- tweenTwist(twist, reverse = false, duration = 500, cancel = false) {
1766
+ tweenTwist(twist, reverse = false, duration = 500, cancel = false, options) {
1720
1767
  if (this._tweens.getAll().length > 0) return;
1768
+ if (options == null) options = this._config.twistOptions;
1721
1769
  if (duration === 0) {
1722
1770
  if (Array.isArray(twist)) {
1723
1771
  if (twist.length == 0) return;
1724
- for (const c of twist) {
1772
+ options?.onStart && options.onStart(this);
1773
+ const len = twist.length;
1774
+ for (let i = 0; i < len; i++) {
1775
+ const c = twist[i];
1725
1776
  this._immediatelyTwist(c, reverse);
1777
+ options?.onTwisted && options.onTwisted(this, c, i + 1, len);
1726
1778
  }
1727
1779
  } else {
1780
+ options?.onStart && options.onStart(this);
1728
1781
  this._immediatelyTwist(twist, reverse);
1782
+ options?.onTwisted && options.onTwisted(this, twist, 1, 1);
1729
1783
  }
1784
+ options?.onComplete && options.onComplete(this);
1730
1785
  return;
1731
1786
  }
1732
1787
  let firstTween = void 0;
@@ -1734,8 +1789,15 @@ var WebGLArcanumCube = class extends ArcanumCube {
1734
1789
  if (Array.isArray(twist)) {
1735
1790
  if (twist.length == 0) return;
1736
1791
  const lap = duration / twist.length;
1737
- for (const c of twist) {
1738
- const t = this._tweenTwist(c, reverse, lap, cancel);
1792
+ const len = twist.length;
1793
+ for (let i = 0; i < len; i++) {
1794
+ const c = twist[i];
1795
+ const opts = {};
1796
+ const ontwisted = options?.onTwisted;
1797
+ if (ontwisted)
1798
+ opts.onTwisted = (self, twist2, n1, n2) => ontwisted(this, twist2, i + 1, len);
1799
+ if (i === len - 1 && options?.onComplete) opts.onComplete = options.onComplete;
1800
+ const t = this._tweenTwist(c, reverse, lap, cancel, opts);
1739
1801
  this._tweens.add(t);
1740
1802
  if (!tween) {
1741
1803
  firstTween = tween = t;
@@ -1745,10 +1807,11 @@ var WebGLArcanumCube = class extends ArcanumCube {
1745
1807
  }
1746
1808
  }
1747
1809
  } else {
1748
- firstTween = this._tweenTwist(twist, reverse, duration, cancel);
1810
+ firstTween = this._tweenTwist(twist, reverse, duration, cancel, options);
1749
1811
  this._tweens.add(firstTween);
1750
1812
  }
1751
1813
  if (firstTween) {
1814
+ options?.onStart && options.onStart(this);
1752
1815
  firstTween.start();
1753
1816
  }
1754
1817
  }
@@ -1770,7 +1833,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1770
1833
  super.twist(twist, reverse);
1771
1834
  }
1772
1835
  // twist with tween
1773
- _tweenTwist(twist, reverse, duration, cancel) {
1836
+ _tweenTwist(twist, reverse, duration, cancel, options = {}) {
1774
1837
  let qa;
1775
1838
  if (this._draggingTwist) {
1776
1839
  this._twistGroup = this._draggingTwist.group;
@@ -1807,12 +1870,28 @@ var WebGLArcanumCube = class extends ArcanumCube {
1807
1870
  super.twist(twist, reverse);
1808
1871
  }
1809
1872
  this._tweens.remove(tween);
1873
+ options.onTwisted && options.onTwisted(this, twist, 1, 1);
1874
+ options.onComplete && options.onComplete(this);
1875
+ if (this._config.autoReset && this.isSolved()) this.reset(0);
1810
1876
  });
1811
1877
  return tween;
1812
1878
  }
1813
1879
  updateTweens() {
1814
1880
  this._tweens.update();
1815
1881
  }
1882
+ // set color of core lights
1883
+ setCoreLightColor(color) {
1884
+ const c = new THREE3.Color(color);
1885
+ this._coreLights.forEach((l) => {
1886
+ l.color = c;
1887
+ });
1888
+ }
1889
+ // change intensity of core lights
1890
+ setCoreLightIntensity(intensity) {
1891
+ this._coreLights.forEach((l) => {
1892
+ l.intensity = intensity;
1893
+ });
1894
+ }
1816
1895
  };
1817
1896
  // Annotate the CommonJS export names for ESM import in node:
1818
1897
  0 && (module.exports = {
@@ -1829,6 +1908,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1829
1908
  FACE,
1830
1909
  GetSkinByName,
1831
1910
  GetSkinNameList,
1911
+ MatchGoalState,
1832
1912
  SIDE_MAX,
1833
1913
  SIDE_MIDDLE,
1834
1914
  SIDE_MIN,
@@ -264,6 +264,42 @@ function getRandomTwistList(steps = 0) {
264
264
  }
265
265
  return list;
266
266
  }
267
+ var SIDE_FACES = Object.freeze([
268
+ [1, 2, 4, 5],
269
+ [2, 0, 5, 3],
270
+ [0, 1, 3, 4],
271
+ [2, 1, 5, 4],
272
+ [0, 2, 3, 5],
273
+ [1, 0, 4, 3]
274
+ ]);
275
+ function getInitialState(up, front) {
276
+ const down = (up + 3) % 6;
277
+ const side = SIDE_FACES[up];
278
+ const state = new Array(CUBE_SIZE * CUBE_SIZE).fill(up);
279
+ for (let i = 0; i < 4; i++) {
280
+ if (i == 2) {
281
+ const downs = [...Array(CUBE_SIZE * CUBE_SIZE)].fill(down);
282
+ state.push(...downs);
283
+ }
284
+ const sides = [...Array(CUBE_SIZE * CUBE_SIZE)].fill(side[(front + i) % 4]);
285
+ state.push(...sides);
286
+ }
287
+ return state;
288
+ }
289
+ function isSameArrays(arr1, arr2) {
290
+ if (arr1.length !== arr2.length) return false;
291
+ return !arr1.some((v, i) => v !== arr2[i]);
292
+ }
293
+ var GOAL_STATE_LIST = [];
294
+ for (let up = 0; up < 6; up++) {
295
+ for (let front = 0; front < 4; front++) {
296
+ GOAL_STATE_LIST.push(getInitialState(up, front));
297
+ }
298
+ }
299
+ Object.freeze(GOAL_STATE_LIST);
300
+ function MatchGoalState(state) {
301
+ return GOAL_STATE_LIST.some((s) => isSameArrays(state, s));
302
+ }
267
303
  var Cube = class {
268
304
  type;
269
305
  position;
@@ -408,6 +444,9 @@ var ArcanumCube = class {
408
444
  const list = this.getUndoList(steps);
409
445
  this.twist(list, true);
410
446
  }
447
+ isSolved() {
448
+ return MatchGoalState(this.getStickerColors());
449
+ }
411
450
  getHistory() {
412
451
  return this._history;
413
452
  }
@@ -1135,7 +1174,8 @@ var WebGLCube = class extends Cube {
1135
1174
  gap: 0.01,
1136
1175
  enableShadow: false,
1137
1176
  skin: DefaultSkin,
1138
- wireframe: false
1177
+ wireframe: false,
1178
+ wireframeColor: 32768
1139
1179
  };
1140
1180
  if (opts) {
1141
1181
  Object.assign(this._config, opts);
@@ -1179,7 +1219,7 @@ var WebGLCube = class extends Cube {
1179
1219
  }
1180
1220
  if (config.wireframe) {
1181
1221
  mat.wireframe = config.wireframe;
1182
- mat.color = new THREE3.Color("#080");
1222
+ mat.color = new THREE3.Color(config.wireframeColor);
1183
1223
  }
1184
1224
  const m = new THREE3.Mesh(geo, mat);
1185
1225
  m.name = this.type;
@@ -1220,7 +1260,7 @@ var WebGLCube = class extends Cube {
1220
1260
  }
1221
1261
  if (config.wireframe) {
1222
1262
  pmat.wireframe = config.wireframe;
1223
- pmat.color = new THREE3.Color("#080");
1263
+ pmat.color = new THREE3.Color(config.wireframeColor);
1224
1264
  }
1225
1265
  const pm = new THREE3.Mesh(pgeo, pmat);
1226
1266
  pm.name = CUBE.STICKER;
@@ -1310,7 +1350,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1310
1350
  /** tween group */
1311
1351
  _tweens;
1312
1352
  /** light at the center of cube */
1313
- _pointLights;
1353
+ _coreLights;
1314
1354
  constructor(options) {
1315
1355
  super(options);
1316
1356
  this._config = {
@@ -1322,8 +1362,13 @@ var WebGLArcanumCube = class extends ArcanumCube {
1322
1362
  gap: 0.01,
1323
1363
  enableShadow: false,
1324
1364
  skin: DefaultSkin,
1325
- enableLight: false,
1326
- wireframe: false
1365
+ autoReset: true,
1366
+ enableCoreLight: false,
1367
+ coreLightColor: 33023,
1368
+ coreLightIntensity: 30,
1369
+ wireframe: false,
1370
+ wireframeColor: 32768,
1371
+ twistOptions: {}
1327
1372
  };
1328
1373
  this._matrix = [];
1329
1374
  this._group = new THREE3.Group();
@@ -1331,7 +1376,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1331
1376
  this._cubeMap = {};
1332
1377
  this._cancelDragDeg = 15;
1333
1378
  this._tweens = new TWEEN.Group();
1334
- this._pointLights = [];
1379
+ this._coreLights = [];
1335
1380
  if (options) {
1336
1381
  Object.assign(this._config, options);
1337
1382
  }
@@ -1357,7 +1402,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1357
1402
  this._cubeMap = {};
1358
1403
  this._matrix = [];
1359
1404
  this._history = [];
1360
- this._pointLights = [];
1405
+ this._coreLights = [];
1361
1406
  const fixedGroups = new THREE3.Group();
1362
1407
  const config = this._config;
1363
1408
  const yarray = [];
@@ -1373,7 +1418,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
1373
1418
  enableShadow: config.enableShadow,
1374
1419
  skin: config.skin,
1375
1420
  envMap: config.envMap,
1376
- wireframe: config.wireframe
1421
+ wireframe: config.wireframe,
1422
+ wireframeColor: config.wireframeColor
1377
1423
  });
1378
1424
  cube.init();
1379
1425
  xarray.push(cube);
@@ -1381,18 +1427,18 @@ var WebGLArcanumCube = class extends ArcanumCube {
1381
1427
  this._cubeObjectList.push(entityGroup);
1382
1428
  this._cubeMap[entityGroup.id] = cube;
1383
1429
  fixedGroups.add(cube.getGroup());
1384
- if (config.enableLight) {
1430
+ if (config.enableCoreLight) {
1385
1431
  if (x !== SIDE_MIN && y !== SIDE_MIN && z !== SIDE_MIN) {
1386
1432
  const light = new THREE3.PointLight(
1387
- config.wireframe ? 32768 : 33023,
1388
- 30,
1433
+ config.wireframe ? config.wireframeColor : config.coreLightColor,
1434
+ config.coreLightIntensity,
1389
1435
  20,
1390
1436
  0.1
1391
1437
  );
1392
1438
  light.position.x = (x - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
1393
1439
  light.position.y = (y - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
1394
1440
  light.position.z += (z - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
1395
- this._pointLights.push(light);
1441
+ this._coreLights.push(light);
1396
1442
  }
1397
1443
  }
1398
1444
  }
@@ -1402,8 +1448,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
1402
1448
  }
1403
1449
  this._matrix = yarray;
1404
1450
  this._group.clear();
1405
- if (config.enableLight) {
1406
- this._pointLights.forEach((light) => {
1451
+ if (config.enableCoreLight) {
1452
+ this._coreLights.forEach((light) => {
1407
1453
  this._group.add(light);
1408
1454
  });
1409
1455
  }
@@ -1605,8 +1651,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
1605
1651
  }
1606
1652
  }
1607
1653
  this._group.clear();
1608
- if (this._config.enableLight) {
1609
- this._pointLights.forEach((light) => {
1654
+ if (this._config.enableCoreLight) {
1655
+ this._coreLights.forEach((light) => {
1610
1656
  this._group.add(light);
1611
1657
  });
1612
1658
  }
@@ -1643,7 +1689,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1643
1689
  // twist randomly several steps
1644
1690
  scramble(steps = 0, duration = 3e3) {
1645
1691
  const list = getRandomTwistList(steps);
1646
- this.tweenTwist(list, false, duration);
1692
+ this.tweenTwist(list, false, duration, false);
1647
1693
  }
1648
1694
  undo(steps = 1, duration = 300) {
1649
1695
  const list = this.getUndoList(steps);
@@ -1651,17 +1697,25 @@ var WebGLArcanumCube = class extends ArcanumCube {
1651
1697
  }
1652
1698
  // twisting(複数回対応)
1653
1699
  // durationを0にするとTweenなしとなる
1654
- tweenTwist(twist, reverse = false, duration = 500, cancel = false) {
1700
+ tweenTwist(twist, reverse = false, duration = 500, cancel = false, options) {
1655
1701
  if (this._tweens.getAll().length > 0) return;
1702
+ if (options == null) options = this._config.twistOptions;
1656
1703
  if (duration === 0) {
1657
1704
  if (Array.isArray(twist)) {
1658
1705
  if (twist.length == 0) return;
1659
- for (const c of twist) {
1706
+ options?.onStart && options.onStart(this);
1707
+ const len = twist.length;
1708
+ for (let i = 0; i < len; i++) {
1709
+ const c = twist[i];
1660
1710
  this._immediatelyTwist(c, reverse);
1711
+ options?.onTwisted && options.onTwisted(this, c, i + 1, len);
1661
1712
  }
1662
1713
  } else {
1714
+ options?.onStart && options.onStart(this);
1663
1715
  this._immediatelyTwist(twist, reverse);
1716
+ options?.onTwisted && options.onTwisted(this, twist, 1, 1);
1664
1717
  }
1718
+ options?.onComplete && options.onComplete(this);
1665
1719
  return;
1666
1720
  }
1667
1721
  let firstTween = void 0;
@@ -1669,8 +1723,15 @@ var WebGLArcanumCube = class extends ArcanumCube {
1669
1723
  if (Array.isArray(twist)) {
1670
1724
  if (twist.length == 0) return;
1671
1725
  const lap = duration / twist.length;
1672
- for (const c of twist) {
1673
- const t = this._tweenTwist(c, reverse, lap, cancel);
1726
+ const len = twist.length;
1727
+ for (let i = 0; i < len; i++) {
1728
+ const c = twist[i];
1729
+ const opts = {};
1730
+ const ontwisted = options?.onTwisted;
1731
+ if (ontwisted)
1732
+ opts.onTwisted = (self, twist2, n1, n2) => ontwisted(this, twist2, i + 1, len);
1733
+ if (i === len - 1 && options?.onComplete) opts.onComplete = options.onComplete;
1734
+ const t = this._tweenTwist(c, reverse, lap, cancel, opts);
1674
1735
  this._tweens.add(t);
1675
1736
  if (!tween) {
1676
1737
  firstTween = tween = t;
@@ -1680,10 +1741,11 @@ var WebGLArcanumCube = class extends ArcanumCube {
1680
1741
  }
1681
1742
  }
1682
1743
  } else {
1683
- firstTween = this._tweenTwist(twist, reverse, duration, cancel);
1744
+ firstTween = this._tweenTwist(twist, reverse, duration, cancel, options);
1684
1745
  this._tweens.add(firstTween);
1685
1746
  }
1686
1747
  if (firstTween) {
1748
+ options?.onStart && options.onStart(this);
1687
1749
  firstTween.start();
1688
1750
  }
1689
1751
  }
@@ -1705,7 +1767,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1705
1767
  super.twist(twist, reverse);
1706
1768
  }
1707
1769
  // twist with tween
1708
- _tweenTwist(twist, reverse, duration, cancel) {
1770
+ _tweenTwist(twist, reverse, duration, cancel, options = {}) {
1709
1771
  let qa;
1710
1772
  if (this._draggingTwist) {
1711
1773
  this._twistGroup = this._draggingTwist.group;
@@ -1742,12 +1804,28 @@ var WebGLArcanumCube = class extends ArcanumCube {
1742
1804
  super.twist(twist, reverse);
1743
1805
  }
1744
1806
  this._tweens.remove(tween);
1807
+ options.onTwisted && options.onTwisted(this, twist, 1, 1);
1808
+ options.onComplete && options.onComplete(this);
1809
+ if (this._config.autoReset && this.isSolved()) this.reset(0);
1745
1810
  });
1746
1811
  return tween;
1747
1812
  }
1748
1813
  updateTweens() {
1749
1814
  this._tweens.update();
1750
1815
  }
1816
+ // set color of core lights
1817
+ setCoreLightColor(color) {
1818
+ const c = new THREE3.Color(color);
1819
+ this._coreLights.forEach((l) => {
1820
+ l.color = c;
1821
+ });
1822
+ }
1823
+ // change intensity of core lights
1824
+ setCoreLightIntensity(intensity) {
1825
+ this._coreLights.forEach((l) => {
1826
+ l.intensity = intensity;
1827
+ });
1828
+ }
1751
1829
  };
1752
1830
  export {
1753
1831
  ArcanumCube,
@@ -1763,6 +1841,7 @@ export {
1763
1841
  FACE,
1764
1842
  GetSkinByName,
1765
1843
  GetSkinNameList,
1844
+ MatchGoalState,
1766
1845
  SIDE_MAX,
1767
1846
  SIDE_MIDDLE,
1768
1847
  SIDE_MIN,