@houstonp/rubiks-cube 1.5.1 → 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 +34 -4
- 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/README.md
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
# Rubiks Cube Web Component
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A Rubik’s Cube web component built with Three.js, WebGPU, and GSAP. The cube renders into a shadow‑DOM canvas and exposes a small, promise‑based API for cube moves, rotations, reset, and camera “peek” positions.
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
This package is published as `@houstonp/rubiks-cube`.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun add @houstonp/rubiks-cube
|
|
13
|
+
# or
|
|
14
|
+
npm install @houstonp/rubiks-cube
|
|
15
|
+
```
|
|
16
|
+
|
|
7
17
|
## Adding the component
|
|
8
18
|
|
|
9
|
-
|
|
10
|
-
by adding the webcomponent tag.
|
|
19
|
+
Register the custom element and then use the tag in your HTML.
|
|
11
20
|
|
|
12
21
|
```js
|
|
13
|
-
//index.js
|
|
14
|
-
import '@houstonp/rubiks-cube';
|
|
22
|
+
// index.js
|
|
23
|
+
import { RubiksCubeElement } from '@houstonp/rubiks-cube';
|
|
24
|
+
|
|
25
|
+
// Registers <rubiks-cube> (you can pass a different tag name if you prefer)
|
|
26
|
+
RubiksCubeElement.register();
|
|
15
27
|
```
|
|
16
28
|
|
|
17
29
|
```html
|
|
@@ -19,84 +31,98 @@ import '@houstonp/rubiks-cube';
|
|
|
19
31
|
<html lang="en">
|
|
20
32
|
<head>
|
|
21
33
|
<meta charset="utf-8" />
|
|
34
|
+
<title>Rubiks Cube Demo</title>
|
|
22
35
|
</head>
|
|
23
36
|
<body>
|
|
24
|
-
<rubiks-cube animation-speed-ms="1000" animation-style="exponential" piece-gap="1.04" camera-speed="100"
|
|
37
|
+
<rubiks-cube animation-speed-ms="1000" animation-style="exponential" piece-gap="1.04" camera-speed-ms="100"></rubiks-cube>
|
|
38
|
+
|
|
25
39
|
<script type="module" src="index.js"></script>
|
|
26
40
|
</body>
|
|
27
41
|
</html>
|
|
28
42
|
```
|
|
29
43
|
|
|
30
|
-
##
|
|
44
|
+
## Component attributes
|
|
45
|
+
|
|
46
|
+
These attributes control animation, spacing, and camera behavior. The available attributes
|
|
47
|
+
can be imported so that they can be get and set easily.
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
import { Attributes } from '@houstonp/rubiks-cube/schema';
|
|
31
51
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
| piece-gap | greater than 1 | sets the gap between rubiks cube pieces |
|
|
37
|
-
| camera-speed-ms | greater than or equal to 0 | sets the duration of camera animations in milliseconds |
|
|
38
|
-
| camera-radius | greater than or equal to 4 | sets the camera radius |
|
|
39
|
-
| camera-peek-angle-horizontal | decimal between 0 and 1 | sets the horizontal peek angle |
|
|
40
|
-
| camera-peek-angle-vertical | decimal between 0 and 1 | sets the vertical peek angle |
|
|
41
|
-
| camera-field-of-view | integer between 40 and 100 | sets the fielf of view of the camera |
|
|
52
|
+
const cube = document.querySelector('rubiks-cube');
|
|
53
|
+
const animationSpeed = cube.getAttribute(AttributeNames.animationSpeed);
|
|
54
|
+
cube.getAttribute(AttributeNames.animationSpeed, animationSpeed + 1);
|
|
55
|
+
```
|
|
42
56
|
|
|
43
|
-
|
|
57
|
+
| attribute | accepted values | Description |
|
|
58
|
+
| ---------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
59
|
+
| animation-speed-ms | integer greater than or equal to 0 | Sets the duration of cube animations in milliseconds |
|
|
60
|
+
| animation-style | `"exponential"`, `"next"`, `"fixed"`, `"match"` | `fixed`: fixed animation lengths, `next`: skips to next animation, `exponential`: speeds up successive animations, `match`: matches the speed to the frequency of events |
|
|
61
|
+
| piece-gap | greater than 1 | Sets the gap between Rubik’s Cube pieces |
|
|
62
|
+
| camera-speed-ms | greater than or equal to 0 | Sets the duration of camera animations in milliseconds |
|
|
63
|
+
| camera-radius | greater than or equal to 4 | Sets the camera radius |
|
|
64
|
+
| camera-peek-angle-horizontal | decimal between 0 and 1 | Sets the horizontal peek angle |
|
|
65
|
+
| camera-peek-angle-vertical | decimal between 0 and 1 | Sets the vertical peek angle |
|
|
66
|
+
| camera-field-of-view | integer between 40 and 100 | Sets the field of view of the camera |
|
|
44
67
|
|
|
45
|
-
|
|
68
|
+
## Programmatic control
|
|
46
69
|
|
|
47
|
-
|
|
70
|
+
The `RubiksCubeElement` instance exposes async methods that return the cube state after the operation completes:
|
|
48
71
|
|
|
49
72
|
```js
|
|
73
|
+
import { RubiksCubeElement } from '@houstonp/rubiks-cube';
|
|
50
74
|
const cube = document.querySelector('rubiks-cube');
|
|
51
|
-
|
|
52
|
-
|
|
75
|
+
|
|
76
|
+
// Reset the cube; resolves with the new state string
|
|
77
|
+
const stateAfterReset = await cube.reset();
|
|
78
|
+
|
|
79
|
+
// Perform a move (see “Rubiks Cube Notation” below for allowed moves)
|
|
80
|
+
// The concrete Movement/Rotation types are exported from the package types.
|
|
81
|
+
cube.move(move).then((state) => {
|
|
82
|
+
console.log('state after move:', state);
|
|
53
83
|
});
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
[sticker, sticker, sticker],
|
|
77
|
-
],
|
|
78
|
-
front: [
|
|
79
|
-
[sticker, sticker, sticker],
|
|
80
|
-
[sticker, sticker, sticker],
|
|
81
|
-
[sticker, sticker, sticker],
|
|
82
|
-
],
|
|
83
|
-
back: [
|
|
84
|
-
[sticker, sticker, sticker],
|
|
85
|
-
[sticker, sticker, sticker],
|
|
86
|
-
[sticker, sticker, sticker],
|
|
87
|
-
],
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
*/
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Available methods:
|
|
87
|
+
|
|
88
|
+
- `cube.move(move)` – performs a cube movement and resolves with the new state string.
|
|
89
|
+
- `cube.rotate(rotation)` – rotates the entire cube and resolves with the new state string.
|
|
90
|
+
- `cube.reset()` – resets the cube to the solved state and resolves with the new state string.
|
|
91
|
+
- `cube.peek(peekType)` – animates the camera to a new “peek” position and resolves with the new peek state.
|
|
92
|
+
|
|
93
|
+
All methods time out and reject if the underlying animation does not complete within an expected window.
|
|
94
|
+
|
|
95
|
+
## Camera Actions
|
|
96
|
+
|
|
97
|
+
The camera position can be changed with the peek method available on the component.
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
import { RubiksCubeElement } from '@houstonp/rubiks-cube';
|
|
101
|
+
import { Rotations, Movements, PeekTypes, PeekState } from '@houstonp/rubiks-cube/core';
|
|
102
|
+
|
|
103
|
+
const cube = document.querySelector('rubiks-cube');
|
|
104
|
+
cube.peek(PeekTypes.right);
|
|
105
|
+
cube.peek(PeekState.rightUp);
|
|
91
106
|
```
|
|
92
107
|
|
|
93
108
|
## Rubiks Cube Notation
|
|
94
109
|
|
|
95
|
-
Notations can include the number of
|
|
110
|
+
Notations can include the number of rotations of a face. For example, `U2` means rotate the upper face 180 degrees.
|
|
96
111
|
|
|
97
|
-
|
|
112
|
+
Notations can also include a prime symbol `'` to indicate a counter‑clockwise rotation. For example, `U'` means rotate the upper face counter‑clockwise. The direction is always determined relative to the face being moved.
|
|
98
113
|
|
|
99
|
-
When both a number and a prime symbol are included the number is stated before the prime symbol. For example, `U2'` means rotate the upper face 180 degrees counter
|
|
114
|
+
When both a number and a prime symbol are included, the number is stated before the prime symbol. For example, `U2'` means rotate the upper face 180 degrees counter‑clockwise, and `U'2` is invalid.
|
|
115
|
+
|
|
116
|
+
Valid Notation is available via an export called core.
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
import { RubiksCubeElement } from '@houstonp/rubiks-cube';
|
|
120
|
+
import { Rotations, Movements, PeekTypes, PeekState } from '@houstonp/rubiks-cube/core';
|
|
121
|
+
|
|
122
|
+
const cube = document.querySelector('rubiks-cube');
|
|
123
|
+
cube.move(Movements.R);
|
|
124
|
+
cube.rotation(Rotations.x2);
|
|
125
|
+
```
|
|
100
126
|
|
|
101
127
|
| Notation | Movement |
|
|
102
128
|
| -------- | ------------------------------------------------ |
|
|
@@ -119,142 +145,22 @@ When both a number and a prime symbol are included the number is stated before t
|
|
|
119
145
|
| y | Rotate cube on y axis clockwise (direction of U) |
|
|
120
146
|
| z | Rotate cube on z axis clockwise (direction of F) |
|
|
121
147
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
## Updating the component
|
|
125
|
-
|
|
126
|
-
The Rubiks cube web component listens for custom events to perform twists, rotations and camera changes. As per convention, the starting rotation has green facing forward, white facing up and red facing to the right.
|
|
148
|
+
These symbols align with the movements and rotations accepted by the component’s API.
|
|
127
149
|
|
|
128
|
-
|
|
150
|
+
## Development
|
|
129
151
|
|
|
130
|
-
|
|
152
|
+
This repository is set up as an npm package and uses **Bun** for scripts and type generation.
|
|
131
153
|
|
|
132
|
-
|
|
154
|
+
- **Install dependencies**
|
|
133
155
|
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```
|
|
156
|
+
```bash
|
|
157
|
+
bun install
|
|
158
|
+
```
|
|
138
159
|
|
|
139
|
-
|
|
160
|
+
- **Generate TypeScript declaration files**
|
|
140
161
|
|
|
141
|
-
|
|
162
|
+
```bash
|
|
163
|
+
bun run build:types
|
|
164
|
+
```
|
|
142
165
|
|
|
143
|
-
|
|
144
|
-
{
|
|
145
|
-
eventId: string,
|
|
146
|
-
action: {
|
|
147
|
-
type: "movement" | "camera" | "rotation",
|
|
148
|
-
actionId: string
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
```js
|
|
154
|
-
var event = new CustomEvent('action', {
|
|
155
|
-
detail: { eventId: 'guid-guid-guid-guid-guid', action: { type: 'camera', actionId: 'peek-toggle-horizontal' } },
|
|
156
|
-
});
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
#### Camera action event
|
|
160
|
-
|
|
161
|
-
action IDs for camera actions are as follows
|
|
162
|
-
|
|
163
|
-
- `peek-right` - Camera is moved to the right of the cube so that the right face is visible
|
|
164
|
-
- `peek-left` - Camera is moved to the left of the cube so that the left face is visible
|
|
165
|
-
- `peek-top` - Camera is moved above the cube so that the top face is visible
|
|
166
|
-
- `peek-bottom` - Camera is moved below the cube so that the bottom face is visible
|
|
167
|
-
- `peek-toggle-horizontal` - Camera is moved to the opposite side of the cube in the horizontal plane
|
|
168
|
-
- `peek-toggle-vertical` - Camera is moved to the opposite side of the cube in the vertical plane
|
|
169
|
-
|
|
170
|
-
#### Example
|
|
171
|
-
|
|
172
|
-
```js
|
|
173
|
-
const cube = document.querySelector('rubiks-cube');
|
|
174
|
-
const event = new CustomEvent('action', {
|
|
175
|
-
detail: { eventId: 'guid-guid-guid-guid-guid', action: { type: 'camera', actionId: 'peek-toggle-horizontal' } },
|
|
176
|
-
});
|
|
177
|
-
cube.dispatchEvent(event);
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
#### Rotation action event
|
|
181
|
-
|
|
182
|
-
| Notation | Rotation |
|
|
183
|
-
| -------- | ------------------------------------------------ |
|
|
184
|
-
| x | Rotate cube on x axis clockwise (direction of R) |
|
|
185
|
-
| y | Rotate cube on y axis clockwise (direction of U) |
|
|
186
|
-
| z | Rotate cube on z axis clockwise (direction of F) |
|
|
187
|
-
|
|
188
|
-
actionIDs for action type "rotation" are as follows
|
|
189
|
-
|
|
190
|
-
- 'x',
|
|
191
|
-
- 'x2',
|
|
192
|
-
- "x'",
|
|
193
|
-
- 'y',
|
|
194
|
-
- 'y2',
|
|
195
|
-
- "y'",
|
|
196
|
-
- 'z',
|
|
197
|
-
- 'z2',
|
|
198
|
-
- "z'",
|
|
199
|
-
|
|
200
|
-
#### Example
|
|
201
|
-
|
|
202
|
-
```js
|
|
203
|
-
const cube = document.querySelector('rubiks-cube');
|
|
204
|
-
const event = new CustomEvent('action', {
|
|
205
|
-
detail: { eventId: 'guid-guid-guid-guid-guid', action: { type: 'rotation', actionId: 'x' } },
|
|
206
|
-
});
|
|
207
|
-
cube.dispatchEvent(event);
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
#### Movement action event
|
|
211
|
-
|
|
212
|
-
| Notation | Movement |
|
|
213
|
-
| -------- | ------------------------------------------ |
|
|
214
|
-
| U | Top face clockwise |
|
|
215
|
-
| u | Top two layers clockwise |
|
|
216
|
-
| D | Bottom face clockwise |
|
|
217
|
-
| d | Bottom two layers clockwise |
|
|
218
|
-
| L | Left face clockwise |
|
|
219
|
-
| l | Left two layers clockwise |
|
|
220
|
-
| R | Right face clockwise |
|
|
221
|
-
| r | Right two layers clockwise |
|
|
222
|
-
| F | Front face clockwise |
|
|
223
|
-
| f | Front two layers clockwise |
|
|
224
|
-
| B | Back face clockwise |
|
|
225
|
-
| b | Back two layers clockwise |
|
|
226
|
-
| M | Middle layer clockwise (relative to L) |
|
|
227
|
-
| E | Equatorial layer clockwise (relative to D) |
|
|
228
|
-
| S | Standing layer clockwise (relative to F) |
|
|
229
|
-
|
|
230
|
-
actionIDs for action type "movement" are as follows
|
|
231
|
-
|
|
232
|
-
- 'R',
|
|
233
|
-
- 'R2',
|
|
234
|
-
- "R'",
|
|
235
|
-
- 'L',
|
|
236
|
-
- 'L2',
|
|
237
|
-
- "L'",
|
|
238
|
-
- 'U',
|
|
239
|
-
- 'U2',
|
|
240
|
-
- "U'",
|
|
241
|
-
- 'D',
|
|
242
|
-
- 'D2',
|
|
243
|
-
- "D'",
|
|
244
|
-
- 'F',
|
|
245
|
-
- 'F2',
|
|
246
|
-
- "F'",
|
|
247
|
-
- 'B',
|
|
248
|
-
- 'B2',
|
|
249
|
-
- "B'",
|
|
250
|
-
- etc...
|
|
251
|
-
|
|
252
|
-
#### Example
|
|
253
|
-
|
|
254
|
-
```js
|
|
255
|
-
const cube = document.querySelector('rubiks-cube');
|
|
256
|
-
const event = new CustomEvent('action', {
|
|
257
|
-
detail: { eventId: 'guid-guid-guid-guid-guid', action: { type: 'movement', actionId: 'U' } },
|
|
258
|
-
});
|
|
259
|
-
cube.dispatchEvent(event);
|
|
260
|
-
```
|
|
166
|
+
The generated `.d.ts` files are emitted into the `types/` directory (ignored in git) and are used for consumers of the package. There is currently no dedicated demo app or automated test suite in this repository; you can import the component into your own app (e.g., Vite, Next.js, or any ES‑module‑aware bundler) to experiment locally.
|
package/package.json
CHANGED
|
@@ -1,13 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@houstonp/rubiks-cube",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Rubiks Cube Web Component built with threejs",
|
|
5
|
-
"main": "index.js",
|
|
6
5
|
"author": "Houston Pearse",
|
|
7
6
|
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"rubik's cube",
|
|
9
|
+
"twisty puzzle",
|
|
10
|
+
"3x3",
|
|
11
|
+
"renderer",
|
|
12
|
+
"threejs"
|
|
13
|
+
],
|
|
14
|
+
"main": "./src/index.js",
|
|
15
|
+
"types": "./types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./types/index.d.ts",
|
|
19
|
+
"default": "./src/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./schema": {
|
|
22
|
+
"types": "./types/schema.d.ts",
|
|
23
|
+
"default": "./src/schema.js"
|
|
24
|
+
},
|
|
25
|
+
"./core": {
|
|
26
|
+
"types": "./types/core.d.ts",
|
|
27
|
+
"default": "./src/core.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build:types": "tsc",
|
|
32
|
+
"watch:types": "tsc --watch"
|
|
33
|
+
},
|
|
8
34
|
"dependencies": {
|
|
9
35
|
"gsap": "^3.14.2",
|
|
10
|
-
"three": "^0.
|
|
36
|
+
"three": "^0.182.0"
|
|
11
37
|
},
|
|
12
38
|
"repository": {
|
|
13
39
|
"type": "git",
|
|
@@ -16,5 +42,9 @@
|
|
|
16
42
|
"bugs": {
|
|
17
43
|
"url": "https://github.com/houstonpearse/rubiks-cube/issues"
|
|
18
44
|
},
|
|
19
|
-
"homepage": "https://github.com/houstonpearse/rubiks-cube#readme"
|
|
45
|
+
"homepage": "https://github.com/houstonpearse/rubiks-cube#readme",
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/three": "^0.182.0",
|
|
48
|
+
"typescript": "^5.9.3"
|
|
49
|
+
}
|
|
20
50
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { PeekStates, PeekTypes } from './core';
|
|
3
|
+
|
|
4
|
+
export class CameraState {
|
|
5
|
+
/**
|
|
6
|
+
* @param {boolean} up
|
|
7
|
+
* @param {boolean} right
|
|
8
|
+
*/
|
|
9
|
+
constructor(up = true, right = true) {
|
|
10
|
+
/** @type {boolean} */
|
|
11
|
+
this.Up = up;
|
|
12
|
+
/** @type {boolean} */
|
|
13
|
+
this.Right = right;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {import("./core").PeekType} peekType
|
|
18
|
+
*/
|
|
19
|
+
peekCamera(peekType) {
|
|
20
|
+
switch (peekType) {
|
|
21
|
+
case PeekTypes.Horizontal:
|
|
22
|
+
this.Right = !this.Right;
|
|
23
|
+
break;
|
|
24
|
+
case PeekTypes.Vertical:
|
|
25
|
+
this.Up = !this.Up;
|
|
26
|
+
break;
|
|
27
|
+
case PeekTypes.Right:
|
|
28
|
+
this.Right = true;
|
|
29
|
+
break;
|
|
30
|
+
case PeekTypes.Left:
|
|
31
|
+
this.Right = false;
|
|
32
|
+
break;
|
|
33
|
+
case PeekTypes.Up:
|
|
34
|
+
this.Up = true;
|
|
35
|
+
break;
|
|
36
|
+
case PeekTypes.Down:
|
|
37
|
+
this.Up = false;
|
|
38
|
+
break;
|
|
39
|
+
case PeekTypes.RightUp:
|
|
40
|
+
this.Right = true;
|
|
41
|
+
this.Up = true;
|
|
42
|
+
break;
|
|
43
|
+
case PeekTypes.RightDown:
|
|
44
|
+
this.Right = true;
|
|
45
|
+
this.Up = false;
|
|
46
|
+
break;
|
|
47
|
+
case PeekTypes.LeftUp:
|
|
48
|
+
this.Right = false;
|
|
49
|
+
this.Up = true;
|
|
50
|
+
break;
|
|
51
|
+
case PeekTypes.LeftDown:
|
|
52
|
+
this.Right = false;
|
|
53
|
+
this.Up = false;
|
|
54
|
+
break;
|
|
55
|
+
default:
|
|
56
|
+
console.error(`Invalid peekType:[${peekType}]. valid values are [${Object.values(PeekTypes)}] `);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @returns {import("./core").PeekState}
|
|
62
|
+
*/
|
|
63
|
+
toPeekState() {
|
|
64
|
+
if (this.Right && this.Up) {
|
|
65
|
+
return PeekStates.RightUp;
|
|
66
|
+
}
|
|
67
|
+
if (!this.Right && this.Up) {
|
|
68
|
+
return PeekStates.LeftUp;
|
|
69
|
+
}
|
|
70
|
+
if (this.Right && !this.Up) {
|
|
71
|
+
return PeekStates.RightDown;
|
|
72
|
+
}
|
|
73
|
+
if (!this.Right && !this.Up) {
|
|
74
|
+
return PeekStates.LeftDown;
|
|
75
|
+
}
|
|
76
|
+
console.error(
|
|
77
|
+
`Invalid CameraState right and up values must be true or false. Actual values: right[${this.Right}] up[${this.Up}]. Default RightUp returned`,
|
|
78
|
+
);
|
|
79
|
+
return PeekStates.RightUp;
|
|
80
|
+
}
|
|
81
|
+
}
|
package/src/core.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {typeof Movements[keyof typeof Movements]} Movement
|
|
4
|
+
*/
|
|
5
|
+
export const Movements = Object.freeze({
|
|
6
|
+
R: 'R',
|
|
7
|
+
R2: 'R2',
|
|
8
|
+
RP: "R'",
|
|
9
|
+
L: 'L',
|
|
10
|
+
L2: 'L2',
|
|
11
|
+
LP: "L'",
|
|
12
|
+
U: 'U',
|
|
13
|
+
U2: 'U2',
|
|
14
|
+
UP: "U'",
|
|
15
|
+
D: 'D',
|
|
16
|
+
D2: 'D2',
|
|
17
|
+
DP: "D'",
|
|
18
|
+
F: 'F',
|
|
19
|
+
F2: 'F2',
|
|
20
|
+
FP: "F'",
|
|
21
|
+
B: 'B',
|
|
22
|
+
B2: 'B2',
|
|
23
|
+
BP: "B'",
|
|
24
|
+
// Wide moves
|
|
25
|
+
r: 'r',
|
|
26
|
+
r2: 'r2',
|
|
27
|
+
rP: "r'",
|
|
28
|
+
l: 'l',
|
|
29
|
+
l2: 'l2',
|
|
30
|
+
lP: "l'",
|
|
31
|
+
u: 'u',
|
|
32
|
+
u2: 'u2',
|
|
33
|
+
uP: "u'",
|
|
34
|
+
d: 'd',
|
|
35
|
+
d2: 'd2',
|
|
36
|
+
dP: "d'",
|
|
37
|
+
f: 'f',
|
|
38
|
+
f2: 'f2',
|
|
39
|
+
fP: "f'",
|
|
40
|
+
b: 'b',
|
|
41
|
+
b2: 'b2',
|
|
42
|
+
bP: "b'",
|
|
43
|
+
// Slice moves
|
|
44
|
+
M: 'M',
|
|
45
|
+
M2: 'M2',
|
|
46
|
+
MP: "M'",
|
|
47
|
+
E: 'E',
|
|
48
|
+
E2: 'E2',
|
|
49
|
+
EP: "E'",
|
|
50
|
+
S: 'S',
|
|
51
|
+
S2: 'S2',
|
|
52
|
+
SP: "S'",
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @typedef {typeof Rotations[keyof typeof Rotations]} Rotation
|
|
57
|
+
*/
|
|
58
|
+
export const Rotations = Object.freeze({
|
|
59
|
+
x: 'x',
|
|
60
|
+
x2: 'x2',
|
|
61
|
+
xP: "x'",
|
|
62
|
+
y: 'y',
|
|
63
|
+
y2: 'y2',
|
|
64
|
+
yP: "y'",
|
|
65
|
+
z: 'z',
|
|
66
|
+
z2: 'z2',
|
|
67
|
+
zP: "z'",
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @typedef {typeof Axi[keyof typeof Axi]} Axis
|
|
72
|
+
*/
|
|
73
|
+
export const Axi = Object.freeze({
|
|
74
|
+
x: 'x',
|
|
75
|
+
y: 'y',
|
|
76
|
+
z: 'z',
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @typedef {typeof Faces [keyof typeof Faces]} Face
|
|
81
|
+
*/
|
|
82
|
+
export const Faces = Object.freeze({
|
|
83
|
+
up: 'U',
|
|
84
|
+
down: 'D',
|
|
85
|
+
left: 'L',
|
|
86
|
+
right: 'R',
|
|
87
|
+
front: 'F',
|
|
88
|
+
back: 'B',
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @typedef {typeof FaceColours [keyof typeof FaceColours]} FaceColour
|
|
93
|
+
*/
|
|
94
|
+
export const FaceColours = Object.freeze({
|
|
95
|
+
up: 'white',
|
|
96
|
+
down: 'yellow',
|
|
97
|
+
left: 'orange',
|
|
98
|
+
right: 'red',
|
|
99
|
+
front: 'green',
|
|
100
|
+
back: 'blue',
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @typedef {typeof PeekTypes [keyof typeof PeekTypes]} PeekType
|
|
105
|
+
*/
|
|
106
|
+
export const PeekTypes = Object.freeze({
|
|
107
|
+
Horizontal: 'horizontal',
|
|
108
|
+
Vertical: 'vertical',
|
|
109
|
+
Right: 'right',
|
|
110
|
+
Left: 'left',
|
|
111
|
+
Up: 'up',
|
|
112
|
+
Down: 'down',
|
|
113
|
+
RightUp: 'rightUp',
|
|
114
|
+
RightDown: 'rightDown',
|
|
115
|
+
LeftUp: 'leftUp',
|
|
116
|
+
LeftDown: 'leftDown',
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @typedef {typeof PeekStates [keyof typeof PeekStates]} PeekState
|
|
121
|
+
*/
|
|
122
|
+
export const PeekStates = Object.freeze({
|
|
123
|
+
RightUp: 'rightUp',
|
|
124
|
+
RightDown: 'rightDown',
|
|
125
|
+
LeftUp: 'leftUp',
|
|
126
|
+
LeftDown: 'leftDown',
|
|
127
|
+
});
|