arcanumcube 0.1.0 → 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 +21 -1
- package/dist/cjs/arcanumcube.cjs +135 -30
- package/dist/esm/arcanumcube.module.js +132 -30
- package/dist/esm/arcanumcube.module.min.js +4 -4
- package/dist/index.html +15 -7
- package/dist/types/core.d.ts +3 -0
- package/dist/types/skins.d.ts +2 -0
- package/dist/types/webgl.d.ts +22 -7
- package/package.json +2 -2
|
@@ -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
|
}
|
|
@@ -630,6 +669,12 @@ function createDefaultLogoTexture() {
|
|
|
630
669
|
texture.needsUpdate = true;
|
|
631
670
|
return texture;
|
|
632
671
|
}
|
|
672
|
+
function GetSkinByName(name) {
|
|
673
|
+
return SkinMap[name];
|
|
674
|
+
}
|
|
675
|
+
function GetSkinNameList() {
|
|
676
|
+
return Object.keys(SkinMap);
|
|
677
|
+
}
|
|
633
678
|
var standardSkin = {
|
|
634
679
|
name: "Standard",
|
|
635
680
|
enableEnvMap: false,
|
|
@@ -1128,12 +1173,14 @@ var WebGLCube = class extends Cube {
|
|
|
1128
1173
|
stickerScale: 0.92,
|
|
1129
1174
|
gap: 0.01,
|
|
1130
1175
|
enableShadow: false,
|
|
1131
|
-
skin: DefaultSkin
|
|
1176
|
+
skin: DefaultSkin,
|
|
1177
|
+
wireframe: false,
|
|
1178
|
+
wireframeColor: 32768
|
|
1132
1179
|
};
|
|
1133
1180
|
if (opts) {
|
|
1134
1181
|
Object.assign(this._config, opts);
|
|
1135
1182
|
}
|
|
1136
|
-
this._skin =
|
|
1183
|
+
this._skin = this._config.skin;
|
|
1137
1184
|
}
|
|
1138
1185
|
getGroup() {
|
|
1139
1186
|
return this._group;
|
|
@@ -1167,9 +1214,13 @@ var WebGLCube = class extends Cube {
|
|
|
1167
1214
|
const geo = mesh.geometry.clone();
|
|
1168
1215
|
geo.scale(scale, scale, scale);
|
|
1169
1216
|
const mat = this._skin.cube.material();
|
|
1170
|
-
if (this._skin.enableEnvMap && config.envMap && (mat instanceof THREE3.MeshStandardMaterial || mat instanceof THREE3.MeshBasicMaterial)) {
|
|
1217
|
+
if (this._skin.enableEnvMap && config.envMap && (mat instanceof THREE3.MeshStandardMaterial || mat instanceof THREE3.MeshBasicMaterial || mat instanceof THREE3.MeshPhysicalMaterial)) {
|
|
1171
1218
|
mat.envMap = config.envMap;
|
|
1172
1219
|
}
|
|
1220
|
+
if (config.wireframe) {
|
|
1221
|
+
mat.wireframe = config.wireframe;
|
|
1222
|
+
mat.color = new THREE3.Color(config.wireframeColor);
|
|
1223
|
+
}
|
|
1173
1224
|
const m = new THREE3.Mesh(geo, mat);
|
|
1174
1225
|
m.name = this.type;
|
|
1175
1226
|
for (const r of angles) {
|
|
@@ -1179,6 +1230,7 @@ var WebGLCube = class extends Cube {
|
|
|
1179
1230
|
m.geometry.rotateZ(Math.PI * axis[2] * steps / 2);
|
|
1180
1231
|
}
|
|
1181
1232
|
m.castShadow = config.enableShadow;
|
|
1233
|
+
m.receiveShadow = config.enableShadow;
|
|
1182
1234
|
m.position.x += (x - 1) * CUBE_SIDE_LEN * (1 + config.gap) * scale;
|
|
1183
1235
|
m.position.y += (y - 1) * CUBE_SIDE_LEN * (1 + config.gap) * scale;
|
|
1184
1236
|
m.position.z += (z - 1) * CUBE_SIDE_LEN * (1 + config.gap) * scale;
|
|
@@ -1203,12 +1255,17 @@ var WebGLCube = class extends Cube {
|
|
|
1203
1255
|
pgeo.scale(scale * config.stickerScale, scale, scale * config.stickerScale);
|
|
1204
1256
|
sticker.color = sticker.face;
|
|
1205
1257
|
const pmat = this._skin.sticker.material(x, y, z, sticker.color);
|
|
1206
|
-
if (this._skin.enableEnvMap && config.envMap && (pmat instanceof THREE3.MeshStandardMaterial || pmat instanceof THREE3.MeshBasicMaterial)) {
|
|
1258
|
+
if (this._skin.enableEnvMap && config.envMap && (pmat instanceof THREE3.MeshStandardMaterial || pmat instanceof THREE3.MeshBasicMaterial || pmat instanceof THREE3.MeshPhysicalMaterial)) {
|
|
1207
1259
|
pmat.envMap = config.envMap;
|
|
1208
1260
|
}
|
|
1261
|
+
if (config.wireframe) {
|
|
1262
|
+
pmat.wireframe = config.wireframe;
|
|
1263
|
+
pmat.color = new THREE3.Color(config.wireframeColor);
|
|
1264
|
+
}
|
|
1209
1265
|
const pm = new THREE3.Mesh(pgeo, pmat);
|
|
1210
1266
|
pm.name = CUBE.STICKER;
|
|
1211
1267
|
pm.castShadow = config.enableShadow;
|
|
1268
|
+
m.receiveShadow = config.enableShadow;
|
|
1212
1269
|
const stickerAngle = STICKER_FACE_2_ANGLE[sticker.face];
|
|
1213
1270
|
pm.geometry.rotateX(Math.PI * stickerAngle[0] / 180);
|
|
1214
1271
|
pm.geometry.rotateY(Math.PI * stickerAngle[1] / 180);
|
|
@@ -1293,7 +1350,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1293
1350
|
/** tween group */
|
|
1294
1351
|
_tweens;
|
|
1295
1352
|
/** light at the center of cube */
|
|
1296
|
-
|
|
1353
|
+
_coreLights;
|
|
1297
1354
|
constructor(options) {
|
|
1298
1355
|
super(options);
|
|
1299
1356
|
this._config = {
|
|
@@ -1304,8 +1361,14 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1304
1361
|
stickerScale: 0.92,
|
|
1305
1362
|
gap: 0.01,
|
|
1306
1363
|
enableShadow: false,
|
|
1307
|
-
skin: DefaultSkin
|
|
1308
|
-
|
|
1364
|
+
skin: DefaultSkin,
|
|
1365
|
+
autoReset: true,
|
|
1366
|
+
enableCoreLight: false,
|
|
1367
|
+
coreLightColor: 33023,
|
|
1368
|
+
coreLightIntensity: 30,
|
|
1369
|
+
wireframe: false,
|
|
1370
|
+
wireframeColor: 32768,
|
|
1371
|
+
twistOptions: {}
|
|
1309
1372
|
};
|
|
1310
1373
|
this._matrix = [];
|
|
1311
1374
|
this._group = new THREE3.Group();
|
|
@@ -1313,7 +1376,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1313
1376
|
this._cubeMap = {};
|
|
1314
1377
|
this._cancelDragDeg = 15;
|
|
1315
1378
|
this._tweens = new TWEEN.Group();
|
|
1316
|
-
this.
|
|
1379
|
+
this._coreLights = [];
|
|
1317
1380
|
if (options) {
|
|
1318
1381
|
Object.assign(this._config, options);
|
|
1319
1382
|
}
|
|
@@ -1324,11 +1387,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1324
1387
|
getCubeObjectList() {
|
|
1325
1388
|
return this._cubeObjectList;
|
|
1326
1389
|
}
|
|
1327
|
-
static getSkinNameList() {
|
|
1328
|
-
return Object.keys(SkinMap);
|
|
1329
|
-
}
|
|
1330
1390
|
async init() {
|
|
1331
|
-
const skin =
|
|
1391
|
+
const skin = this._config.skin;
|
|
1332
1392
|
if (skin.modelLoading) {
|
|
1333
1393
|
this._init();
|
|
1334
1394
|
} else {
|
|
@@ -1342,7 +1402,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1342
1402
|
this._cubeMap = {};
|
|
1343
1403
|
this._matrix = [];
|
|
1344
1404
|
this._history = [];
|
|
1345
|
-
this.
|
|
1405
|
+
this._coreLights = [];
|
|
1346
1406
|
const fixedGroups = new THREE3.Group();
|
|
1347
1407
|
const config = this._config;
|
|
1348
1408
|
const yarray = [];
|
|
@@ -1357,7 +1417,9 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1357
1417
|
gap: config.gap,
|
|
1358
1418
|
enableShadow: config.enableShadow,
|
|
1359
1419
|
skin: config.skin,
|
|
1360
|
-
envMap: config.envMap
|
|
1420
|
+
envMap: config.envMap,
|
|
1421
|
+
wireframe: config.wireframe,
|
|
1422
|
+
wireframeColor: config.wireframeColor
|
|
1361
1423
|
});
|
|
1362
1424
|
cube.init();
|
|
1363
1425
|
xarray.push(cube);
|
|
@@ -1365,13 +1427,18 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1365
1427
|
this._cubeObjectList.push(entityGroup);
|
|
1366
1428
|
this._cubeMap[entityGroup.id] = cube;
|
|
1367
1429
|
fixedGroups.add(cube.getGroup());
|
|
1368
|
-
if (config.
|
|
1430
|
+
if (config.enableCoreLight) {
|
|
1369
1431
|
if (x !== SIDE_MIN && y !== SIDE_MIN && z !== SIDE_MIN) {
|
|
1370
|
-
const light = new THREE3.PointLight(
|
|
1432
|
+
const light = new THREE3.PointLight(
|
|
1433
|
+
config.wireframe ? config.wireframeColor : config.coreLightColor,
|
|
1434
|
+
config.coreLightIntensity,
|
|
1435
|
+
20,
|
|
1436
|
+
0.1
|
|
1437
|
+
);
|
|
1371
1438
|
light.position.x = (x - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
|
|
1372
1439
|
light.position.y = (y - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
|
|
1373
1440
|
light.position.z += (z - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
|
|
1374
|
-
this.
|
|
1441
|
+
this._coreLights.push(light);
|
|
1375
1442
|
}
|
|
1376
1443
|
}
|
|
1377
1444
|
}
|
|
@@ -1381,14 +1448,14 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1381
1448
|
}
|
|
1382
1449
|
this._matrix = yarray;
|
|
1383
1450
|
this._group.clear();
|
|
1384
|
-
if (config.
|
|
1385
|
-
this.
|
|
1451
|
+
if (config.enableCoreLight) {
|
|
1452
|
+
this._coreLights.forEach((light) => {
|
|
1386
1453
|
this._group.add(light);
|
|
1387
1454
|
});
|
|
1388
1455
|
}
|
|
1389
1456
|
this._group.add(fixedGroups);
|
|
1390
1457
|
}
|
|
1391
|
-
async setSkin(
|
|
1458
|
+
async setSkin(skin) {
|
|
1392
1459
|
const dispose = (obj) => {
|
|
1393
1460
|
if (obj instanceof THREE3.Group) {
|
|
1394
1461
|
for (const o of obj.children) {
|
|
@@ -1400,7 +1467,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1400
1467
|
obj.geometry.dispose();
|
|
1401
1468
|
}
|
|
1402
1469
|
};
|
|
1403
|
-
this._config.skin =
|
|
1470
|
+
this._config.skin = skin;
|
|
1404
1471
|
for (const obj of this._group.children) {
|
|
1405
1472
|
dispose(obj);
|
|
1406
1473
|
}
|
|
@@ -1584,8 +1651,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1584
1651
|
}
|
|
1585
1652
|
}
|
|
1586
1653
|
this._group.clear();
|
|
1587
|
-
if (this._config.
|
|
1588
|
-
this.
|
|
1654
|
+
if (this._config.enableCoreLight) {
|
|
1655
|
+
this._coreLights.forEach((light) => {
|
|
1589
1656
|
this._group.add(light);
|
|
1590
1657
|
});
|
|
1591
1658
|
}
|
|
@@ -1622,7 +1689,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1622
1689
|
// twist randomly several steps
|
|
1623
1690
|
scramble(steps = 0, duration = 3e3) {
|
|
1624
1691
|
const list = getRandomTwistList(steps);
|
|
1625
|
-
this.tweenTwist(list, false, duration);
|
|
1692
|
+
this.tweenTwist(list, false, duration, false);
|
|
1626
1693
|
}
|
|
1627
1694
|
undo(steps = 1, duration = 300) {
|
|
1628
1695
|
const list = this.getUndoList(steps);
|
|
@@ -1630,17 +1697,25 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1630
1697
|
}
|
|
1631
1698
|
// twisting(複数回対応)
|
|
1632
1699
|
// durationを0にするとTweenなしとなる
|
|
1633
|
-
tweenTwist(twist, reverse = false, duration = 500, cancel = false) {
|
|
1700
|
+
tweenTwist(twist, reverse = false, duration = 500, cancel = false, options) {
|
|
1634
1701
|
if (this._tweens.getAll().length > 0) return;
|
|
1702
|
+
if (options == null) options = this._config.twistOptions;
|
|
1635
1703
|
if (duration === 0) {
|
|
1636
1704
|
if (Array.isArray(twist)) {
|
|
1637
1705
|
if (twist.length == 0) return;
|
|
1638
|
-
|
|
1706
|
+
options?.onStart && options.onStart(this);
|
|
1707
|
+
const len = twist.length;
|
|
1708
|
+
for (let i = 0; i < len; i++) {
|
|
1709
|
+
const c = twist[i];
|
|
1639
1710
|
this._immediatelyTwist(c, reverse);
|
|
1711
|
+
options?.onTwisted && options.onTwisted(this, c, i + 1, len);
|
|
1640
1712
|
}
|
|
1641
1713
|
} else {
|
|
1714
|
+
options?.onStart && options.onStart(this);
|
|
1642
1715
|
this._immediatelyTwist(twist, reverse);
|
|
1716
|
+
options?.onTwisted && options.onTwisted(this, twist, 1, 1);
|
|
1643
1717
|
}
|
|
1718
|
+
options?.onComplete && options.onComplete(this);
|
|
1644
1719
|
return;
|
|
1645
1720
|
}
|
|
1646
1721
|
let firstTween = void 0;
|
|
@@ -1648,8 +1723,15 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1648
1723
|
if (Array.isArray(twist)) {
|
|
1649
1724
|
if (twist.length == 0) return;
|
|
1650
1725
|
const lap = duration / twist.length;
|
|
1651
|
-
|
|
1652
|
-
|
|
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);
|
|
1653
1735
|
this._tweens.add(t);
|
|
1654
1736
|
if (!tween) {
|
|
1655
1737
|
firstTween = tween = t;
|
|
@@ -1659,10 +1741,11 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1659
1741
|
}
|
|
1660
1742
|
}
|
|
1661
1743
|
} else {
|
|
1662
|
-
firstTween = this._tweenTwist(twist, reverse, duration, cancel);
|
|
1744
|
+
firstTween = this._tweenTwist(twist, reverse, duration, cancel, options);
|
|
1663
1745
|
this._tweens.add(firstTween);
|
|
1664
1746
|
}
|
|
1665
1747
|
if (firstTween) {
|
|
1748
|
+
options?.onStart && options.onStart(this);
|
|
1666
1749
|
firstTween.start();
|
|
1667
1750
|
}
|
|
1668
1751
|
}
|
|
@@ -1684,7 +1767,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1684
1767
|
super.twist(twist, reverse);
|
|
1685
1768
|
}
|
|
1686
1769
|
// twist with tween
|
|
1687
|
-
_tweenTwist(twist, reverse, duration, cancel) {
|
|
1770
|
+
_tweenTwist(twist, reverse, duration, cancel, options = {}) {
|
|
1688
1771
|
let qa;
|
|
1689
1772
|
if (this._draggingTwist) {
|
|
1690
1773
|
this._twistGroup = this._draggingTwist.group;
|
|
@@ -1721,12 +1804,28 @@ var WebGLArcanumCube = class extends ArcanumCube {
|
|
|
1721
1804
|
super.twist(twist, reverse);
|
|
1722
1805
|
}
|
|
1723
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);
|
|
1724
1810
|
});
|
|
1725
1811
|
return tween;
|
|
1726
1812
|
}
|
|
1727
1813
|
updateTweens() {
|
|
1728
1814
|
this._tweens.update();
|
|
1729
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
|
+
}
|
|
1730
1829
|
};
|
|
1731
1830
|
export {
|
|
1732
1831
|
ArcanumCube,
|
|
@@ -1740,6 +1839,9 @@ export {
|
|
|
1740
1839
|
DefaultModel,
|
|
1741
1840
|
DefaultSkin,
|
|
1742
1841
|
FACE,
|
|
1842
|
+
GetSkinByName,
|
|
1843
|
+
GetSkinNameList,
|
|
1844
|
+
MatchGoalState,
|
|
1743
1845
|
SIDE_MAX,
|
|
1744
1846
|
SIDE_MIDDLE,
|
|
1745
1847
|
SIDE_MIN,
|