@houstonp/rubiks-cube 1.5.2 → 2.0.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/README.md +100 -194
- package/package.json +33 -3
- package/src/cameraState.js +81 -0
- package/src/core.js +127 -0
- package/src/cube/cube.js +123 -75
- package/src/cube/cubeRotation.js +26 -10
- package/src/cube/cubeSettings.js +18 -0
- package/src/cube/cubeState.js +1 -0
- package/src/cube/slice.js +143 -0
- package/src/debouncer.js +16 -0
- package/src/globals.ts +9 -0
- package/src/index.js +496 -0
- package/src/schema.js +22 -0
- package/src/settings.js +126 -0
- package/src/threejs/materials.js +52 -40
- package/src/threejs/pieces.js +1 -4
- package/src/threejs/stickers.js +18 -26
- package/types/cameraState.d.ts +19 -0
- package/types/core.d.ts +125 -0
- package/types/cube/cube.d.ts +102 -0
- package/types/cube/cubeRotation.d.ts +33 -0
- package/types/cube/cubeSettings.d.ts +17 -0
- package/types/cube/cubeState.d.ts +16 -0
- package/types/cube/slice.d.ts +15 -0
- package/types/debouncer.d.ts +13 -0
- package/types/globals.d.ts +7 -0
- package/types/index.d.ts +65 -0
- package/types/schema.d.ts +11 -0
- package/types/settings.d.ts +34 -0
- package/types/threejs/materials.d.ts +21 -0
- package/types/threejs/pieces.d.ts +28 -0
- package/types/threejs/stickers.d.ts +6 -0
- package/.prettierrc +0 -7
- package/index.js +0 -274
- package/src/utils/debouncer.js +0 -7
- package/src/utils/rotation.js +0 -53
package/src/threejs/materials.js
CHANGED
|
@@ -1,42 +1,54 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { MeshStandardMaterial, MeshBasicMaterial } from 'three';
|
|
3
|
+
import { FaceColours, Faces } from '../core';
|
|
4
|
+
/** @typedef {{type: "sticker", face: import('../core').Face , color: import('../core').FaceColour}} StickerUserData */
|
|
5
|
+
/** @typedef {{type: "core" }} CoreUserData */
|
|
2
6
|
export default class Materials {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
7
|
+
static front = new MeshStandardMaterial({
|
|
8
|
+
color: '#2cbf13',
|
|
9
|
+
metalness: 0,
|
|
10
|
+
roughness: 0.4,
|
|
11
|
+
/** @type {StickerUserData} */
|
|
12
|
+
userData: { type: 'sticker', face: Faces.front, color: FaceColours.front },
|
|
13
|
+
});
|
|
14
|
+
static back = new MeshStandardMaterial({
|
|
15
|
+
color: 'blue',
|
|
16
|
+
metalness: 0,
|
|
17
|
+
roughness: 0.4,
|
|
18
|
+
/** @type {StickerUserData} */
|
|
19
|
+
userData: { type: 'sticker', face: Faces.back, color: FaceColours.back },
|
|
20
|
+
});
|
|
21
|
+
static up = new MeshStandardMaterial({
|
|
22
|
+
color: 'white',
|
|
23
|
+
metalness: 0,
|
|
24
|
+
roughness: 0.4,
|
|
25
|
+
/** @type {StickerUserData} */
|
|
26
|
+
userData: { type: 'sticker', face: Faces.up, color: FaceColours.up },
|
|
27
|
+
});
|
|
28
|
+
static down = new MeshStandardMaterial({
|
|
29
|
+
color: 'yellow',
|
|
30
|
+
metalness: 0,
|
|
31
|
+
roughness: 0.4,
|
|
32
|
+
/** @type {StickerUserData} */
|
|
33
|
+
userData: { type: 'sticker', face: Faces.down, color: FaceColours.down },
|
|
34
|
+
});
|
|
35
|
+
static left = new MeshStandardMaterial({
|
|
36
|
+
color: '#fc9a05',
|
|
37
|
+
metalness: 0,
|
|
38
|
+
roughness: 0.4,
|
|
39
|
+
/** @type {StickerUserData} */
|
|
40
|
+
userData: { type: 'sticker', face: Faces.left, color: FaceColours.left },
|
|
41
|
+
});
|
|
42
|
+
static right = new MeshStandardMaterial({
|
|
43
|
+
color: 'red',
|
|
44
|
+
metalness: 0,
|
|
45
|
+
roughness: 0.4,
|
|
46
|
+
/** @type {StickerUserData} */
|
|
47
|
+
userData: { type: 'sticker', face: Faces.right, color: FaceColours.right },
|
|
48
|
+
});
|
|
49
|
+
static core = new MeshBasicMaterial({
|
|
50
|
+
color: 'black',
|
|
51
|
+
/** @type {CoreUserData} */
|
|
52
|
+
userData: { type: 'core' },
|
|
53
|
+
});
|
|
42
54
|
}
|
package/src/threejs/pieces.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import { Group, BoxGeometry, Mesh, SphereGeometry, Material } from 'three';
|
|
2
3
|
import Stickers from './stickers';
|
|
3
4
|
import Materials from './materials';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
|
-
* @param {Geometry} sticker
|
|
7
7
|
* @param {Material} frontMaterial
|
|
8
8
|
* @param {Material} rightMaterial
|
|
9
9
|
* @param {Material} topMaterial
|
|
@@ -42,7 +42,6 @@ export function createCornerGroup(frontMaterial, rightMaterial, topMaterial, cor
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
-
* @param {Geometry} sticker
|
|
46
45
|
* @param {Material} frontMaterial
|
|
47
46
|
* @param {Material} topMaterial
|
|
48
47
|
* @param {Material} coreMaterial
|
|
@@ -73,9 +72,7 @@ export function createEdgeGroup(frontMaterial, topMaterial, coreMaterial) {
|
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
/**
|
|
76
|
-
* @param {Geometry} sticker
|
|
77
75
|
* @param {Material} frontMaterial
|
|
78
|
-
* @param {Material} topMaterial
|
|
79
76
|
* @param {Material} coreMaterial
|
|
80
77
|
* @returns {Group}
|
|
81
78
|
*/
|
package/src/threejs/stickers.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { SVGLoader } from 'three/examples/jsm/Addons.js';
|
|
3
|
+
import { ExtrudeGeometry } from 'three';
|
|
3
4
|
|
|
4
5
|
const loader = new SVGLoader();
|
|
5
6
|
const cornerSVG = loader.parse(`
|
|
@@ -19,30 +20,21 @@ const centerSVG = loader.parse(`
|
|
|
19
20
|
`);
|
|
20
21
|
|
|
21
22
|
export default class Stickers {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
28
|
-
.scale(0.002, 0.002, 0.002)
|
|
29
|
-
.translate(-0.5, -0.5, 0);
|
|
23
|
+
static center = new ExtrudeGeometry(SVGLoader.createShapes(centerSVG.paths[0])[0], {
|
|
24
|
+
depth: 15,
|
|
25
|
+
})
|
|
26
|
+
.scale(0.002, 0.002, 0.002)
|
|
27
|
+
.translate(-0.5, -0.5, 0);
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
)
|
|
37
|
-
.scale(0.002, 0.002, 0.002)
|
|
38
|
-
.translate(-0.5, -0.5, 0);
|
|
29
|
+
static edge = new ExtrudeGeometry(SVGLoader.createShapes(edgeSVG.paths[0])[0], {
|
|
30
|
+
depth: 15,
|
|
31
|
+
})
|
|
32
|
+
.scale(0.002, 0.002, 0.002)
|
|
33
|
+
.translate(-0.5, -0.5, 0);
|
|
39
34
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
)
|
|
46
|
-
.scale(0.002, 0.002, 0.002)
|
|
47
|
-
.translate(-0.5, -0.5, 0);
|
|
35
|
+
static corner = new ExtrudeGeometry(SVGLoader.createShapes(cornerSVG.paths[0])[0], {
|
|
36
|
+
depth: 15,
|
|
37
|
+
})
|
|
38
|
+
.scale(0.002, 0.002, 0.002)
|
|
39
|
+
.translate(-0.5, -0.5, 0);
|
|
48
40
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class CameraState {
|
|
2
|
+
/**
|
|
3
|
+
* @param {boolean} up
|
|
4
|
+
* @param {boolean} right
|
|
5
|
+
*/
|
|
6
|
+
constructor(up?: boolean, right?: boolean);
|
|
7
|
+
/** @type {boolean} */
|
|
8
|
+
Up: boolean;
|
|
9
|
+
/** @type {boolean} */
|
|
10
|
+
Right: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* @param {import("./core").PeekType} peekType
|
|
13
|
+
*/
|
|
14
|
+
peekCamera(peekType: import("./core").PeekType): void;
|
|
15
|
+
/**
|
|
16
|
+
* @returns {import("./core").PeekState}
|
|
17
|
+
*/
|
|
18
|
+
toPeekState(): import("./core").PeekState;
|
|
19
|
+
}
|
package/types/core.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {typeof Movements[keyof typeof Movements]} Movement
|
|
3
|
+
*/
|
|
4
|
+
export const Movements: Readonly<{
|
|
5
|
+
R: "R";
|
|
6
|
+
R2: "R2";
|
|
7
|
+
RP: "R'";
|
|
8
|
+
L: "L";
|
|
9
|
+
L2: "L2";
|
|
10
|
+
LP: "L'";
|
|
11
|
+
U: "U";
|
|
12
|
+
U2: "U2";
|
|
13
|
+
UP: "U'";
|
|
14
|
+
D: "D";
|
|
15
|
+
D2: "D2";
|
|
16
|
+
DP: "D'";
|
|
17
|
+
F: "F";
|
|
18
|
+
F2: "F2";
|
|
19
|
+
FP: "F'";
|
|
20
|
+
B: "B";
|
|
21
|
+
B2: "B2";
|
|
22
|
+
BP: "B'";
|
|
23
|
+
r: "r";
|
|
24
|
+
r2: "r2";
|
|
25
|
+
rP: "r'";
|
|
26
|
+
l: "l";
|
|
27
|
+
l2: "l2";
|
|
28
|
+
lP: "l'";
|
|
29
|
+
u: "u";
|
|
30
|
+
u2: "u2";
|
|
31
|
+
uP: "u'";
|
|
32
|
+
d: "d";
|
|
33
|
+
d2: "d2";
|
|
34
|
+
dP: "d'";
|
|
35
|
+
f: "f";
|
|
36
|
+
f2: "f2";
|
|
37
|
+
fP: "f'";
|
|
38
|
+
b: "b";
|
|
39
|
+
b2: "b2";
|
|
40
|
+
bP: "b'";
|
|
41
|
+
M: "M";
|
|
42
|
+
M2: "M2";
|
|
43
|
+
MP: "M'";
|
|
44
|
+
E: "E";
|
|
45
|
+
E2: "E2";
|
|
46
|
+
EP: "E'";
|
|
47
|
+
S: "S";
|
|
48
|
+
S2: "S2";
|
|
49
|
+
SP: "S'";
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* @typedef {typeof Rotations[keyof typeof Rotations]} Rotation
|
|
53
|
+
*/
|
|
54
|
+
export const Rotations: Readonly<{
|
|
55
|
+
x: "x";
|
|
56
|
+
x2: "x2";
|
|
57
|
+
xP: "x'";
|
|
58
|
+
y: "y";
|
|
59
|
+
y2: "y2";
|
|
60
|
+
yP: "y'";
|
|
61
|
+
z: "z";
|
|
62
|
+
z2: "z2";
|
|
63
|
+
zP: "z'";
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* @typedef {typeof Axi[keyof typeof Axi]} Axis
|
|
67
|
+
*/
|
|
68
|
+
export const Axi: Readonly<{
|
|
69
|
+
x: "x";
|
|
70
|
+
y: "y";
|
|
71
|
+
z: "z";
|
|
72
|
+
}>;
|
|
73
|
+
/**
|
|
74
|
+
* @typedef {typeof Faces [keyof typeof Faces]} Face
|
|
75
|
+
*/
|
|
76
|
+
export const Faces: Readonly<{
|
|
77
|
+
up: "U";
|
|
78
|
+
down: "D";
|
|
79
|
+
left: "L";
|
|
80
|
+
right: "R";
|
|
81
|
+
front: "F";
|
|
82
|
+
back: "B";
|
|
83
|
+
}>;
|
|
84
|
+
/**
|
|
85
|
+
* @typedef {typeof FaceColours [keyof typeof FaceColours]} FaceColour
|
|
86
|
+
*/
|
|
87
|
+
export const FaceColours: Readonly<{
|
|
88
|
+
up: "white";
|
|
89
|
+
down: "yellow";
|
|
90
|
+
left: "orange";
|
|
91
|
+
right: "red";
|
|
92
|
+
front: "green";
|
|
93
|
+
back: "blue";
|
|
94
|
+
}>;
|
|
95
|
+
/**
|
|
96
|
+
* @typedef {typeof PeekTypes [keyof typeof PeekTypes]} PeekType
|
|
97
|
+
*/
|
|
98
|
+
export const PeekTypes: Readonly<{
|
|
99
|
+
Horizontal: "horizontal";
|
|
100
|
+
Vertical: "vertical";
|
|
101
|
+
Right: "right";
|
|
102
|
+
Left: "left";
|
|
103
|
+
Up: "up";
|
|
104
|
+
Down: "down";
|
|
105
|
+
RightUp: "rightUp";
|
|
106
|
+
RightDown: "rightDown";
|
|
107
|
+
LeftUp: "leftUp";
|
|
108
|
+
LeftDown: "leftDown";
|
|
109
|
+
}>;
|
|
110
|
+
/**
|
|
111
|
+
* @typedef {typeof PeekStates [keyof typeof PeekStates]} PeekState
|
|
112
|
+
*/
|
|
113
|
+
export const PeekStates: Readonly<{
|
|
114
|
+
RightUp: "rightUp";
|
|
115
|
+
RightDown: "rightDown";
|
|
116
|
+
LeftUp: "leftUp";
|
|
117
|
+
LeftDown: "leftDown";
|
|
118
|
+
}>;
|
|
119
|
+
export type Movement = (typeof Movements)[keyof typeof Movements];
|
|
120
|
+
export type Rotation = (typeof Rotations)[keyof typeof Rotations];
|
|
121
|
+
export type Axis = (typeof Axi)[keyof typeof Axi];
|
|
122
|
+
export type Face = (typeof Faces)[keyof typeof Faces];
|
|
123
|
+
export type FaceColour = (typeof FaceColours)[keyof typeof FaceColours];
|
|
124
|
+
export type PeekType = (typeof PeekTypes)[keyof typeof PeekTypes];
|
|
125
|
+
export type PeekState = (typeof PeekStates)[keyof typeof PeekStates];
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/** @typedef {{ up: import('../core').Face[][], down: import('../core').Face[][], front: import('../core').Face[][], back: import('../core').Face[][], left: import('../core').Face[][], right: import('../core').Face[][] }} StickerState*/
|
|
2
|
+
export default class Cube {
|
|
3
|
+
/**
|
|
4
|
+
* @param {CubeSettings} cubeSettings
|
|
5
|
+
*/
|
|
6
|
+
constructor(cubeSettings: CubeSettings);
|
|
7
|
+
/** @type {CubeSettings} */
|
|
8
|
+
cubeSettings: CubeSettings;
|
|
9
|
+
/** @type {Group} */
|
|
10
|
+
group: Group;
|
|
11
|
+
/** @type {Group} */
|
|
12
|
+
rotationGroup: Group;
|
|
13
|
+
/** @type {CubeRotation[]} */
|
|
14
|
+
rotationQueue: CubeRotation[];
|
|
15
|
+
/** @type {CubeRotation | undefined} */
|
|
16
|
+
currentRotation: CubeRotation | undefined;
|
|
17
|
+
/** @type {number | undefined} */
|
|
18
|
+
_matchSpeed: number | undefined;
|
|
19
|
+
/** @type {number} */
|
|
20
|
+
_lastGap: number;
|
|
21
|
+
/** @type {StickerState} */
|
|
22
|
+
currentState: StickerState;
|
|
23
|
+
/**
|
|
24
|
+
* adds threejs objects to group
|
|
25
|
+
*/
|
|
26
|
+
init(): Group<import("three").Object3DEventMap>;
|
|
27
|
+
/**
|
|
28
|
+
* update the cube and continue any rotations
|
|
29
|
+
*/
|
|
30
|
+
update(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Updates the gap of the pieces. To be used when the cube is not rotating
|
|
33
|
+
* @returns {void}
|
|
34
|
+
*/
|
|
35
|
+
updateGap(): void;
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* calculates the current speed of the current rotation in ms.
|
|
39
|
+
* calculation is dependent on animation style and animation speed settings
|
|
40
|
+
* - exponential: speeds up rotations depending on the queue length
|
|
41
|
+
* - next: an animation speed of 0 when there is another animation in the queue
|
|
42
|
+
* - match: will match the speed of rotations to the frequency of key presses.
|
|
43
|
+
* - fixed: will return a constant value
|
|
44
|
+
* @returns {number}
|
|
45
|
+
*/
|
|
46
|
+
getRotationSpeed(): number;
|
|
47
|
+
/**
|
|
48
|
+
* Complete the current rotation and reset the cube
|
|
49
|
+
* @param {(state:string) => boolean} completedCallback
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
52
|
+
reset(completedCallback: (state: string) => boolean): void;
|
|
53
|
+
/**
|
|
54
|
+
* Adds pieces in the rotationGroup back into the main group.
|
|
55
|
+
* @returns {void}
|
|
56
|
+
*/
|
|
57
|
+
clearRotationGroup(): void;
|
|
58
|
+
/**
|
|
59
|
+
* @param {string} eventId
|
|
60
|
+
* @param {import('../core').Rotation} rotation
|
|
61
|
+
* @param {((state: string) => void )} completedCallback
|
|
62
|
+
* @param {((reason: string) => void )} failedCallback
|
|
63
|
+
*/
|
|
64
|
+
rotation(eventId: string, rotation: import("../core").Rotation, completedCallback: ((state: string) => void), failedCallback: ((reason: string) => void)): void;
|
|
65
|
+
/**
|
|
66
|
+
* @param {string} eventId
|
|
67
|
+
* @param {import('../core').Movement} movement
|
|
68
|
+
* @param {((state: string) => void )} completedCallback
|
|
69
|
+
* @param {((reason: string) => void )} failedCallback
|
|
70
|
+
*/
|
|
71
|
+
movement(eventId: string, movement: import("../core").Movement, completedCallback: ((state: string) => void), failedCallback: ((reason: string) => void)): void;
|
|
72
|
+
/**
|
|
73
|
+
* @param {import('./slice').Slice} slice
|
|
74
|
+
* @returns {Object3D[]}
|
|
75
|
+
*/
|
|
76
|
+
getRotationLayer(slice: import("./slice").Slice): Object3D[];
|
|
77
|
+
/**
|
|
78
|
+
* @returns {string}
|
|
79
|
+
*/
|
|
80
|
+
get kociembaState(): string;
|
|
81
|
+
/**
|
|
82
|
+
* @param {StickerState} stickerState
|
|
83
|
+
* @returns {string}
|
|
84
|
+
*/
|
|
85
|
+
toKociemba(stickerState: StickerState): string;
|
|
86
|
+
/**
|
|
87
|
+
* @returns {StickerState}
|
|
88
|
+
*/
|
|
89
|
+
getStickerState(): StickerState;
|
|
90
|
+
}
|
|
91
|
+
export type StickerState = {
|
|
92
|
+
up: import("../core").Face[][];
|
|
93
|
+
down: import("../core").Face[][];
|
|
94
|
+
front: import("../core").Face[][];
|
|
95
|
+
back: import("../core").Face[][];
|
|
96
|
+
left: import("../core").Face[][];
|
|
97
|
+
right: import("../core").Face[][];
|
|
98
|
+
};
|
|
99
|
+
import CubeSettings from './cubeSettings';
|
|
100
|
+
import { Group } from 'three';
|
|
101
|
+
import { CubeRotation } from './cubeRotation';
|
|
102
|
+
import { Object3D } from 'three';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export class CubeRotation {
|
|
2
|
+
/**
|
|
3
|
+
* @param {string} eventId
|
|
4
|
+
* @param {import('./slice').Slice} slice
|
|
5
|
+
* @param {((state: string) => void )} completedCallback
|
|
6
|
+
* @param {((reason: string) => void )} failedCallback
|
|
7
|
+
*/
|
|
8
|
+
constructor(eventId: string, slice: import("./slice").Slice, completedCallback: ((state: string) => void), failedCallback: ((reason: string) => void));
|
|
9
|
+
/** @type {((state: string) => void )} */
|
|
10
|
+
completedCallback: ((state: string) => void);
|
|
11
|
+
/** @type {((reason: string) => void )} */
|
|
12
|
+
failedCallback: ((reason: string) => void);
|
|
13
|
+
/** @type {string} */
|
|
14
|
+
eventId: string;
|
|
15
|
+
/** @type {import('./slice').Slice} */
|
|
16
|
+
slice: import("./slice").Slice;
|
|
17
|
+
/** @type {"pending" | "initialised" | "inProgress" | "complete" | "disposed"} */
|
|
18
|
+
status: "pending" | "initialised" | "inProgress" | "complete" | "disposed";
|
|
19
|
+
/** @type {number} */
|
|
20
|
+
timestampMs: number;
|
|
21
|
+
/** @type {number | undefined} */
|
|
22
|
+
_lastUpdatedTimeMs: number | undefined;
|
|
23
|
+
/** @type {number} */
|
|
24
|
+
_rotationPercentage: number;
|
|
25
|
+
initialise(): void;
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* @param {Group} rotationGroup
|
|
29
|
+
* @param {number} speedMs
|
|
30
|
+
*/
|
|
31
|
+
update(rotationGroup: Group, speedMs: number): void;
|
|
32
|
+
}
|
|
33
|
+
import { Group } from 'three';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** @typedef {"exponential" | "next" | "fixed" | "match"} AnimationStyle */
|
|
2
|
+
export default class CubeSettings {
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number} pieceGap
|
|
6
|
+
* @param {number} animationSpeed
|
|
7
|
+
* @param {AnimationStyle} animationStyle
|
|
8
|
+
*/
|
|
9
|
+
constructor(pieceGap: number, animationSpeed: number, animationStyle: AnimationStyle);
|
|
10
|
+
/** @type {number} pieceGap */
|
|
11
|
+
pieceGap: number;
|
|
12
|
+
/** @type {number} pieceGap */
|
|
13
|
+
animationSpeedMs: number;
|
|
14
|
+
/** @type {AnimationStyle} pieceGap */
|
|
15
|
+
animationStyle: AnimationStyle;
|
|
16
|
+
}
|
|
17
|
+
export type AnimationStyle = "exponential" | "next" | "fixed" | "match";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type vector = {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
z: number;
|
|
5
|
+
};
|
|
6
|
+
export type state = {
|
|
7
|
+
position: vector;
|
|
8
|
+
rotation: vector;
|
|
9
|
+
type: "corner" | "edge" | "center";
|
|
10
|
+
group: Group;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* @return {state[]}
|
|
14
|
+
*/
|
|
15
|
+
export function createCubeState(): state[];
|
|
16
|
+
import { Group } from 'three';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {import("../core").Movement} movement
|
|
3
|
+
* @returns {Slice}
|
|
4
|
+
*/
|
|
5
|
+
export default function GetMovementSlice(movement: import("../core").Movement): Slice;
|
|
6
|
+
/**
|
|
7
|
+
* @param {import("../core").Rotation} rotation
|
|
8
|
+
* @returns {Slice}
|
|
9
|
+
*/
|
|
10
|
+
export function GetRotationSlice(rotation: import("../core").Rotation): Slice;
|
|
11
|
+
export type Slice = {
|
|
12
|
+
axis: import("../core").Axis;
|
|
13
|
+
layers: (-1 | 0 | 1)[];
|
|
14
|
+
direction: 1 | -1 | 2 | -2;
|
|
15
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {number} delay
|
|
3
|
+
* @param {{ (entries: { contentRect: { width: number; height: number; }; }[]): void; apply?: any; }} f
|
|
4
|
+
*/
|
|
5
|
+
export function debounce(f: {
|
|
6
|
+
(entries: {
|
|
7
|
+
contentRect: {
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
};
|
|
11
|
+
}[]): void;
|
|
12
|
+
apply?: any;
|
|
13
|
+
}, delay: number): (...args: any[]) => void;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/// <reference path="globals.d.ts" preserve="true" />
|
|
2
|
+
export class RubiksCubeElement extends HTMLElement {
|
|
3
|
+
/**
|
|
4
|
+
* @param {string} tagName the name of the tag to register the web component under
|
|
5
|
+
*/
|
|
6
|
+
static register(tagName?: string): void;
|
|
7
|
+
static get observedAttributes(): ("piece-gap" | "animation-speed-ms" | "animation-style" | "camera-speed-ms" | "camera-radius" | "camera-field-of-view" | "camera-peek-angle-horizontal" | "camera-peek-angle-vertical")[];
|
|
8
|
+
/** @private @type {HTMLCanvasElement} */
|
|
9
|
+
private canvas;
|
|
10
|
+
/** @private @type {Settings} */
|
|
11
|
+
private settings;
|
|
12
|
+
/** @private @type {CubeSettings} */
|
|
13
|
+
private cubeSettings;
|
|
14
|
+
/**
|
|
15
|
+
* @param {string} name
|
|
16
|
+
* @param {string} oldVal
|
|
17
|
+
* @param {string} newVal
|
|
18
|
+
* */
|
|
19
|
+
attributeChangedCallback(name: string, oldVal: string, newVal: string): void;
|
|
20
|
+
connectedCallback(): void;
|
|
21
|
+
/** @private */
|
|
22
|
+
private animateCameraSetting;
|
|
23
|
+
/** @private */
|
|
24
|
+
private updateCameraFOV;
|
|
25
|
+
/** @import {Movement} from './core' */
|
|
26
|
+
/** @internal @typedef {{eventId: string, move: Movement}} MovementEvent */
|
|
27
|
+
/** @internal @typedef {{eventId: string, move: Movement, state: string}} MovementCompleteEventData */
|
|
28
|
+
/** @internal @typedef {{eventId: string, move: Movement, reason: string}} MovementFailedEventData */
|
|
29
|
+
/**
|
|
30
|
+
* @param {Movement} move
|
|
31
|
+
* @returns {Promise<string>}
|
|
32
|
+
*/
|
|
33
|
+
move(move: Movement): Promise<string>;
|
|
34
|
+
/** @import {Rotation} from './core' */
|
|
35
|
+
/** @internal @typedef {{eventId: string, rotation: Rotation}} RotationEventData */
|
|
36
|
+
/** @internal @typedef {{eventId: string, rotation: Rotation, state: string, }} RotationCompleteEventData*/
|
|
37
|
+
/** @internal @typedef {{eventId: string, rotation: Rotation, reason: string, }} RotationFailedEventData*/
|
|
38
|
+
/**
|
|
39
|
+
* @param {Rotation} rotation
|
|
40
|
+
* @returns {Promise<string>}
|
|
41
|
+
*/
|
|
42
|
+
rotate(rotation: Rotation): Promise<string>;
|
|
43
|
+
/** @internal @typedef {{state: string }} ResetCompleteEventData */
|
|
44
|
+
/**
|
|
45
|
+
* @returns {Promise<string>}
|
|
46
|
+
*/
|
|
47
|
+
reset(): Promise<string>;
|
|
48
|
+
/** @import {PeekType} from './core' */
|
|
49
|
+
/** @internal @typedef {{eventId: string, peekType: PeekType}} CameraPeekEventData */
|
|
50
|
+
/** @import {PeekState} from './core' */
|
|
51
|
+
/** @internal @typedef {{eventId: string, peekState: PeekState }} CameraPeekCompleteEventData */
|
|
52
|
+
/**
|
|
53
|
+
* This function changes the camera position to one of four states depending on the arguments passed.
|
|
54
|
+
*
|
|
55
|
+
* @param {PeekType} peekType
|
|
56
|
+
* @returns {Promise<PeekState>}
|
|
57
|
+
*/
|
|
58
|
+
peek(peekType: PeekType): Promise<PeekState>;
|
|
59
|
+
/** @private */
|
|
60
|
+
private init;
|
|
61
|
+
}
|
|
62
|
+
import type { Movement } from './core';
|
|
63
|
+
import type { Rotation } from './core';
|
|
64
|
+
import type { PeekType } from './core';
|
|
65
|
+
import type { PeekState } from './core';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export namespace AttributeNames {
|
|
2
|
+
let pieceGap: "piece-gap";
|
|
3
|
+
let animationSpeed: "animation-speed-ms";
|
|
4
|
+
let animationStyle: "animation-style";
|
|
5
|
+
let cameraSpeed: "camera-speed-ms";
|
|
6
|
+
let cameraRadius: "camera-radius";
|
|
7
|
+
let cameraFieldOfView: "camera-field-of-view";
|
|
8
|
+
let cameraPeekAngleHorizontal: "camera-peek-angle-horizontal";
|
|
9
|
+
let cameraPeekAngleVertical: "camera-peek-angle-vertical";
|
|
10
|
+
}
|
|
11
|
+
export type AttributeName = (typeof AttributeNames)[keyof typeof AttributeNames];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export default class Settings {
|
|
2
|
+
/** @type {number} */
|
|
3
|
+
pieceGap: number;
|
|
4
|
+
/** @type {number} */
|
|
5
|
+
animationSpeedMs: number;
|
|
6
|
+
/** @type {import("./cube/cubeSettings").AnimationStyle} */
|
|
7
|
+
animationStyle: import("./cube/cubeSettings").AnimationStyle;
|
|
8
|
+
/** @type {number} */
|
|
9
|
+
cameraSpeedMs: number;
|
|
10
|
+
/** @type {number} */
|
|
11
|
+
cameraRadius: number;
|
|
12
|
+
/** @type {number} */
|
|
13
|
+
cameraFieldOfView: number;
|
|
14
|
+
/** @type {number} */
|
|
15
|
+
cameraPeekAngleHorizontal: number;
|
|
16
|
+
/** @type {number} */
|
|
17
|
+
cameraPeekAngleVertical: number;
|
|
18
|
+
/** @param {string | null} value*/
|
|
19
|
+
setPieceGap(value: string | null): void;
|
|
20
|
+
/** @param {string | null} value in ms */
|
|
21
|
+
setAnimationSpeed(value: string | null): void;
|
|
22
|
+
/** @param {string | null} value */
|
|
23
|
+
setAnimationStyle(value: string | null): void;
|
|
24
|
+
/** @param {string | null} value in ms */
|
|
25
|
+
setCameraSpeed(value: string | null): void;
|
|
26
|
+
/** @param {string | null} value */
|
|
27
|
+
setCameraRadius(value: string | null): void;
|
|
28
|
+
/** @param {string | null} value in ms */
|
|
29
|
+
setCameraPeekAngleHorizontal(value: string | null): void;
|
|
30
|
+
/** @param {string | null} value in ms */
|
|
31
|
+
setCameraPeekAngleVertical(value: string | null): void;
|
|
32
|
+
/** @param {string | null} value in ms */
|
|
33
|
+
setCameraFieldOfView(value: string | null): void;
|
|
34
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** @typedef {{type: "sticker", face: import('../core').Face , color: import('../core').FaceColour}} StickerUserData */
|
|
2
|
+
/** @typedef {{type: "core" }} CoreUserData */
|
|
3
|
+
export default class Materials {
|
|
4
|
+
static front: MeshStandardMaterial;
|
|
5
|
+
static back: MeshStandardMaterial;
|
|
6
|
+
static up: MeshStandardMaterial;
|
|
7
|
+
static down: MeshStandardMaterial;
|
|
8
|
+
static left: MeshStandardMaterial;
|
|
9
|
+
static right: MeshStandardMaterial;
|
|
10
|
+
static core: MeshBasicMaterial;
|
|
11
|
+
}
|
|
12
|
+
export type StickerUserData = {
|
|
13
|
+
type: "sticker";
|
|
14
|
+
face: import("../core").Face;
|
|
15
|
+
color: import("../core").FaceColour;
|
|
16
|
+
};
|
|
17
|
+
export type CoreUserData = {
|
|
18
|
+
type: "core";
|
|
19
|
+
};
|
|
20
|
+
import { MeshStandardMaterial } from 'three';
|
|
21
|
+
import { MeshBasicMaterial } from 'three';
|